LIBV

This library collects the invocations to functions that are not present in Hi-tech C 3.09 which I believe are important.

Below are the individual modules to be filled in individually and then linked in the LIBV.LIB library

I wrote a version of the FMOD module in assembler z80 which you will find at this address https://automatico.freevar.com/index.php/cp-m-80-2/hitech-c-per-z80/passaggio-parametri/2

/* exp.c */
/* questa funzione rende disponibile anche la funzione "pow" 
   con floating point elevato a floating point */
#include        <math.h>

extern double   eval_poly();
double
exp(x)
double x;
{
        int     exp;
        char    sign;

        static double coeff[] =
        {
                1.0000000000e+00,
                6.9314718056e-01,
                2.4022650695e-01,
                5.5504108945e-02,
                9.6181261779e-03,
                1.3333710529e-03,
                1.5399104432e-04,
                1.5327675257e-05,
                1.2485143336e-06,
                1.3908092221e-07,
        };

        if(x == 0.0)
                return 1.0;
        sign = x < 0.0;
        if(sign)
                x = -x;
        x *= 1.4426950409;              /* convert to log2 */
        exp = (int)floor(x);
        x -= (double)exp;
        x = ldexp(eval_poly(x, coeff, sizeof coeff/sizeof coeff[0] - 1), exp);
        if(sign)
                return 1.0/x;
        return x;
}

double
pow(x, y)
double  x, y;
{
        if(y == 0.0)
                return 1.0;
        if(x < 0.0)
                return 0.0;
        if(x == 0.0)
                return 0.0;
        x = exp(log(x) * y);
        return x;
}
/* floor.c */
/* La funzione floor restituisce un valore floating point che rappresenta 
   il numero intero più grande ma minore o uguale a quello passato.
   Non restituisce alcun errore.
*/
#include        <math.h>

extern double   _frndint();

double
floor(x)
double  x;
{
        double  i;

        i = _frndint(x);
        if(i > x)
                return i - 1.0;
        return i;
}
/* fmod.c */
#include <math.h>
#include <float.h>
/* calcolo del resto della divisione di due numeri in floating point */

double
fmod(x, y)
double x, y;
{
/* resto in floating point                      */
        double mod;

/* se il divisore vale zero la divisione vale infinito */
/* il massimo valore esprimibile in floating point si ritiene
   che sia un valore infinito. In Hi-tech c per Z80 vale 1.84467e19
        if (y == 0.0)
        {
                return FLT_MAX;
        }

/* se il dividendo vale zero allora il resto vale zero */
        if (x == 0.0)
        {
                return 0.0;
        }

/* se il dividendo e’ negativo il valore iniziale del modulo vale il dividendo ma positivo */
        if (x < 0.0)
        {
                mod=-x;
        }

/* altrimenti il valore del modulo iniziale vale il dividendo */
        else
        {
                mod = x;
        }

/* se il divisore e’ negativo diventa positivo  */
        if (y < 0.0)
        {
                y = -y;
        }

/* sottrai il divisore da mod fino a che il resto sia positivo */
        while(mod >= y)
        {
                mod = mod – y;
        }

/* se il dividendo e’ negativo allora lo e’ anche il modulo */
        if (x < 0.0)
        {
                return -mod;
        }

        return mod;
}
/* itoa.c */
/* Una delle funzioni più importanti, la conversione di un numero
   interno di base assegnata in caratteri ASCII */
#include <stdio.h>
#include <stdlib.h>

/*
        numero = valore intero da convertire
        stringa = buffer di appoggio per il ritorno
        base = base numerica alla quale convertire numero
*/

char*
itoa(numero, stringa, base)
int numero; char* stringa; int base;
{
        int i, j, k;
        char c;
        short unsigned int negativo = 0;

        /*
           se numero e' uguale a zero
           riempe il vettore di '0' piu' il terminatore
        */
        i = 0;
        if (numero == 0)
        {
                stringa[i++] = '0';
                stringa[i] = '\0';
                return stringa;
        }

        /*
           itoa() standard tratta i numeri negativi solo se
           sono in base 10. Altrimenti i numeri sono considerati
           senza segno.
        */
        if (numero < 0 &amp;&amp; base == 10)
        {
                negativo = 1;
                numero = -numero;
        }

        /* Scansione del numero in singoli valori               */
        while (numero != 0)
        {
                int resto = numero % base;
                stringa[i++] = (resto > 9)? (resto-10) + 'a' : resto + '0';
                numero = numero/base;
        }

        /* Se il numero e' negativo aggiungi '-'                */
        if (negativo)
                stringa[i++] = '-';

        /* Aggiunge il terminatore di stringa                   */
        stringa[i] = '\0';

        /* Lunghezza stringa                                    */
        i--;

        /* Inverte l'ordine degli elementi del vettore          */
        for (k = 0, j = i; k<j; k++, j--)
        {
                c = stringa[k];
                stringa[k] = stringa[j];
        }
        return stringa;
}

/* ldexp.c */
/* Ritorna il valore di x*2^y  */
#include <math.h>

extern double exp();

double
ldexp(x, y)
double  x;
int y;
{
        if(y == 0)
                return 1.0;
        if(x == 0.0)
                return 0.0;
        if (x < 0)
        {
                x = -x;
                return -exp(log(x) * y);
        }
        return exp(log(x) * y);
}
/* logn.c */
/* Ritorna il logaritmo di val in base passati come parametri */
#include <math.h>
#include "float.h"

double
logn(base, val)
int base;
double val;
{
        return log(val)/log(base);
}
/* power.c */
#include  <math.h>

extern double exp();

double
power(x, y)
double  x, y;
{
        if(y == 0.0)
                return 1.0;

        if(x == 0.0)
                return 0.0;

        if (x < 0)
        {
                x = -x;
                return -exp(log(x) * y);
        }

        return exp(log(x) * y);
}
/* radcub.c */
#include <math.h>

extern double pow(double,double);

double radcub(r)
double r;
{
        double y;
        y = pow(r, 0.3333333);
        return y;
}

Per facilitare il compito di costruzione della libreria ecco le direttive di compilazione in forma SUBMIT:

;----------  LIBV.SUB  ----------
c -C -O EXP.C
c -C -O FLOOR.C
c -C -O ITOA.C
c -C -O LDEXP.C
c -C -O LOGN.C
c -C -O POWER.C
c -C -O RADCUB.C
c -C -O FMOD.C
LIBR R LIBV.LIB EXP.OBJ
LIBR R LIBV.LIB FLOOR.OBJ
LIBR R LIBV.LIB ITOA.OBJ
LIBR R LIBV.LIB LOGN.OBJ
LIBR R LIBV.LIB POWER.OBJ
LIBR R LIBV.LIB RADCUB.OBJ
LIBR R LIBV.LIB FMOD.OBJ
;----------  fine  ----------
LIBR M LIBV.LIB

 

 

Loading