Hi All,
I'm trying to store a long/far address in a variable, cast and then jump to that specific address. with the code below:
uint32_t appl_start_address;
appl_start_address = 0x701234;
((void(*_far) (void))(appl_start_address))();
in the debugger, it does the FCALL, but the PC seems to only go to 7012, and the PPAGE is set to 34.
Shouldn't the Program at least jump to address 0x347012?
Essentially i would like to jump and run program at address 0x701234. however, so i'm doing something majorly wrong.
thanks in advance.
Regards
Quasio
Solved! Go to Solution.
quasio,
I'd suggest you to use logical addresses in this case since global addresses can be used to access data only (not call subroutines).
Banked function pointer allocation expects page pointer located at third position. So if you change the application start address to 0x9234C0 it should work.
appl_start_address = 0x9234C0; // 0xC0_9234'L = 0x701234'G;
((void(* far) (void))(appl_start_address))();
Stanish
quasio,
I'd suggest you to use logical addresses in this case since global addresses can be used to access data only (not call subroutines).
Banked function pointer allocation expects page pointer located at third position. So if you change the application start address to 0x9234C0 it should work.
appl_start_address = 0x9234C0; // 0xC0_9234'L = 0x701234'G;
((void(* far) (void))(appl_start_address))();
Stanish
Ah that worked well.
So whats the best way to convert global addresses to logical addresses during runtime?
Is there a macro or a function i can use?
If possible avoid the conversions.
The plain global to paged conversion can is done by the compiler when assigning a global (__far) data pointer to a paged data pointer, see the code below.
Note that no conversion is done from or to function pointers and in addition function pointers use a different byte ordering so when using data pointers the bytes have to be swapped before used as function pointer.
Why do you have to convert a global to a __far function pointer?
Daniel
void* __far far_ptr;void* __pptr p_ptr;long long_log_addr;long far_adr = 0x701234;long long_log_addr2;void main(void) { far_ptr = (void* __far)0x701234; p_ptr = (void* __pptr)far_ptr; long_log_addr = (long)p_ptr; long_log_addr2 = (long) (void* __pptr) (void* __far) far_adr; for(;;) {}}
You may use this macro to convert from global appl_start_address to PPAGE banked appl_start_address:
#define GLOBAL2LOGICAL(x) (((x & 0x3FFFul | 0x8000) << 8) | ((x >> 14) & 0xFF))
PPAGE = global_address / size_of_ppage_window & 0xFF
PPAGE offset = global_address % size_of_ppage_window + start_of_ppage_window(=0x8000)