/* * Common part of gemlib bindings * * ++jrb bammi@cadence.com * modified: mj -- ntomczak@vm.ucs.ualberta.ca */ #define __IN_COMMON_C #include "common.h" /* vdi binding arrays (extern everywhere else) */ unsigned short _contrl[CNTRLMAX]; short _intin[INTINMAX]; short _intout[INTOUTMAX]; short _ptsin[2 * PTSINMAX]; /* upto PTSINMAX vertices are allowed - currently 1024 */ short _ptsout[2 * PTSOUTMAX]; /* likewise */ /* * aes binding arrays - we need only global, other overlapped with * arrays for vdi - see common.h */ unsigned short _global[GLOBMAX]; /* this should be exact */ /* aes binding params */ void *_aesparams[6] = { (void *)&_control[0], (void *)&_global[0], (void *)&_int_in[0], (void *)&_int_out[0], (void *)&_addrin[0], (void *)&_addrout[0] }; /* why did atari do this when apid is avail on appl_init ?? */ int gl_apid; /* initialized in appl_init */ int gl_ap_version; /* initialized in appl_init */ /* vdi binding params */ void *_vdiparams[5] = { (void *)&_contrl[0], (void *)&_intin[0], (void *)&_ptsin[0], (void *)&_intout[0], (void *)&_ptsout[0] }; /* * the common interface to aes * int __aes__(coded control); * unsigned long coded control; * coded control: (1 byte for each element of control in the long) * DD CC BB AA * DD : aes opcode * CC : sizeof _int_in * BB : sizeof _int_out * AA : sizeof _addrin * * Note: sizeof _addrout is needed only for rsrc_gaddr and is special * cased below. * * output: the value (int)_intout[0] */ #ifdef __OLD__ int __aes__(unsigned long coded_control) { register unsigned char *p = (unsigned char *)&coded_control; register unsigned short *q = &_control[0]; /* decode control */ do { *q++ = (unsigned short)(*p++); } while(q < &_control[4]); /* only rsrc_gaddr() needs this */ *q = (_control[0] == 112) ? 1 : 0; /* call aes */ __asm__ volatile (" movl %0, d1 movw #0xc8, d0 trap #2" : /* no outputs */ : "g"(&_aesparams[0]) /* inputs */ : "d0", "d1", "d2", "a0", "a1", "a2" /* clobbered regs */ ); return (int)_int_out[0]; } #else /* * new more efficient coding thanks to Thomas Koenig (UI0T@DKAUNI2.BITNET) * "I made use here of the movep instruction for the 680xx, which transfers * data from a data register to alternate bytes of memory. The odd * address makes sure that these bytes are transferred to the lower half * of the words." */ int __aes__(unsigned long coded_control) { /* call aes */ __asm__ volatile (" movel %1, d1 lea __contrl, a0 | arrays _contrl and _control overlap moveq #0, d0 movepl d0, a0@(0) | clear high bytes of control array movepl d1, a0@(1) movl %0, d1 movw #0xc8, d0 | note -- no movq here, it sign extends trap #2" : /* no outputs */ : "g"(&_aesparams[0]), "g"(coded_control) /* inputs */ : "d0", "d1", "d2", "a0", "a1", "a2" /* clobbered regs */ ); return (int)_int_out[0]; } #endif /* * the common interface to vdi * void __vdi__(coded contrl, handle); * unsigned long coded contrl; * int handle; * coded contrl: * DD BB CC AA * DD : subfunc (_contrl[5]) 5 bits * BB : nvert. _ptsin (_contrl[1]) 11 (== # vertices, size = 2 * CC) * CC : sizeof _intin (_contrl[3]) 8 bits * AA : vdi opcode (_contrl[0]) 8 * * output : void (because it is so inconsistent, individual binding funcs * will pull info out of the appro. binding arrays) */ void __vdi__(unsigned long coded_contrl, int handle) { /* decode contrl */ _contrl[0] = (unsigned short)(coded_contrl & 0xff); _contrl[3] = (unsigned short)((coded_contrl >>= 8) & 0xff); _contrl[1] = (unsigned short)((coded_contrl >>= 8) & 0x7ff); _contrl[5] = (unsigned short)(coded_contrl >> 11); _contrl[6] = handle; /* call vdi */ __asm__ volatile (" movl %0, d1 movq #0x73, d0 trap #2" : /* no outputs */ : "g"(&_vdiparams[0]) /* inputs */ : "d0", "d1", "d2", "a0", "a1", "a2" /* clobbered regs */ ); } void vdi(void) { __asm__ volatile (" movl %0, d1 movq #0x73, d0 trap #2" : /* no outputs */ : "g"(&_vdiparams[0]) /* inputs */ : "d0", "d1", "d2", "a0", "a1", "a2" /* clobbered regs */ ); } /* -eof- */