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

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