source: libcaca/trunk/kernel/klibc.c @ 4333

Last change on this file since 4333 was 4333, checked in by Sam Hocevar, 10 years ago

Large source code cleanup, getting rid of spaces, tabs, and svn keywords.

File size: 11.6 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2006 Sam Hocevar <sam@hocevar.net>
4 *                2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
5 *                All Rights Reserved
6 *
7 *  This library is free software. It comes without any warranty, to
8 *  the extent permitted by applicable law. You can redistribute it
9 *  and/or modify it under the terms of the Do What The Fuck You Want
10 *  To Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14#include "config.h"
15#include "caca_types.h"
16
17#include "klibc.h"
18#include "drivers/timer.h"
19#include "kernel.h"
20
21
22void htoa(unsigned int value, char s[]);
23
24#define IS_DIGIT(x) (x>='0' && x<='9')
25#define IS_ALPHA(x) (x>='A' && x<='z')
26#define IS_UPPER(x) (x>='A' && x<='Z')
27#define IS_LOWER(x) (x>='a' && x<='z')
28#define UPPER(x) (IS_LOWER(x)?(x+('A'-'a')):x)
29#define LOWER(x) (IS_UPPER(x)?(x-('a'-'A')):x)
30
31/* Our default seed for random number generator */
32static int seed = 0x68743284;
33
34/* Our memory mapping */
35static uint32_t *freemem = (uint32_t *) 0x00200000;
36int kX = 0;
37int kY = 0;
38
39void scroll(void)
40{
41    unsigned char *video, *tmp;
42
43    for (video = (unsigned char *)0xB8000; video < (unsigned char *)0xB8FA0;
44         video++)
45    {
46        tmp = (unsigned char *)(video + 1 * 160);
47
48        if (tmp < (unsigned char *)0xB8FA0)
49            *video = *tmp;
50        else
51            *video = 0;
52    }
53
54    kY -= 1;
55    if (kY < 0)
56        kY = 0;
57}
58
59void putcar(unsigned char c)
60{
61    unsigned char *video;
62
63    if (c == 10)
64    {
65        kX = 0;
66        kY++;
67    }
68    else
69    {
70        video = (unsigned char *)(0xB8000 + 2 * kX + 160 * kY);
71        *video = c;
72        *(video + 1) = 0x07;
73
74        kX++;
75        if (kX > 79)
76        {
77            kX = 0;
78            kY++;
79        }
80        if (kY >= 24)
81        {
82            scroll();
83        }
84    }
85}
86
87void print(char *str)
88{
89    char const *ptr = str;
90    while (*ptr)
91    {
92        putcar(*ptr++);
93    }
94}
95
96void clearscreen(void)
97{
98    int x, y;
99    kX = 0;
100    kY = 0;
101    for (y = 0; y < 25; y++)
102        for (x = 0; x < 80; x++)
103        {
104            putcar(' ');
105        }
106    kX = 0;
107    kY = 0;
108}
109
110/* stdlib.h functions */
111void *malloc(size_t size)
112{
113    uint32_t *p = freemem;
114    if (!size)
115        return NULL;
116    size = (size + 0x7) / 4;
117    *p = size;
118    freemem += size + 1;
119    return p + 1;
120}
121
122void free(void *ptr)
123{
124    return;
125}
126
127void *realloc(void *ptr, size_t size)
128{
129    uint32_t oldsize;
130    void *p;
131
132    if (!size)
133        return NULL;
134
135    if (!ptr)
136        oldsize = 0;
137    else
138    {
139        oldsize = ((uint32_t *) ptr)[-1];
140        if (oldsize >= size)
141            return ptr;
142    }
143
144    p = malloc(size);
145    memcpy(p, ptr, oldsize);
146    return p;
147}
148
149char *getenv(const char *name)
150{
151    return NULL;
152}
153
154int getpid(void)
155{
156    return 0x1337;
157}
158
159void srand(unsigned int s)
160{
161    seed = rand();
162}
163
164int time(void *dummy)
165{
166    return rand();
167}
168
169int rand(void)
170{
171    seed = (seed * 0x7f32ba17) ^ 0xf893a735;
172    return seed % RAND_MAX;
173}
174
175int abs(int j)
176{
177    if (j < 0)
178        return -j;
179    return j;
180}
181
182void exit(int status)
183{
184    /* FIXME: reboot? */
185    while (1);
186}
187
188int atexit(void (*function) (void))
189{
190    /* FIXME: register function */
191    return 0;
192}
193
194/* string.h functions */
195void *memset(void *s, int c, size_t n)
196{
197    uint8_t *ptr = s;
198
199    while (n--)
200        *ptr++ = c;
201
202    return s;
203}
204
205void *memcpy(void *dest, const void *src, size_t n)
206{
207    uint8_t *destptr = dest;
208    uint8_t const *srcptr = src;
209
210    while (n--)
211        *destptr++ = *srcptr++;
212
213    return dest;
214}
215
216void *memmove(void *dest, const void *src, size_t n)
217{
218    memcpy(freemem, src, n);
219    memcpy(dest, freemem, n);
220    return dest;
221}
222
223size_t strlen(const char *s)
224{
225    int len = 0;
226
227    while (*s++)
228        len++;
229
230    return len;
231}
232
233int strcmp(const char *s1, const char *s2)
234{
235    while (*s1 && *s1 == *s2)
236    {
237        s1++;
238        s2++;
239    }
240
241    return (int)*s1 - (int)*s2;
242}
243
244int strcasecmp(const char *s1, const char *s2)
245{
246    while (*s1 && *s2 && UPPER(*s1) == UPPER(*s2))
247    {
248        s1++;
249        s2++;
250    }
251
252    return (int)UPPER(*s1) - (int)UPPER(*s2);
253}
254
255int memcmp(const void *_s1, const void *_s2, size_t n)
256{
257    uint8_t const *s1 = _s1, *s2 = _s2;
258
259    while (n--)
260    {
261        if (*s1 != *s2)
262            return (int)*s1 - (int)*s2;
263        s1++;
264        s2++;
265    }
266    return 0;
267}
268
269char *strdup(const char *s)
270{
271    char *new;
272    unsigned int len = strlen(s);
273
274    new = malloc(len + 1);
275    memcpy(new, s, len + 1);
276
277    return new;
278}
279
280char *strchr(const char *s, int c)
281{
282    do
283        if (*s == c)
284            return (char *)(intptr_t) s;
285    while (*s++);
286
287    return NULL;
288}
289
290/* stdarg.h functions */
291int vsnprintf(char *str, size_t size, const char *format, va_list ap)
292{
293    /* FIXME */
294    return 0;
295}
296
297/* stdio.h functions */
298FILE *fopen(const char *path, const char *mode)
299{
300    /* FIXME */
301    return NULL;
302}
303
304int feof(FILE * stream)
305{
306    /* FIXME */
307    return 0;
308}
309
310char *fgets(char *s, int size, FILE * stream)
311{
312    /* FIXME */
313    return NULL;
314}
315
316size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE * stream)
317{
318    return 0;
319}
320
321int fclose(FILE * fp)
322{
323    /* FIXME */
324    return 0;
325}
326
327int printf(const char *fmt, ...)
328{
329    char str[200];
330    char tmp[100];
331    args_list args;
332    args_start(args, fmt);
333
334    char *s;
335    int ptr = 0;
336    int i = 0;
337
338    for (; fmt[i]; ++i)
339    {
340        if ((fmt[i] != '%') && (fmt[i] != '\\'))
341        {
342            str[ptr++] = fmt[i];
343            continue;
344        }
345        else if (fmt[i] == '\\')
346        {
347            switch (fmt[++i])
348            {
349            case 'a':
350                str[ptr++] = '\a';
351                break;
352            case 'b':
353                str[ptr++] = '\b';
354                break;
355            case 't':
356                str[ptr++] = '\t';
357                break;
358            case 'n':
359                str[ptr++] = '\n';
360                break;
361            case 'r':
362                str[ptr++] = '\r';
363                break;
364            case '\\':
365                str[ptr++] = '\\';
366                break;
367            }
368            continue;
369        }
370
371        switch (fmt[++i])
372        {
373        case 's':
374            s = (char *)args_next(args, char *);
375            while (*s)
376                str[ptr++] = *s++;
377            break;
378        case 'c':
379            str[ptr++] = (char)args_next(args, int);
380            break;
381        case 'p':
382        case 'x':
383            htoa((unsigned long)args_next(args, unsigned long), tmp);
384            memcpy(&str[ptr], tmp, strlen(tmp));
385            ptr += strlen(tmp);
386            break;
387        case 'd':
388            itoa((unsigned long)args_next(args, unsigned long), tmp);
389            memcpy(&str[ptr], tmp, strlen(tmp));
390            ptr += strlen(tmp);
391            break;
392        case '%':
393            str[ptr++] = '%';
394            break;
395        default:
396            str[ptr++] = fmt[i];
397            break;
398        }
399    }
400
401    str[ptr] = '\0';
402    args_end(args);
403
404    print(str);
405
406    return 0;
407}
408
409int fprintf(FILE * stream, const char *format, ...)
410{
411    /* FIXME */
412    return 0;
413}
414
415int fflush(FILE * stream)
416{
417    /* FIXME */
418    return 0;
419}
420
421int sprintf(char *str, const char *fmt, ...)
422{
423    char tmp[100];
424    args_list args;
425    args_start(args, fmt);
426
427    char *s;
428    int ptr = 0;
429    int i = 0;
430
431    for (; fmt[i]; ++i)
432    {
433        if ((fmt[i] != '%') && (fmt[i] != '\\'))
434        {
435            str[ptr++] = fmt[i];
436            continue;
437        }
438        else if (fmt[i] == '\\')
439        {
440            switch (fmt[++i])
441            {
442            case 'a':
443                str[ptr++] = '\a';
444                break;
445            case 'b':
446                str[ptr++] = '\b';
447                break;
448            case 't':
449                str[ptr++] = '\t';
450                break;
451            case 'n':
452                str[ptr++] = '\n';
453                break;
454            case 'r':
455                str[ptr++] = '\r';
456                break;
457            case '\\':
458                str[ptr++] = '\\';
459                break;
460            }
461            continue;
462        }
463
464        switch (fmt[++i])
465        {
466        case 's':
467            s = (char *)args_next(args, char *);
468            while (*s)
469                str[ptr++] = *s++;
470            break;
471        case 'c':
472            str[ptr++] = (char)args_next(args, int);
473            break;
474        case 'p':
475        case 'x':
476            htoa((unsigned long)args_next(args, unsigned long), tmp);
477            memcpy(&str[ptr], tmp, strlen(tmp));
478            ptr += strlen(tmp);
479            break;
480        case 'd':
481            itoa((unsigned long)args_next(args, unsigned long), tmp);
482            memcpy(&str[ptr], tmp, strlen(tmp));
483            ptr += strlen(tmp);
484            break;
485        case '%':
486            str[ptr++] = '%';
487            break;
488        default:
489            str[ptr++] = fmt[i];
490            break;
491        }
492    }
493
494    str[ptr] = '\0';
495    args_end(args);
496
497    return 0;
498}
499
500int sscanf(const char *str, const char *format, ...)
501{
502    /* FIXME */
503    return 0;
504}
505
506/* unistd.h functions */
507void usleep(unsigned long usec)
508{
509    u32 start = ticks;
510    signed int diff = 0;
511
512    while (1)
513    {
514        diff = (signed int)(ticks - start);
515        if (diff >= (signed int)(usec / 20))
516            break;
517    }
518}
519
520void sleep(unsigned long sec)
521{
522    usleep(sec * 1000);
523}
524
525
526int gettimeofday(struct timeval *tv, struct timezone *tz)
527{
528    static int usec = 0;
529    static int sec = 0;
530
531    /* FIXME */
532    usec += 10000;
533    if (usec > 1000000)
534    {
535        sec++;
536        usec -= 1000000;
537    }
538
539    tv->tv_sec = sec;
540    tv->tv_usec = usec;
541
542    return 0;
543}
544
545/* math.h functions */
546double cos(double x)
547{
548    double ret = 0.0;
549#ifdef HAVE_FSIN_FCOS
550    asm volatile ("fcos":"=t" (ret):"0"(x));
551#else
552    double x2;
553    double num = 1.0;
554    double fact = 1.0;
555    int i;
556
557    x = x - ((double)(int)(x / (2 * M_PI))) * (2 * M_PI);
558    x2 = x * x;
559
560    /* cos(x) = 1/0! - x^2/2! + x^4/4! - x^6/6! ... */
561    for (i = 0; i < 10; i++)
562    {
563        ret += num / fact;
564        num *= -x2;
565        fact *= (2 * i + 1) * (2 * i + 2);
566    }
567#endif
568    return ret;
569}
570
571double sin(double x)
572{
573    double ret = 0.0;
574#ifdef HAVE_FSIN_FCOS
575    asm volatile ("fsin":"=t" (ret):"0"(x));
576#else
577    double x2;
578    double num;
579    double fact = 1.0;
580    int i;
581
582    x = x - ((double)(int)(x / (2 * M_PI))) * (2 * M_PI);
583    x2 = x * x;
584    num = x;
585
586    /* sin(x) = x/1! - x^3/3! + x^5/5! - x^7/7! ... */
587    for (i = 0; i < 10; i++)
588    {
589        ret += num / fact;
590        num *= -x2;
591        fact *= (2 * i + 2) * (2 * i + 3);
592    }
593#endif
594    return ret;
595}
596
597double sqrt(double x)
598{
599    double ret = x;
600    int i;
601
602    /* This is Newton's method */
603    for (i = 0; i < 10; i++)
604        ret = (ret * ret + x) / (ret * 2.0);
605
606    return ret;
607}
608
609
610/* reverse: reverse string s in place */
611void reverse(char s[])
612{
613    int i, j;
614    char c;
615
616    for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
617    {
618        c = s[i];
619        s[i] = s[j];
620        s[j] = c;
621    }
622}
623
624
625/* itoa implementation, by Kernighan and Ritchie's The C Programming Language */
626void itoa(int n, char s[])
627{
628    int i, sign;
629
630    if ((sign = n) < 0)         /* record sign */
631        n = -n;                 /* make n positive */
632    i = 0;
633    do
634    {                           /* generate digits in reverse order */
635        s[i++] = n % 10 + '0';  /* get next digit */
636    }
637    while ((n /= 10) > 0);      /* delete it */
638    if (sign < 0)
639        s[i++] = '-';
640    s[i] = '\0';
641    reverse(s);
642}
643
644void htoa(unsigned int value, char s[])
645{
646    int i = 8;
647    int ptr = 0;
648    while (i-- > 0)
649    {
650        s[ptr++] = "0123456789abcdef"[(value >> (i * 4)) & 0xf];
651    }
652    s[ptr] = 0;
653}
654
655
656/* errno.h stuff */
657int errno = 0;
Note: See TracBrowser for help on using the repository browser.