You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

658 regels
12 KiB

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