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