Native library question
  • Butterfly
    Butterfly
    alfie
    Posts: 96 from 2005/3/25
    From: Italy
    I am in a native library. At offset -30 there is a function foo that:
    - receives one argument in A0
    - returns 2 results in D0 and A0

    Is the following code correct?

    Code:

    funcTable[] =
    {
    ...
    (APTR)FUNCARRAY_32BIT_RESTORE_NATIVE,
    (APTR)foo,
    (APTR)-1,
    ...
    };

    void
    foo(void)
    {
    ULONG arg = REG_A0;
    ULONG res_d0, res_a0;
    ULONG d[8], a[8];
    int i;

    for (i = 1; i<8; i++) {
    d[i] = MyEmulHandle->Dn[i];
    a[i] = MyEmulHandle->An[i];
    }

    ...

    for (i = 1; i<8; i++) {
    MyEmulHandle->Dn[i] = d[i];
    MyEmulHandle->An[i] = a[i];
    }

    REG_D0 = res_d0;
    REG_A0 = res_a0;
    }


    The above works, but I feel like there must be a "more elegant" solution.
  • »31.05.24 - 14:46
    Profile Visit Website
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    Tcheko
    Posts: 518 from 2003/2/25
    From: France
    Quote:

    alfie wrote:
    I am in a native library. At offset -30 there is a function foo that:
    - receives one argument in A0
    - returns 2 results in D0 and A0

    Is the following code correct?

    Code:

    funcTable[] =
    {
    ...
    (APTR)FUNCARRAY_32BIT_RESTORE_NATIVE,
    (APTR)foo,
    (APTR)-1,
    ...
    };

    void
    foo(void)
    {
    ULONG arg = REG_A0;
    ULONG res_d0, res_a0;
    ULONG d[8], a[8];
    int i;

    for (i = 1; i<8; i++) {
    d[i] = MyEmulHandle->Dn[i];
    a[i] = MyEmulHandle->An[i];
    }

    ...

    for (i = 1; i<8; i++) {
    MyEmulHandle->Dn[i] = d[i];
    MyEmulHandle->An[i] = a[i];
    }

    REG_D0 = res_d0;
    REG_A0 = res_a0;
    }


    The above works, but I feel like there must be a "more elegant" solution.



    This function likely returns random values from stack in D0 and A0. The copy from emul regs are doing nothing too, can probably be removed without harm.
    Quelque soit le chemin que tu prendras dans la vie, sache que tu auras des ampoules aux pieds.
    -------
    I need to practice my Kung Fu.
  • »01.06.24 - 03:16
    Profile Visit Website
  • Butterfly
    Butterfly
    alfie
    Posts: 96 from 2005/3/25
    From: Italy
    OK thanks, but the solution is ?

    PS
    That doesn't return random values; the library works in a very complex scenario without problems. If I remove the savings, the system freezes.
  • »01.06.24 - 06:58
    Profile Visit Website
  • Moderator
    Kronos
    Posts: 2267 from 2003/2/24
    Quote:

    Tcheko wrote:

    This function likely returns random values from stack in D0 and A0. The copy from emul regs are doing nothing too, can probably be removed without harm.



    This is a function in a library, so yeah that is needed at least for as long as it uses 68k based calling.

    Just looked up what I did in my LUA MUI/ABox wrapper and it looks the same and AFAIR I nicked that from some example code so this seems the way to go.
  • »01.06.24 - 07:16
    Profile
  • Priest of the Order of the Butterfly
    Priest of the Order of the Butterfly
    Tcheko
    Posts: 518 from 2003/2/25
    From: France
    Quote:

    alfie wrote:
    OK thanks, but the solution is ?

    PS
    That doesn't return random values; the library works in a very complex scenario without problems. If I remove the savings, the system freezes.



    Missed the ... between the loops. You're doing other stuff in. My bad.

    Still, I am a bit puzzled. I never had to mess with emulreg handle directly in my 68k compatible library (camd.library for instance).

    Using FUNCARRAY_32BIT_NATIVE is just good enough for most libraries if the compatibility with 68k binary is needed afaik.

    Library function looks like

    VOID LIB_DummyFunc()
    {
    struct LibBase *Base = REG_A6;
    APTR arg0 = REG_A0; // whatever the function needs as argument
    ULONG arg1 = REG_D0;

    [[ do interesting stuff ]]

    REG_D0 = result;
    }

    As you can see, no emul context saving needed.

    Why are you using FUNCARRAY_RESTORE_NATIVE instead of the more common FUNCARRAY_32BIT_NATIVE?
    Quelque soit le chemin que tu prendras dans la vie, sache que tu auras des ampoules aux pieds.
    -------
    I need to practice my Kung Fu.
  • »01.06.24 - 11:15
    Profile Visit Website
  • Butterfly
    Butterfly
    alfie
    Posts: 96 from 2005/3/25
    From: Italy
    Quote:


    Why are you using FUNCARRAY_RESTORE_NATIVE instead of the more common FUNCARRAY_32BIT_NATIVE?


    The function foo must return an error code in R0 and a STRPTR in A0 if R0 is 0.

    FUNCARRAY_32BIT_NATIVE would restore A0.

    The right one seemed to be FUNCARRAY_32BIT_RESTORE_NATIVE and it works, but I am not truly sure...

    [ Edited by alfie 01.06.2024 - 13:46 ]
  • »01.06.24 - 12:45
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 582 from 2003/2/24
    From: finland, the l...
    I would use FUNCARRAY_32BIT_D0D1A0A1SR_NATIVE in this case.

    Place the desired A0 value to REG_A0 (*) before final return. You don't need to worry about D1, A1 or SR as they're generally undefined after function calls anyway (well except that REG_SR supervisor side flags must not change naturally).

    *) REG_A0 is a #define to MyEmulHandle->An[0] normally.

    [ Edited by Piru 01.06.2024 - 18:29 ]
  • »01.06.24 - 16:28
    Profile
  • Butterfly
    Butterfly
    alfie
    Posts: 96 from 2005/3/25
    From: Italy
    Quote:

    Piru wrote:
    I would use FUNCARRAY_32BIT_D0D1A0A1SR_NATIVE in this case.

    Place the desired A0 value to REG_A0 (*) before final return. You don't need to worry about D1, A1 or SR as they're generally undefined after function calls anyway (well except that REG_SR supervisor side flags must not change naturally).

    *) REG_A0 is a #define to MyEmulHandle->An[0] normally.


    Thanks, it is actually "more elegant" :)
  • »03.06.24 - 00:29
    Profile Visit Website