stdlib.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * Standard library
  3. * Contains basic functions, including timer and memory functions
  4. * Modified version for BCC
  5. */
  6. // uses math.c
  7. #define UART_TX_ADDR 0xC02723
  8. // Timer I/O Addresses
  9. #define TIMER1_VAL 0xC02739
  10. #define TIMER1_CTRL 0xC0273A
  11. #define TIMER2_VAL 0xC0273B
  12. #define TIMER2_CTRL 0xC0273C
  13. #define TIMER3_VAL 0xC0273D
  14. #define TIMER3_CTRL 0xC0273E
  15. // isalpha
  16. word isalpha(word argument)
  17. {
  18. if (argument >= 'A' && argument <= 'Z')
  19. return 2;
  20. if (argument >= 'a' && argument <= 'z')
  21. return 1;
  22. return 0;
  23. }
  24. // isdigit
  25. word isdigit(word argument)
  26. {
  27. if (argument >= '0' && argument <= '9')
  28. return 1;
  29. return 0;
  30. }
  31. // isalnum
  32. word isalnum(word argument)
  33. {
  34. if (isdigit(argument) || isalpha(argument))
  35. return 1;
  36. return 0;
  37. }
  38. void* memcpy(void *dest, const void *src, size_t len)
  39. {
  40. // Typecast src and dest addresses to (char *)
  41. char *csrc = (char *)src;
  42. char *cdest = (char *)dest;
  43. // Copy contents of src[] to dest[]
  44. word i;
  45. for (i=0; i<len; i++)
  46. cdest[i] = csrc[i];
  47. }
  48. void* memmove(void* dest, const void* src, size_t n)
  49. {
  50. unsigned char* from = (unsigned char*) src;
  51. unsigned char* to = (unsigned char*) dest;
  52. if (from == to || n == 0)
  53. return dest;
  54. if (to > from && to-from < (word)n) {
  55. /* to overlaps with from */
  56. /* <from......> */
  57. /* <to........> */
  58. /* copy in reverse, to avoid overwriting from */
  59. word i;
  60. for(i=n-1; i>=0; i--)
  61. to[i] = from[i];
  62. return dest;
  63. }
  64. if (from > to && from-to < (word)n) {
  65. /* to overlaps with from */
  66. /* <from......> */
  67. /* <to........> */
  68. /* copy forwards, to avoid overwriting from */
  69. size_t i;
  70. for(i=0; i<n; i++)
  71. to[i] = from[i];
  72. return dest;
  73. }
  74. memcpy(dest, src, n);
  75. return dest;
  76. }
  77. // Function to implement `strcpy()` function
  78. char* strcpy(char* destination, const char* source)
  79. {
  80. // return if no memory is allocated to the destination
  81. if (destination == NULL) {
  82. return NULL;
  83. }
  84. // take a pointer pointing to the beginning of the destination string
  85. char *ptr = destination;
  86. // copy the C-string pointed by source into the array
  87. // pointed by destination
  88. while (*source != '\0')
  89. {
  90. *destination = *source;
  91. destination++;
  92. source++;
  93. }
  94. // include the terminating null character
  95. *destination = '\0';
  96. // the destination is returned by standard `strcpy()`
  97. return ptr;
  98. }
  99. size_t strlen(const char *str)
  100. {
  101. const char *s;
  102. for (s = str; *s; ++s);
  103. return (s - str);
  104. }
  105. char* strcat (char *dest, const char *src)
  106. {
  107. strcpy (dest + strlen (dest), src);
  108. return dest;
  109. }
  110. char* strchr (const char *s, word c)
  111. {
  112. do {
  113. if (*s == c)
  114. {
  115. return (char*)s;
  116. }
  117. } while (*s++);
  118. return (0);
  119. }
  120. word strcmp(const char* s1, const char* s2)
  121. {
  122. while(*s1 && (*s1 == *s2))
  123. {
  124. s1++;
  125. s2++;
  126. }
  127. return *(unsigned char*)s1 - *(unsigned char*)s2;
  128. }
  129. word strncmp(const char * s1, const char * s2, size_t n )
  130. {
  131. while ( n && *s1 && ( *s1 == *s2 ) )
  132. {
  133. ++s1;
  134. ++s2;
  135. --n;
  136. }
  137. if ( n == 0 )
  138. {
  139. return 0;
  140. }
  141. else
  142. {
  143. return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
  144. }
  145. }
  146. // Returns interrupt ID by using the readintid asm instruction
  147. word getIntID()
  148. {
  149. word retval = 0;
  150. asm(
  151. "readintid r2 ;reads interrupt id to r2\n"
  152. "write -4 r14 r2 ;write to stack to return\n"
  153. );
  154. return retval;
  155. }
  156. /*
  157. Recursive helper function for itoa
  158. Eventually returns the number of digits in n
  159. s is the output buffer
  160. */
  161. word itoar(word n, char *s)
  162. {
  163. word digit = MATH_modU(n, 10);
  164. word i = 0;
  165. n = MATH_divU(n,10);
  166. if ((unsigned int) n > 0)
  167. i += itoar(n, s);
  168. s[i++] = digit + '0';
  169. return i;
  170. }
  171. /*
  172. Converts integer n to characters.
  173. The characters are placed in the buffer s.
  174. The buffer is terminated with a 0 value.
  175. Uses recursion, division and mod to compute.
  176. */
  177. void itoa(word n, char *s)
  178. {
  179. // compute and fill the buffer
  180. word i = itoar(n, s);
  181. // end with terminator
  182. s[i] = 0;
  183. }
  184. /*
  185. Prints a single char c by writing it to UART_TX_ADDR
  186. */
  187. void uprintc(char c)
  188. {
  189. word *p = (word *)UART_TX_ADDR; // address of UART TX
  190. *p = (word)c; // write char over UART
  191. }
  192. /*
  193. Sends each character from str over UART
  194. by writing them to UART_TX_ADDR
  195. until a 0 value is found.
  196. Does not send a newline afterwards.
  197. */
  198. void uprint(char* str)
  199. {
  200. word *p = (word *)UART_TX_ADDR; // address of UART TX
  201. char chr = *str; // first character of str
  202. while (chr != 0) // continue until null value
  203. {
  204. *p = (word)chr; // write char over UART
  205. str++; // go to next character address
  206. chr = *str; // get character from address
  207. }
  208. }
  209. /*
  210. Same as uprint(char* str),
  211. except it sends a newline afterwards.
  212. */
  213. void uprintln(char* str)
  214. {
  215. uprint(str);
  216. uprintc('\n');
  217. }
  218. // Converts char c to uppercase if possible
  219. char toUpper(char c)
  220. {
  221. if (c>96 && c<123)
  222. c = c ^ 0x20;
  223. return c;
  224. }
  225. // Converts string str to uppercase if possible
  226. void strToUpper(char* str)
  227. {
  228. char chr = *str; // first character of str
  229. while (chr != 0) // continue until null value
  230. {
  231. *str = toUpper(chr); // uppercase char
  232. str++; // go to next character address
  233. chr = *str; // get character from address
  234. }
  235. }