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 && 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
![]()
