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

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