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