EmulCallQuick68k how to
  • Butterfly
    Butterfly
    alfie
    Posts: 89 from 2005/3/25
    From: Italy
    The following is with EmulCall68k.

    Code:
    #include <proto/exec.h>
    #include <stdio.h>

    struct Library *RexxSysBase;

    int toupper(int c)
    {
    struct EmulCaos ec = {0};
    ULONG fun, res;

    fun = (ULONG)RexxSysBase-0x126;
    ec.caos_Un.Function = (APTR)fun;
    ec.reg_d0 = (ULONG)c;
    ec.reg_a6 = (ULONG)RexxSysBase;

    res = (*MyEmulHandle->EmulCall68k)(&ec);

    return (int)res;
    }

    int main(int argc,char **argv)
    {
    ULONG res;

    if (argc!=2)
    return 1;

    RexxSysBase = OpenLibrary("rexxsyslib.library",0);
    if (!RexxSysBase)
    return 1;

    res = toupper(argv[1][0]);
    printf("%c %cn",argv[1][0],res);

    CloseLibrary(RexxSysBase);

    return 0;
    }


    How to do the same using EmulCallQuick68k?

    P.S.
    I am asking this silly question(s), because this is the convoluted way I use to call some function, f.e. CVs2i:

    being the 68k asm:
    Code:
        _CVs2i:
    move.l d1,-(a7)
    move.l a1,-(a7)
    jsr _LVOCVs2i(a6)
    movea.l (a7)+,a1
    move.l d1,(a1)
    move.l (a7)+,d1
    rts


    I use a ridiculous:
    Code:
    static UWORD CVs2i_code[] =
    {
    0x2F01,
    0x2F09,
    0x4EAE, 0xFE26,
    0x225F,
    0x2281,
    0x221F,
    0x4E75
    };

    int
    CVs2i(struct RexxArg *ss,LONG *value,struct RxsLib *base)
    {
    REG_A0 = (ULONG)ss;
    REG_A1 = (ULONG)value;
    REG_A6 = (ULONG)base;
    return (int)(*MyEmulHandle->EmulCallDirect68k)(CVs2i_code);
    }


    which is too much :P

    [ Edited by alfie 04.06.2024 - 09:16 ]
  • »04.06.24 - 08:06
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 580 from 2003/2/24
    From: finland, the l...
    You can use the macros in ppcinline/macros.h for this. If you have return a value and a single argument LP1 macro is appropriate:
    Code:
    int mytoupper(int c)
    {
    return (int) LP1(0x126, int, mytoupper, int, c, d0, , RexxSysBase, 0, 0, 0, 0, 0, 0);
    }

    Or just the code that it will evaluate to:
    Code:
    int mytoupper(int c)
    {
    ULONG res;
    REG_D0 = (ULONG) c;
    REG_A6 = (ULONG) RexxSysBase;
    res = MyEmulHandle->EmulCallDirectOS(-0x126);
    return (int) res;
    }


    Note that it is not a good idea to replace Standard C library toupper in case some other linklibrary calls it and expects specific behaviour which might not be replicated by the RexxSysBase function.

    The 2nd case indeed is a bit special as MorphOS 68k emul interface doesn't support return values in other registers than d0. A stub like that storing the additional return values is the only way.
  • »04.06.24 - 16:11
    Profile
  • Butterfly
    Butterfly
    alfie
    Posts: 89 from 2005/3/25
    From: Italy
    Thanks Piru.

    toupper was only to write a vary basic example.

    The matter is whatever I do, I always crash trying to use Quick; I remember 20 years ago I had the very same problem: no way to make Quick works.
  • »04.06.24 - 17:35
    Profile Visit Website
  • MorphOS Developer
    Piru
    Posts: 580 from 2003/2/24
    From: finland, the l...
    Quote:

    alfie wrote:
    The matter is whatever I do, I always crash trying to use Quick; I remember 20 years ago I had the very same problem: no way to make Quick works.


    EmulCallQuick68k is tricky to use. Typically you need to set up the call with assembler stub in order to cater for the requirements of the call. If you just call the function directly from C it can wipe r13-r31, something that the C compiler is not aware of. So combining the call with any complicated C code will likely result in a crash.

    Generally it should not be used by user applications.
  • »06.06.24 - 22:09
    Profile
  • Butterfly
    Butterfly
    alfie
    Posts: 89 from 2005/3/25
    From: Italy
    I see, thanks again.
  • »10.06.24 - 21:01
    Profile Visit Website