Yes, you are right but some additional should be taken into account which is modifier near or far. It is cause by default function placement. The memory model defines whether function is near (called by JSR and return code is RTS) or it is far function (called by CALL and return code is RTC). Of course you canuse explicit conversion where you will say to compiler hot to exactly process the function (be sure it is placed in the near space if you use near modifier)
(So a "far" function can be placed in a near space. The near function can be place in a far space only and only in the case when such a near space exists (4000~7FFF, C000~FFFF, 2000~3FFF,..se memory maps attached)) In this case the MCU automatically recognizes direct address in an offset of a far function (0xC000_00) and correctly uses it.
Finally,
Direct function address converted to a far space 0xC000 => 0xC000_00.
Something different is to convert far function pointer from far space to global address. Explained below or in attached example.
For example
#pragma CODE_SEG NEAR MY_SEG
void near fction1(void); // JSR used
void fction2(void); // JSR used because of near segment ---not sure whether memory model takes precedence
void far fction1(void); // CALL is used because of explicit conversion. Even the function is, for example placed
// at 0xC000 the far pointer to it will be used with value 0xC000_00
#pragma CODE SEG DEFAULT
Now I’ll copy here an answer I was preparing on background.
Even I do not have full info about your initializations I would like to describe you briefly what you have to keep in mind.
There are different types of addresses near/far global/PPAG_OFFSET/RPAGE_OFFSET/…..
The map file shows real addresses (the form of the a classic hexadecimal number).
If you use pointers to a numbers then GLDx, GSTx assembler instructions are used to simplify access so the pointers looks correctly. (different situation is when you use local addressing page_offset form). Pleae lok into attached map files.
However, pointer to a function has different for in Code and environment processing. The address is switched. It makes some issues if you want ot copy some function from flash and you want to use its start and stop address in the copy cycle. In this case you have to transform the number you get as a unsigned long addr = (unsigned long) fction;
It is also good to test wat is difference if you combine variables and fucnctions definitions. I mean far and near.
So, if I have pointer to a function then I am able to transform it to a long number:
void far flash_ function(void);
unsigned long addr_of_flash_far_function;
unsigned long global_addr_of_flash_far_function;
addr_of_flash_far_function = unsigned long (far_function);
global_addr_of_flash_far_function = ((addr_of_flash_far_function<<14) & 0x003FC000UL) | ((addr_of_flash_far_function >>8) & 0x00003FFFUL) | 0x00400000;
let function is at 0xE08000 (map file) then it is visualized in the debugger 0x8000E0 and to be able to get its correct global address to be able to access individual bytes by data accessing commands you have to transform it by above mentioned formula to get a global address 0x780000: (Gpage_offset)
0xE0_8000 => code warrior 0x8000_E0 => global address 0x780000
This global address can be used to access bytes of the function in the flash.
for ( i = global_addr_of_flash_far_function, i < end; i++)
{
unsigned char x;
x = *((unsigned char *far)) i; // read flash where the “far_function” is placed
}
If I am working with a near space, for example function at address 0xC000, then it is near function (called by JSR and return code is RTS) and it can be called with this address. But when I consider it as a far function (implicit or explicit conversion is applied) then I need a far address of it which means it is converted to 0xC000_00 and it must contains return code RTC because calling assembler instruction is CALL)
Confusing? I know but when you try to perform code which copies PIC (position independent) functions from far flash to near or far RAM and then you are able to run them out of the RAM you will understand it perfectly. An example (from the bottom of my old table drawer) of such task is attached. (In the example I use nonpaged RAM for functions placement so backward conversion from global address to a pointer to a function is simplified because MCU is able to recognize access to a far function (CALL) if the offset is from a space assigned to a RAM direct addressing space)
The approach is the same for S12XD and S12XE families.
Best regards,
Ladislav