Re: [cc65] function pointer, fastcall

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2008-08-28 22:59:31
On Wed, Aug 27, 2008 at 09:58:04PM -0400, Greg King wrote:
> "far" and "fastcall" qualify different kinds of objects.  The first one
> describes an address -- in this case, a pointer.  The second one describes a
> function -- what it wants to see after it starts running.  That is why "far"
> and "fastcall" should be put in different places in a function-pointer's
> declaration.

Actually this is only half of the truth. I've invested some time researching
the issue after I've noticed that the current implementation is doubtful (to
say at least).

Address size qualifiers as "far" and "near" should work with any object, not
only with pointers.

    int far I;

means that the object I needs to be addressed using "far" addressing (whatever
that is - it is not defined in the standard). Taking the address of I will
result in a "far" pointer by default. Assigning a "far" pointer to a "near"
pointer - if this is possible - needs a conversion at compile or runtime.

While "far" and "near" are part of a type and can also be applied to any
object, "fastcall" can only applied to functions or function types, but not to
pointers. A pointer may point to a fastcall function, but it is itself not
"farcall".

Because of syntax requirements, these modifiers modify the object or pointer
to its right. So

    void fastcall Func (int);

defines a fastcall function, while

    void (* fastcall Func) (int);

defines a pointer to a fastcall function (please note: This is not the syntax
currently required by cc65). Using

    void (fastcall * Func) (int);       /* illegal! */

would be illegal, because on the right of the "fastcall" modifier is a pointer
and a pointer cannot be fastcall.

    void fastcall far Func (int);

is a fastcall function that must be called by "far" addressing, while

    void (* fastcall far Func) (int);

is a pointer to a fastcall function that must be called using "far"
addressing. This implies that the pointer itself is also "far". Using

    void (far * fastcall far Func) (int);

says the same but explicitly: The pointer is also declared "far".

    void (near * fastcall far Func) (int);

means a near pointer to a far function. This may or may not be useful or
allowed.

If you think about 80x86 architectures, "far" could mean "segmented" while
"near" could mean a 16 or 32 bit pointer without a segment. For the 65816,
"near" could mean 16 bit addressing while "far" could mean 24 bit addressing.
For the 6502 or 65816, "zeropage" could be another address size modifier,
which would mean 8 bit addressing. After declaring

        int zeropage I;

an 8 bit pointer would be declared as

        int zeropage* pI = &I;

while a 16 bit pointer could be declared as

        int near* pI = &I

Just a few thoughts ...

Regards


        Uz


-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Thu Aug 28 23:02:28 2008

This archive was generated by hypermail 2.1.8 : 2008-08-28 23:02:30 CEST