#include "dos.h" #include "math.h" #define F_NEAR 0x0001 #define F_PAD 0x0008 #define RT_DOUBLE 3 typedef unsigned short WORD; /* 16-bit unsigned value */ extern WORD _psp; /* Lattice C variables */ extern WORD _tsize; /* Note xwait and xbye are the actual addresses we'll jump to when we call XLI from the glue routine. C calls the glue routine at the two entry points xli_wait and xli_bye. These 2 routines set up the stack for calling xwait and xbye. */ WORD xwait[2]; /* XLI entry points */ WORD xbye[2]; struct xli_file_struct { WORD id; WORD flags; WORD table[2]; /* offset in 0, segment in 1 */ WORD parm_block[2]; WORD reserved[8]; } file_block; struct xli_routine_struct { WORD select; WORD special_service; WORD ss_args[8]; WORD reserved[8]; WORD return_type; double return_value; double arg1; double arg2; } parm_block; char table[] = /* 0 2 4 6 8 10 12 */ "sqrt/sin/cos/tan/asin/acos/atan/atan2/exp/expt/ln/log10/log//"; void main(argc,argv) int argc; char *argv[]; { WORD psp; /*WORD memsize; */ WORD buffer[2]; struct SREGS segregs; int xli_wait(); void xli_bye(); /* Note PSP@ is not necessarily directly accessible in any Lattice C memory model. */ psp = *(&_psp+1); /* get seg addr of PSP */ /* init file block */ file_block.id = 0x4252; file_block.flags = F_NEAR+F_PAD; file_block.table[0] = (WORD) table; file_block.parm_block[0] = (WORD) &parm_block; segread(&segregs); file_block.table[1] = segregs.ds; file_block.parm_block[1] = segregs.ds; /* determine link address */ buffer[0] = (WORD) &file_block; buffer[1] = segregs.ds; /* determine size to keep */ /*memsize = _tsize; */ /* done in glue routine for S Lattice */ /* establish the link addresses between C and PCS */ poke((int) psp, 0x5c, (char *) buffer, 4); /* poke file block@ into PSP */ peek((int) psp, 0x0a, (char *) xwait, 4); /* get DOS ret@ */ xbye[0] = xwait[0]; xbye[1] = xwait[1]; xwait[0] += 3; /* incr by 3 for normal call */ xbye[0] += 6; /* incr by 6 for termination */ while (xli_wait()) { switch (parm_block.select) { case 0: parm_block.return_value = sqrt(parm_block.arg1); break; case 1: parm_block.return_value = sin(parm_block.arg1); break; case 2: parm_block.return_value = cos(parm_block.arg1); break; case 3: parm_block.return_value = tan(parm_block.arg1); break; case 4: parm_block.return_value = asin(parm_block.arg1); break; case 5: parm_block.return_value = acos(parm_block.arg1); break; case 6: parm_block.return_value = atan(parm_block.arg1); break; case 7: parm_block.return_value = atan2(parm_block.arg1,parm_block.arg2); break; case 8: parm_block.return_value = exp(parm_block.arg1); break; case 9: parm_block.return_value = pow(parm_block.arg1,parm_block.arg2); break; case 10: parm_block.return_value = log(parm_block.arg1); break; case 11: parm_block.return_value = log10(parm_block.arg1); break; case 12: parm_block.return_value = log(parm_block.arg1) / log(parm_block.arg2); break; default: ; } /* end switch */ parm_block.return_type = RT_DOUBLE; } /* end while */ xli_bye(); } /* end main */