Re: how to tell near from far pointers

"Mircea Neacsu [email protected] [rabbit-semi]" <[email protected]> Thu, 6 Oct 2016 11:52:40 -0400
Newsgroups gmane.comp.hardware.rabbit-semiconductor
Message-ID <[email protected]>
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: [email protected]

On 10/6/2016 10:56 AM, Mircea Neacsu [email protected] [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:[email protected]
> On 10/6/2016 6:57 AM, [email protected] [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.
>
>