Work done on VDI bindings

VDI bindings in gemlib and mgemlib are quite similar (the main diff is the use of inline asm trap in gemlib). A big part of the work was to include local VDIPB structure in each binding, and make the (now local) vdi_intin, vdi_intout, vdi_ptsin and vdi_ptsout array size as small as possible. (AFAIK, AES userdefined object are drawn using VDI functions, and in such context, the stack used is the « system » stack, which is small on single-TOS).

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



Ok, enought words, here is an example: the binding of vsl_color.



vcl_color binding from MGEMLIB 41

Extract form v_attrib.c

int vsl_color (int handle, int index)
{
       vdi_intin[0] = index;

       vdi_control[0] = 17;
       vdi_control[1] = vdi_control[5] = 0;
       vdi_control[3] = 1;
       vdi_control[6] = handle;

       vdi (&vdi_params);

       return ((int)vdi_intout[0]);
}



vsl_color binding from GEMLIB 0.42.2

The file gem_vdiP.h

/*
* gem_vdiP.h -- VDI trap interface
*
*    <AltF4@freemint.de>
*/

#ifndef _GEM_VDI_P_
# define _GEM_VDI_P_

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


#define vdi_control_ptr(n)   *((void**)(vdi_control +n))
#define vdi_intin_ptr(n)     *((void**)(vdi_intin   +n))
#define vdi_intout_long(n)   *((long*) (vdi_intout  +n))


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

static inline void
_vdi_trap_esc (VDIPB * vdipb,
              long cntrl_0_1, long cntrl_3, long cntrl_5, short handle)
{
       __asm__ volatile ("
               movea.l %0, a0;    | &vdipb
               move.l  a0, d1;
               move.l  (a0), a0;  | vdipb->control
               move.l  %1, (a0)+; | cntrl_0, cntrl_1
               move.l  %2, (a0)+; | cntrl_2, cntrl_3
               move.l  %3, (a0)+; | cntrl_4, cntrl_5
               move.w  %4, (a0);  | handle
               move.w  #115, d0;  | 0x0073
               trap    #2;
               "
               :
               : "a"(vdipb), "g"(cntrl_0_1), "g"(cntrl_3), "g"(cntrl_5), "g"(handle)
               : "a0", "d0","d1"
       );
}
#define VDI_TRAP_ESC(vdipb, handle, opcode, subop, cntrl_1, cntrl_3) \
       _vdi_trap_esc (&vdipb, (opcode##uL<<16)|cntrl_1, cntrl_3, subop, handle)

static inline void
_vdi_trap_00 (VDIPB * vdipb, long cntrl_0_1, short handle)
{
       __asm__ volatile ("
               movea.l %0, a0;    | &vdipb
               move.l  a0, d1;
               move.l  (a0), a0;  | vdipb->control
               move.l  %1, (a0)+; | cntrl_0, cntrl_1
               eor.l   d0, d0;
               move.l  d0, (a0)+; | cntrl_2, cntrl_3
               move.l  d0, (a0)+; | cntrl_4, cntrl_5
               move.w  %2, (a0);  | handle
               move.w  #115, d0;  | 0x0073
               trap    #2;
               "
               :
               : "a"(vdipb), "g"(cntrl_0_1), "g"(handle)
               : "a0", "d0","d1"
       );
}
#define VDI_TRAP_00(vdipb, handle, opcode) \
       _vdi_trap_00 (&vdipb, (opcode##uL<<16), handle)


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

#define VDI_TRAP_ESC(vdipb, handle, opcode, subop, cntrl_1, cntrl_3) \
       vdi_control[0] = opcode;  \
       vdi_control[1] = cntrl_1; \
       vdi_control[3] = cntrl_3; \
       vdi_control[5] = subop;   \
       vdi_control[6] = handle;  \
       vdi (&vdipb);

#define VDI_TRAP_00(vdipb, handle, opcode) \
       VDI_TRAP_ESC (vdipb, handle, opcode, 0, 0, 0)
#endif


#define VDI_TRAP(vdipb, handle, opcode, cntrl_1, cntrl_3) \
       VDI_TRAP_ESC(vdipb, handle, opcode, 0, cntrl_1, cntrl_3)


# endif /* _GEM_VDI_P_ */



The file vsl_color.c

/*
*   line attribute
*/

#include "gem_vdiP.h"


short
vsl_color (short handle, short index)
{
       vdi_intin[0] = index;

       VDI_TRAP (vdi_params, handle, 17, 0,1);

       return vdi_intout[0];
}



appl_find binding of the next major GEMlib release

The file gem_vdiP.h

/*
*  $Id: gem_vdiP.h,v 1.4.4.1 2002/12/28 18:58:33 a_bercegeay Exp $
*/

#ifndef _GEM_VDI_P_
# define _GEM_VDI_P_

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


#define vdi_control_ptr(n)   *((void**)(vdi_control +n))
#define vdi_intin_ptr(n)     *((void**)(vdi_intin   +n))
#define vdi_intout_long(n)   *((long*) (vdi_intout  +n))

#define USE_LOCAL_VDIPB 1

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

static inline void
_vdi_trap_esc (VDIPB * vdipb,
              long cntrl_0_1, long cntrl_3, long cntrl_5, short handle)
{
       __asm__ volatile ("
               movea.l %0, a0;    | &vdipb
               move.l  a0, d1;
               move.l  (a0), a0;  | vdipb->control
               move.l  %1, (a0)+; | cntrl_0, cntrl_1
               move.l  %2, (a0)+; | cntrl_2, cntrl_3
               move.l  %3, (a0)+; | cntrl_4, cntrl_5
               move.w  %4, (a0);  | handle
               move.w  #115, d0;  | 0x0073
               trap    #2;
               "
               :
               : "a"(vdipb), "g"(cntrl_0_1), "g"(cntrl_3), "g"(cntrl_5), "g"(handle)
               : "a0", "d0","d1"
       );
}
#define VDI_TRAP_ESC(vdipb, handle, opcode, subop, cntrl_1, cntrl_3) \
       _vdi_trap_esc (&vdipb, (opcode##uL<<16)|cntrl_1, cntrl_3, subop, handle)

static inline void
_vdi_trap_00 (VDIPB * vdipb, long cntrl_0_1, short handle)
{
       __asm__ volatile ("
               movea.l %0, a0;    | &vdipb
               move.l  a0, d1;
               move.l  (a0), a0;  | vdipb->control
               move.l  %1, (a0)+; | cntrl_0, cntrl_1
               eor.l   d0, d0;
               move.l  d0, (a0)+; | cntrl_2, cntrl_3
               move.l  d0, (a0)+; | cntrl_4, cntrl_5
               move.w  %2, (a0);  | handle
               move.w  #115, d0;  | 0x0073
               trap    #2;
               "
               :
               : "a"(vdipb), "g"(cntrl_0_1), "g"(handle)
               : "a0", "d0","d1"
       );
}
#define VDI_TRAP_00(vdipb, handle, opcode) \
       _vdi_trap_00 (&vdipb, (opcode##uL<<16), handle)


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

#define VDI_TRAP_ESC(vdipb, handle, opcode, subop, cntrl_1, cntrl_3) \
       vdi_control[0] = opcode;  \
       vdi_control[1] = cntrl_1; \
       vdi_control[3] = cntrl_3; \
       vdi_control[5] = subop;   \
       vdi_control[6] = handle;  \
       vdi (&vdipb);

#define VDI_TRAP_00(vdipb, handle, opcode) \
       VDI_TRAP_ESC (vdipb, handle, opcode, 0, 0, 0)
#endif


#define VDI_TRAP(vdipb, handle, opcode, cntrl_1, cntrl_3) \
       VDI_TRAP_ESC(vdipb, handle, opcode, 0, cntrl_1, cntrl_3)


# endif /* _GEM_VDI_P_ */



The file vsl_color.c

/*
*  $Id: vsl_color.c,v 1.4.4.1 2002/12/28 18:48:46 a_bercegeay Exp $
*/

#include "gem_vdiP.h"

/** sets the color index for lines
*
*  @param handle Device handle
*  @param index requested line color. If the index is invalid, color index 1
*         will be selected.
*
*  @return realized line color
*
*  @since all VDI versions
*/

short
vsl_color (short handle, short index)
{
#if USE_LOCAL_VDIPB
       short vdi_control[VDI_CNTRLMAX];
       short vdi_intout[1];
       VDIPB vdi_params =
       {
               &vdi_control[0],             /* vdi_control */
               &index,                      /* vdi_intin   */
               0L,                          /* vdi_ptsin   */
               &vdi_intout[0],              /* vdi_intout  */
               0L                           /* vdi_ptsout  */
       };
#else
       vdi_intin[0] = index;
#endif

       VDI_TRAP (vdi_params, handle, 17, 0,1);

       return vdi_intout[0];
}