pcs/xli/trig_llc.c

121 lines
4.6 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------*/
/* PC Scheme 3.0 Transcendental Function Support */
/* (c) Copyright 1987 by Texas Instruments Incorporated */
/* All Rights Reserved. */
/*---------------------------------------------------------*/
/*
This program is a Large Model Lattice C (version 3.0) implementation of
the transcendental functions in PC Scheme, version 3, and is the one
officially supported. The associated assembly language file GLUE_LLC.ASM
is required set up the "wait" and "bye" routines.
To build TRIG_LLC.EXE, perform the following steps; you may need to
substitute directory names and set your path accordingly.
lc -ml trig_llc
masm glue_llc;
link \lc\l\c+trig_llc+glue_llc,trig_llc,,\lc\l\lcm+\lc\l\lc
*/
#include "dos.h"
#include "math.h"
#define RT_DOUBLE 3 /* Designates return value of double float */
typedef unsigned long DWORD; /* 32-bit unsigned value */
typedef unsigned short WORD; /* 16-bit unsigned value */
extern char *_psp; /* Lattice C variable - ptr to psp address */
extern WORD _tsize; /* Lattice C variable - size of program */
/*
Note xwait and xbye are the actual addresses we'll jump to when we call XLI
from the glue routine. We call the glue routine at the two entry points xli_wait
& 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;
char *table; /* pointer to lookup table */
char *parm_block; /* pointer to parameter block */
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; /* return value = pointer to double float */
DWORD dummy; /* dummy out rest of return value field */
double *arg1; /* pointer to argument 1, a double float */
double *arg2; /* pointer to argument 2, a double float */
} 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[];
{
int xli_wait(); /* xli glue routines */
void xli_bye();
char *buffer; /* temp to hold address of file block */
/* initialize the file block */
file_block.id = 0x4252; /* identify as xli routines */
file_block.flags = 0; /* far model, don't pack args */
file_block.table = table; /* address of lookup table */
file_block.parm_block = &parm_block; /* address of parameter block */
buffer = (char *) &file_block; /* hold address of file block,*/
movmem(&buffer, (_psp+0x5c), 4); /* then move it into PSP+0x5C */
movmem((_psp+0xa), (char *) &xwait, 4); /* get callers return address */
xbye[0] = xwait[0]; /* into xwait and xbye */
xbye[1] = xwait[1];
xwait[0] += 3; /* calc normal return address */
xbye[0] += 6; /* calc termination address */
/*
Initialization complete - return to xli. The following loop will execute
until xli gives us a non-zero value
*/
while (xli_wait()) {
parm_block.return_value = parm_block.arg1; /* use arg1 for return value */
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; /* return type = double float */
} /* end while */
xli_bye(); /* terminate xli routine */
} /* end main */