GEMlib
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().
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]); } |
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]; } |
The file gem_vdiP.h |
/* * $Id: gem_vdiP.h,v 1.4.4.3 2003/02/16 20:57:41 a_bercegeay Exp $ */ #ifndef _GEM_VDI_P_ # define _GEM_VDI_P_ # ifndef _GEMLIB_H_ # include "mt_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) #define VDI_PARAMS(a,b,c,d,e) \ VDIPB vdi_params; \ vdi_params.control = a; \ vdi_params.intin = b; \ vdi_params.ptsin = c; \ vdi_params.intout = d; \ vdi_params.ptsout = e; # endif /* _GEM_VDI_P_ */ |
The file vsl_color.c |
/* * $Id: vsl_color.c,v 1.4.4.2 2003/02/16 20:19:07 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]; VDI_PARAMS(vdi_control, &index, 0L, vdi_intout, 0L ); #else vdi_intin[0] = index; #endif VDI_TRAP (vdi_params, handle, 17, 0,1); return vdi_intout[0]; } |