1 #ifndef __STDLIB_H__ 2 #define __STDLIB_H__ 3 4 /* 5 * Lots of nice support functions here and a few defines 6 * to support some functions 7 * 8 * $Id: stdlib.h,v 1.51 2016-07-10 20:59:19 dom Exp $ 9 */ 10 11 #include <sys/compiler.h> 12 #include <sys/types.h> 13 #include <stdint.h> 14 15 16 /**********************************/ 17 /* STANDARD K&R LIBRARY FUNCTIONS */ 18 /**********************************/ 19 20 21 ////////////////////////////////// 22 //// String <-> Number Conversions 23 ////////////////////////////////// 24 25 // double atof(char *s); /* check math library for availability */ 26 27 extern int __LIB__ atoi(const char *s) __z88dk_fastcall; 28 extern long __LIB__ atol(const char *s) __z88dk_fastcall; 29 30 extern char __LIB__ *itoa(int num,char *buf,int radix) __smallc; 31 extern char __LIB__ *itoa_callee(int num,char *buf,int radix) __smallc __z88dk_callee; 32 #define itoa(a,b,c) itoa_callee(a,b,c) 33 34 extern char __LIB__ *ltoa(long num,char *buf,int radix) __smallc; 35 extern char __LIB__ *ltoa_callee(long num,char *buf,int radix) __smallc __z88dk_callee; 36 #define ltoa(a,b,c) ltoa_callee(a,b,c) 37 38 extern long __LIB__ strtol(char *nptr,char **endptr,int base) __smallc; 39 extern long __LIB__ strtol_callee(char *nptr,char **endptr,int base) __smallc __z88dk_callee; 40 #define strtol(a,b,c) strtol_callee(a,b,c) 41 42 43 extern uint32_t __LIB__ strtoul(char *nptr,char **endptr,int base) __smallc; 44 extern uint32_t __LIB__ strtoul_callee(char *nptr,char **endptr,int base) __smallc __z88dk_callee; 45 #define strtoul(a,b,c) strtoul_callee(a,b,c) 46 47 extern char __LIB__ *ultoa(uint32_t num,char *buf,int radix) __smallc; 48 extern char __LIB__ *ultoa_callee(uint32_t num,char *buf,int radix) __smallc __z88dk_callee; 49 #define ultoa(a,b,c) ultoa_callee(a,b,c) 50 51 52 extern char __LIB__ *utoa(uint16_t num,char *buf,int radix) __smallc; 53 extern char __LIB__ *utoa_callee(uint16_t num,char *buf,int radix) __smallc __z88dk_callee; 54 #define utoa(a,b,c) utoa_callee(a,b,c) 55 56 57 // double strtod(char *s, char **endp); /* check math library for availability */ 58 59 #ifdef __SDCC 60 /* 64 bit is only available with sdcc */ 61 extern long long atoll(char *buf) __stdc; 62 extern long long atoll_callee(char *buf) __z88dk_callee __stdc; 63 #define atoll(a) atoll_callee(a) 64 65 66 extern char *lltoa(long long num,char *buf,int radix) __stdc; 67 extern char *lltoa_callee(long long num,char *buf,int radix) __z88dk_callee __stdc; 68 #define lltoa(a,b,c) lltoa_callee(a,b,c) 69 70 71 extern long long strtoll(char *nptr,char **endptr,int base) __stdc; 72 extern long long strtoll_callee(char *nptr,char **endptr,int base) __z88dk_callee __stdc; 73 #define strtoll(a,b,c) strtoll_callee(a,b,c) 74 75 76 extern unsigned long long strtoull(char *nptr,char **endptr,int base) __stdc; 77 extern unsigned long long strtoull_callee(char *nptr,char **endptr,int base) __z88dk_callee __stdc; 78 #define strtoull(a,b,c) strtoull_callee(a,b,c) 79 80 81 extern char *ulltoa(unsigned long long num,char *buf,int radix) __stdc; 82 extern char *ulltoa_callee(unsigned long long num,char *buf,int radix) __z88dk_callee __stdc; 83 #define ulltoa(a,b,c) ulltoa_callee(a,b,c) 84 #endif 85 86 /////////////////// 87 //// Random Numbers 88 /////////////////// 89 90 #define RAND_MAX 32767 91 92 extern int __LIB__ rand(void); 93 extern void __LIB__ srand(unsigned int seed) __z88dk_fastcall; 94 95 // Not sure why Rex has it's own rand() routine using different seed? 96 97 #define randRex() rand() 98 99 ////////////////////// 100 //// Memory Allocation 101 ////////////////////// 102 103 // Before using the malloc library you must initialize the heap -- see malloc.h for details 104 // calloc(), malloc(), realloc(), free(), mallinit(), mallinfo(), sbrk() 105 // ot use the -DAMALLOC option to let z88dk doing it automatically 106 107 #include <malloc.h> 108 109 /////////////////////// 110 //// System Environment 111 /////////////////////// 112 113 // Z88: abort is a macro to exit with RC_Err - only for apps 114 115 #define abort() exit(15) 116 117 #define EXIT_FAILURE 1 118 #define EXIT_SUCCESS 0 119 120 extern void __LIB__ exit(int status) __z88dk_fastcall; 121 extern int __LIB__ atexit(void *fcn) __z88dk_fastcall; 122 123 // int system(char *s); /* might be implemented in target's library but doubtful */ 124 // char *getenv(char *name); /* might be implemented in target's library but doubtful */ 125 126 extern int __LIB__ getopt (int, char **, char *) __smallc; 127 extern char *optarg; /* getopt(3) external variables */ 128 extern int opterr; 129 extern int optind; 130 extern int optopt; 131 extern int optreset; 132 133 ////////////////// 134 //// Search & Sort 135 ////////////////// 136 137 // These are not quite ansi (array items are assumed to be two bytes in length). Also look 138 // into the heapsort implementation in the abstract data types library (adt.h) as a stack- 139 // usage-free alternative to quicksort. 140 // 141 // void *cmp == char (*cmp)(void *key, void *datum); 142 143 extern void __LIB__ *l_bsearch(void *key, void *base, unsigned int n, void *cmp) __smallc; 144 extern void __LIB__ *l_bsearch_callee(void *key, void *base, unsigned int n, void *cmp) __smallc __z88dk_callee; 145 extern void __LIB__ l_qsort(void *base, unsigned int size, void *cmp) __smallc; 146 extern void __LIB__ l_qsort_callee(void *base, unsigned int size, void *cmp) __smallc __z88dk_callee; 147 148 #define l_bsearch(a,b,c,d) l_bsearch_callee(a,b,c,d) 149 150 extern void __LIB__ qsort_sccz80(void *base, unsigned int nel, unsigned int width, void *compar) __smallc; 151 extern void __LIB__ qsort_sccz80_callee(void *base, unsigned int nel, unsigned int width, void *compar) __smallc __z88dk_callee; 152 153 extern void __LIB__ qsort_sdcc(void *base, unsigned int nel, unsigned int width, void *compar) __smallc; 154 extern void __LIB__ qsort_sdcc_callee(void *base, unsigned int nel, unsigned int width, void *compar) __smallc __z88dk_callee; 155 156 #ifdef __Z88DK_R2L_CALLING_CONVENTION 157 158 #define qsort qsort_sdcc 159 #define qsort_sdcc(a,b,c,d) qsort_sdcc_callee(a,b,c,d) 160 161 #else 162 163 #define qsort qsort_sccz80 164 #define qsort_sccz80(a,b,c,d) qsort_sccz80_callee(a,b,c,d) 165 166 #endif 167 168 #ifdef __ZX81__ 169 #define l_qsort(a,b,c) qsort(a,b,2,c) 170 #else 171 #define l_qsort(a,b,c) l_qsort_callee(a,b,c) 172 #endif 173 174 175 ////////////////////////// 176 //// Division routines 177 ////////////////////////// 178 179 typedef struct 180 { 181 182 int rem; 183 int quot; 184 185 } div_t; 186 187 typedef struct 188 { 189 190 unsigned int rem; 191 unsigned int quot; 192 193 } divu_t; 194 195 typedef struct 196 { 197 198 long quot; 199 long rem; 200 201 } ldiv_t; 202 203 typedef struct 204 { 205 206 unsigned long quot; 207 unsigned long rem; 208 209 } ldivu_t; 210 211 extern void __LIB__ _div_(div_t *d,int numer,int denom) __smallc; 212 extern void __LIB__ _div__callee(div_t *d,int numer,int denom) __smallc __z88dk_callee; 213 #define _div_(a,b,c) _div__callee(a,b,c) 214 215 216 extern void __LIB__ _divu_(divu_t *d,unsigned int numer,unsigned int denom) __smallc; 217 extern void __LIB__ _divu__callee(divu_t *d,unsigned int numer,unsigned int denom) __smallc __z88dk_callee; 218 #define _divu_(a,b,c) _divu__callee(a,b,c) 219 220 221 extern void __LIB__ _ldiv_(ldiv_t *ld,long numer,long denom) __smallc; 222 extern void __LIB__ _ldiv__callee(ldiv_t *ld,long numer,long denom) __smallc __z88dk_callee; 223 #define _ldiv_(a,b,c) _ldiv__callee(a,b,c) 224 225 226 extern void __LIB__ _ldivu_(ldivu_t *ld,unsigned long numer,unsigned long denom) __smallc; 227 extern void __LIB__ _ldivu__callee(ldivu_t *ld,unsigned long numer,unsigned long denom) __smallc __z88dk_callee; 228 #define _ldivu_(a,b,c) _ldivu__callee(a,b,c) 229 230 231 232 ////////////////////////// 233 //// Misc Number Functions 234 ////////////////////////// 235 236 extern int __LIB__ abs(int n) __z88dk_fastcall; 237 extern long __LIB__ labs(long n) __z88dk_fastcall; 238 239 extern uint __LIB__ isqrt(uint n) __z88dk_fastcall; 240 241 242 /******************************************************/ 243 /* NON-STANDARD BUT GENERALLY USEFUL FOR Z80 MACHINES */ 244 /******************************************************/ 245 246 247 ////////////// 248 //// I/O PORTS 249 ////////////// 250 251 // For accessing 16-bit i/o ports from C. The macros can be 252 // used to inline code if the parameters resolve to constants. 253 254 extern unsigned int __LIB__ inp(unsigned int port) __z88dk_fastcall; 255 extern void __LIB__ outp(unsigned int port, unsigned int byte) __smallc; 256 extern void __LIB__ outp_callee(unsigned int port, unsigned int byte) __smallc __z88dk_callee; 257 258 #define outp(a,b) outp_callee(a,b) 259 260 #define M_INP(port) asm("ld\tbc,"#port"\nin\tl,(c)\nld\th,0\n"); 261 #define M_INP8(port) asm("in\ta,("#port")\nld\tl,a\nld\th,0\n"); 262 #define M_OUTP(port,byte) asm("ld\tbc,"#port"\nld\ta,"#byte"\nout\t(c),a\n"); 263 #define M_OUTP8(port,byte) asm("ld\ta,"#byte"\nout\t("#port"),a\n"); 264 265 /////////////////////////////// 266 //// Direct Memory Manipulation 267 /////////////////////////////// 268 269 extern void __LIB__ *swapendian(void *addr) __z88dk_fastcall; 270 271 // The macros can be used to inline code if the parameters resolve to constants 272 273 extern void __LIB__ bpoke(void *addr, unsigned char byte) __smallc; 274 extern void __LIB__ bpoke_callee(void *addr, unsigned char byte) __smallc __z88dk_callee; 275 extern void __LIB__ wpoke(void *addr, unsigned int word) __smallc; 276 extern void __LIB__ wpoke_callee(void *addr, unsigned int word) __smallc __z88dk_callee; 277 extern unsigned char __LIB__ bpeek(const void *addr) __z88dk_fastcall; 278 extern unsigned int __LIB__ wpeek(const void *addr) __z88dk_fastcall; 279 280 #define bpoke(a,b) bpoke_callee(a,b) 281 #define wpoke(a,b) wpoke_callee(a,b) 282 283 #define M_BPOKE(addr,byte) asm("ld\thl,"#addr"\nld\t(hl),"#byte"\n"); 284 #define M_WPOKE(addr,word) asm("ld\thl,"#addr"\nld\t(hl),"#word"%256\ninc\thl\nld\t(hl),"#word"/256\n"); 285 #define M_BPEEK(addr) asm("ld\thl,("#addr")\nld\th,0\n"); 286 #define M_WPEEK(addr) asm("ld\thl,("#addr")\n"); 287 288 ////////////////////////////////////////////////// 289 // Timing (some are non-standard) 290 ////////////////////////////////////////////////// 291 292 // ACCURATE T-STATE DELAY 293 extern void __LIB__ t_delay(unsigned int tstates) __z88dk_fastcall; // at least 141 T 294 295 extern int __LIB__ __SAVEFRAME__ sleep (int secs) __z88dk_fastcall; 296 extern void __LIB__ msleep(unsigned int milliseconds) __z88dk_fastcall; 297 298 #ifdef __Z88__ 299 /* Sleep for a number of centiseconds */ 300 extern void __LIB__ __SAVEFRAME__ csleep(unsigned int centiseconds) __z88dk_fastcall; 301 #else 302 #define csleep(x) msleep((x) * 10) 303 #endif 304 305 306 /*********/ 307 /* OTHER */ 308 /*********/ 309 310 // Non standard stdlib.h defs (mode is ignored) 311 // Extract a given number of bits from a byte string (at specified bit position) and load into a long value 312 extern unsigned long __LIB__ extract_bits(unsigned char *data, unsigned int start, unsigned int size) __smallc; 313 extern unsigned long __LIB__ extract_bits_callee(unsigned char *data, unsigned int start, unsigned int size) __smallc __z88dk_callee; 314 315 #define extract_bits(a,b,c) extract_bits_callee(a,b,c) 316 317 // Compare a file name in "8.3" format to a wildcard expression 318 extern int __LIB__ wcmatch(char *wildnam, char *filnam) __smallc; 319 320 // Convert a BCD encoded value to unsigned int 321 extern unsigned int __LIB__ unbcd(unsigned int value); 322 323 #ifdef __Z88__ 324 extern int system(const char *text); /* should this be in the z88 library? */ 325 #endif 326 327 328 329 #endif 330