GEMlib
Work done on AES bindings

In one hand, Mgemlib have fixed a lot of bugs, add new functions, and included the mt_aes library (mt_aes was already included in gemlib 34 and gemlib 35, but removed on gemlib 36).

In the other hand, last Gemlib release (0.42.2) doesn't include the mt_aes library, but have some other bug fixes and optimisations (for instance inline asm for aes trap).

The next gemlib release is based on mgemlib (for AES bindings). The modifications are listed below:

Ok, enought words, here is an example: the binding of appl_find().

appl_find() binding from MGEMLIB 41

Extract from mgem.h
extern int  mt_appl_find        (char *Name,INT16 *global_aes);

#define appl_find(a) mt_appl_find(a,aes_global)

extern INT16    aes_global[];
Extract form a_appl.c
int mt_appl_find(char *Name, INT16 *global_aes)
{
    static INT16    aes_control[AES_CTRLMAX]={13,0,1,1,0};
    INT16           aes_intin[AES_INTINMAX],
                aes_intout[AES_INTOUTMAX];
    long            aes_addrin[AES_ADDRINMAX],
                aes_addrout[AES_ADDROUTMAX];

    AESPB aes_params;
    aes_params.control = &aes_control[0];   /* AES Control Array             */
    aes_params.global  = &global_aes[0];    /* AES Global Array              */
    aes_params.intin   = &aes_intin[0];     /* input integer array           */
    aes_params.intout  = &aes_intout[0];    /* output integer array          */
    aes_params.addrin  = &aes_addrin[0];    /* input address array           */
    aes_params.addrout = &aes_addrout[0];   /* output address array          */
                    
    aes_addrin[0] = (long)Name;

    aes(&aes_params);

    return aes_intout[0];
}

#ifdef appl_find
#undef appl_find
#endif
int appl_find(char *Name)
{
    return(mt_appl_find(Name, aes_global));
}

appl_find() binding from GEMLIB 0.42.2

The file gem_aesP.h
/*
 * gem_aesP.h -- AES trap interface
 *
 *    <AltF4@freemint.de>
 */

#ifndef _GEM_AES_P_
# define _GEM_AES_P_

# ifndef _GEMLIB_H_
# include "gem.h"
# endif


#if defined(__GNUC_INLINE__) && (__GNUC__ > 2 ¦¦ __GNUC_MINOR__ > 5)

static inline void
_aes_trap (AESPB * aespb, long cntrl_0_1, long cntrl_2_3, short cntrl_4)
{
    __asm__ volatile ("
        movea.l %0, a0;    ¦ &aespb
        move.l  a0, d1;
        move.l  (a0), a0;  ¦ aespb->control
        move.l  %1, (a0)+; ¦ cntrl_0, cntrl_1
        move.l  %2, (a0)+; ¦ cntrl_2, cntrl_3
        move.l  %3, d0;    ¦ 0x00C8,  cntrl_4
        move.w  d0, (a0);  ¦ cntrl_4
        swap    d0;        ¦ 0x00C8
        trap    #2;
        "
        :
        : "a"(aespb), "g"(cntrl_0_1), "g"(cntrl_2_3), "g"(0xC80000uL¦cntrl_4)
        : "a0", "d0","d1"
    );
}
#define AES_TRAP(aespb, cntrl_0, cntrl_1, cntrl_2, cntrl_3, cntrl_4) \
    _aes_trap (&aespb, \
               (cntrl_0##uL<<16cntrl_1, \
               (cntrl_2##uL<<16cntrl_3, \
                cntrl_4)


#else /* no usage of gnu inlines, go the old way */

#define AES_TRAP(aespb, cntrl_0, cntrl_1, cntrl_2, cntrl_3, cntrl_4) \
    aes_control[0] = cntrl_0; \
    aes_control[1] = cntrl_1; \
    aes_control[2] = cntrl_2; \
    aes_control[3] = cntrl_3; \
    aes_control[4] = cntrl_4; \
    aes (&aespb);

#endif


extern short aes_control[];
extern short aes_global[];
extern short aes_intin[];
extern short aes_intout[];
extern long  aes_addrin[];
extern long  aes_addrout[];


# endif /* _GEM_AES_P_ */
The file a_appl_find.c
#include "gem_aesP.h"


short
appl_find (const char *Name)
{
       aes_addrin[0] = (long)Name;
       
       AES_TRAP (aes_params, 13, 0,1,1,0);
       
       return aes_intout[0];
}

appl_find() binding of the next GEMlib release

The file gem_aesP.h
/*
 *  $Id: gem_aesP.h,v 1.2.4.6 2003/02/16 20:58:06 a_bercegeay Exp $
 */

#ifndef _GEM_AES_P_
# define _GEM_AES_P_

# ifndef _GEMLIB_H_
#  include "mt_gem.h"
# endif


#if defined(__GNUC_INLINE__) && (__GNUC__ > 2 ¦¦ __GNUC_MINOR__ > 5)

static inline void
_aes_trap (AESPB * aespb)
{
       __asm__ volatile ("
              move.l %0, d1;    ¦ &aespb
              move.w  #200,d0;
              trap    #2;
              "
              :
              : "a"(aespb)
              : "d0","d1"
       );
}
#define AES_TRAP(aespb) _aes_trap(&aespb)

#else /* no usage of gnu inlines, go the old way */

#define AES_TRAP(aespb) aes(&aespb)

#endif


#define AES_PARAMS(a,b,c,d,e) \
       static short    aes_control[AES_CTRLMAX]={a,b,c,d,e}; \
       short                 aes_intin[AES_INTINMAX],                       \
                                   aes_intout[AES_INTOUTMAX];                  \
       long                     aes_addrin[AES_ADDRINMAX],                  \
                                   aes_addrout[AES_ADDROUTMAX];                \
                                                                                                    \
       AESPB aes_params;                                                             \
       aes_params.control = &aes_control[0];                          \
       aes_params.global  = &global_aes[0];                              \
       aes_params.intin   = &aes_intin[0];                               \
       aes_params.intout  = &aes_intout[0];                              \
       aes_params.addrin  = &aes_addrin[0];                              \
       aes_params.addrout = &aes_addrout[0]


#endif /* _GEM_AES_P_ */
The file a_appl_find.c
/*
 *  $Id: a_appl_find.c,v 1.3.4.7 2002/12/18 19:40:00 a_bercegeay Exp $
 */

#include "gem_aesP.h"

/** searches the AES's current process list for a program named Name and,
 *  if present, returns the application identifier of the process.
 *
 *  @param name is a pointer to a null-terminated ASCII string
 *         containing a valid GEMDOS filename (not including an
 *         extension) padded with blanks to be exactly 8 characters
 *         long (not including the NULL).
 *  @param global_aes global AES array
 *
 *  @return the application identifier of the process if it is found or
 *          -1 otherwise.
 *
 *  @since All AES versions.
 *
 *  @sa mt_appl_write(), mt_appl_init()
 *
 *  AES versions from 4.0 add several extensions to this call
 *  for the benefit of MultiTOS. This functionality only exists if the
 *  AES version is 4.0 and above and mt_appl_getinfo() indicates that it
 *  is available. Here is the extension description:
 *  - If the upper word
 *    of the CHAR * is 0xFFFF, the lower word is assumed to be
 *    the MiNT id and mt_appl_find() will return the AES application
 *    identifier.
 *  - If the upper word of the CHAR * is 0xFFFE, the lower word
 *    is assumed to be the AES application identifier and the
 *    MiNT id is returned.
 *  - If the upper word of the CHAR * is 0x0000, the current
 *    processes' application identifier is returned.
 */

short
mt_appl_find(const char *name, short *global_aes)
{
       AES_PARAMS(13,0,1,1,0);

       aes_addrin[0] = (long)name;

       AES_TRAP(aes_params);

       return aes_intout[0];
}

Extract from mt_gem.h
short   mt_appl_find    (const char *name, short *global_aes);

Extract from gem.h
#define appl_find(a) mt_appl_find(a,aes_global)

/** global AES array */
extern short aes_global[];

And an extract from the new file a_glue.c (for linking backward compatibility purpose only)
#ifdef appl_find
#undef appl_find
#endif
short
appl_find(const char *name)
{
       return(mt_appl_find(name, aes_global));
}