EmbeddedRelated.com
Forums

how to tell near from far pointers

Started by "tit...@gmail.com [rabbit-semi]" October 6, 2016
Does anybody know what is the standard way to tell if a pointer can be safely casted to near?

Here is a sample program:

#include "xbee/platform.h"

void my_dump(void far *address)
{
const char far *data = address;

printf("Address %" PRIpFAR, data);
printf(" contains: 0x%02" PRIX8 ".\n", data[0]);
}

char far f[64];
char n[64];

void main ()
{
f[0] = 0x00;
n[0] = 0x01;
my_dump(f);
my_dump(n);
}

The output looks like this:

Address 107FC0 contains: 0x00.
Address FFFFB372 contains: 0x01.

The "my_dump" function should be able to recognize a near pointer for proper formatting.

By the way ( address == (void far *)(void *)address ) is true when address is near, but it also throws a warning ("Explicit cast from pointer-to-far to pointer-to-near.")

Thank you.
Is this what you need?

char far df[10];

char dn[10];

//return 1 if far pointer can be downcasted to a near pointer
int safe_downcast (void far *pf,void **pn)
{
union {
struct {
void *n;
unsigned int h;
} s;
char far *f;
} u;
u.f = pf;
if (u.s.h == 0xffff)
{
*pn = u.s.n;
return 1;
}
return 0;
}
int main ()
{
char far *pf;
char *pn;
int ok;

printf ("Size of far pointer is %d\nSize of near pointer is %d\n\n",sizeof(pf),sizeof(pn));
df[0] = 0x55;
dn[0] = 0xaa;

pf = df;
ok = safe_downcast (pf, &pn);
printf ("Far data: pf is 0x%08lx\nContent of *pf is 0x%02x\nsafe_downcast says
%d\n\n", pf, *pf, ok);

pf = dn;
ok = safe_downcast (pf, &pn);
printf ("Near data: pf is 0x%08lx\nContent of *pf is 0x%02x\nsafe_downcast says
%d\n", pf, *pf, ok);
printf ("pn is 0x%04x\nContent of *pn is 0x%02x\n", pn, *pn);
}

Mircea Neacsu
M: 514-591-0329
E: m...@neacsu.net

On 10/6/2016 6:57 AM, t...@gmail.com [rabbit-semi] wrote:
>
> Does anybody know what is the standard way to tell if a pointer can be
> safely casted to near?
>
> Here is a sample program:
> #include "xbee/platform.h"
>
> void my_dump(void far *address)
>
> {
>
> const char far *data = address;
>
> printf("Address %" PRIpFAR, data);
>
> printf(" contains: 0x%02" PRIX8 ".\n", data[0]);
>
> }
>
> char far f[64];
>
> char n[64];
>
> void main ()
>
> {
>
> f[0] = 0x00;
>
> n[0] = 0x01;
>
> my_dump(f);
>
> my_dump(n);
>
> }
>
> The output looks like this:
>
> Address 107FC0 contains: 0x00.
>
> Address FFFFB372 contains: 0x01.
>
> The "my_dump" function should be able to recognize a near pointer for
> proper formatting.
>
> By the way ( address == (void far *)(void *)address ) is true when
> address is near, but it also throws a warning ("Explicit cast from
> pointer-to-far to pointer-to-near.")
>
> Thank you.
>
I looked at the generated code to figure out why far pointers have the
high word set to 0xFFFF (comments are mine).

pf = dn;
000:e825 2193B3 ld hl, 0xB393 //address of dn
000:e828 B1 ld de, hl //DE = low word of far
pointer
000:e829 CC bool hl //anything except 0
becomes 1
000:e82a 4D neg hl //anything except 0
becomes 0xFFFF
000:e82b 91 ld bc, hl //BC = high word of
far pointer
000:e82c DD9D ld px, bcde //PX = far pointer.
NULL pointer is 0
000:e82e ED1504 ld (sp + 0x04), px // anything else
is 0xffff....

I've modified the safe_downcast function to take into account NULL pointers:

//return 1 if far pointer can be downcasted to a near pointer
int safe_downcast (void far *pf,void **pn)
{
union {
struct {
void *n;
unsigned int h;
} s;
char far *f;
} u;
u.f = pf;
if (!pf || u.s.h == 0xffff)
{
*pn = u.s.n;
return 1;
}
return 0;
}
Mircea Neacsu
M: 514-591-0329
E: m...@neacsu.net

On 10/6/2016 10:56 AM, Mircea Neacsu m...@neacsu.net [rabbit-semi] wrote:
>
> Is this what you need?
>
> char far df[10];
> char dn[10];
>
> //return 1 if far pointer can be downcasted to a near pointer
> int safe_downcast (void far *pf,void **pn)
> {
> union {
> struct {
> void *n;
> unsigned int h;
> } s;
> char far *f;
> } u;
> u.f = pf;
> if (u.s.h == 0xffff)
> {
> *pn = u.s.n;
> return 1;
> }
> return 0;
> }
> int main ()
> {
> char far *pf;
> char *pn;
> int ok;
>
> printf ("Size of far pointer is %d\nSize of near pointer is %d\n\n",sizeof(pf),sizeof(pn));
> df[0] = 0x55;
> dn[0] = 0xaa;
>
> pf = df;
> ok = safe_downcast (pf, &pn);
> printf ("Far data: pf is 0x%08lx\nContent of *pf is 0x%02x\nsafe_downcast says
> %d\n\n", pf, *pf, ok);
>
> pf = dn;
> ok = safe_downcast (pf, &pn);
> printf ("Near data: pf is 0x%08lx\nContent of *pf is 0x%02x\nsafe_downcast
> says %d\n", pf, *pf, ok);
> printf ("pn is 0x%04x\nContent of *pn is 0x%02x\n", pn, *pn);
> }
> Mircea Neacsu
> M: 514-591-0329
> E:m...@neacsu.net
> On 10/6/2016 6:57 AM, t...@gmail.com [rabbit-semi] wrote:
>>
>> Does anybody know what is the standard way to tell if a pointer can
>> be safely casted to near?
>>
>> Here is a sample program:
>> #include "xbee/platform.h"
>>
>> void my_dump(void far *address)
>>
>> {
>>
>> const char far *data = address;
>>
>> printf("Address %" PRIpFAR, data);
>>
>> printf(" contains: 0x%02" PRIX8 ".\n", data[0]);
>>
>> }
>>
>> char far f[64];
>>
>> char n[64];
>>
>> void main ()
>>
>> {
>>
>> f[0] = 0x00;
>>
>> n[0] = 0x01;
>>
>> my_dump(f);
>>
>> my_dump(n);
>>
>> }
>>
>> The output looks like this:
>>
>> Address 107FC0 contains: 0x00.
>>
>> Address FFFFB372 contains: 0x01.
>>
>> The "my_dump" function should be able to recognize a near pointer for
>> proper formatting.
>>
>> By the way ( address == (void far *)(void *)address ) is true when
>> address is near, but it also throws a warning ("Explicit cast from
>> pointer-to-far to pointer-to-near.")
>>
>> Thank you.
Consider using paddr_far() from XMEM.LIB to just convert to the actual physical address corresponding to the upcast near pointer. I haven't tested, but that's what that function appears to do.

-Tom
On Oct 6, 2016, at 3:57 AM, t...@gmail.com [rabbit-semi] wrote:

> Does anybody know what is the standard way to tell if a pointer can be safely casted to near?
Very good informations, thanks Mircea and Tom.