/* Support.c, Copyright (c) by Christian Conrad, Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. TOPSY -- A Teachable Operating System. Implementation of a tiny and simple micro kernel for teaching purposes. For further information, please visit http://www.tik.ee.ethz.ch/~topsy This software is provided under the terms of the GNU General Public Licence. A full copy of the GNU GPL is provided in the file COPYING found in the development root of Topsy. */ /* File: $Source: /usr/drwho/vault/cvs/topsy/Topsy/Topsy/Support.c,v $ Author(s): Christian Conrad Affiliation: ETH Zuerich, TIK Version: $Revision: 1.9 $ Creation Date: Last Date of Change: $Date: 2000/03/31 17:50:40 $ by: $Author: gfa $ $Log: Support.c,v $ Revision 1.9 2000/03/31 17:50:40 gfa Merged with /Net from several term projects Revision 1.8 1999/12/13 21:48:37 ruf GNU General Public Licence Update Revision 1.7 1999/10/27 14:20:10 jeker fixes in mips asm code Revision 1.6 1998/06/05 14:40:12 gfa get/set time Revision 1.5 1998/04/11 20:21:07 gfa added longCopy() * Revision 1.4 97/03/16 22:14:24 gfa * added zeroOut * * Revision 1.3 1997/02/27 14:39:29 conrad * Adding of function stringCopy() * * Revision 1.2 1997/02/25 17:00:36 conrad * writing of byteCopy() * * Revision 1.1 1997/02/20 09:36:46 conrad * Initial revision * */ #include "Support.h" void byteCopy( Address targetAddress, Address sourceAddress, unsigned long int nbBytes) { long* tar = (long*)targetAddress; long* src = (long*)sourceAddress; int rem; rem = nbBytes % (sizeof(long)/sizeof(char)); nbBytes /= (sizeof(long)/sizeof(char)); /* long copy */ for (; nbBytes > 0; nbBytes--) { *tar++ = *src++; } /* byte copy the remaining bytes */ if(rem) { char* source = (char *)(src-1); char* target = (char *)(tar-1); target++; source++; for( ; rem > 0; rem--) *target++ = *source++; } } void zeroOut( Address targetAddress, unsigned long int nbBytes) { long* tar = (long*)targetAddress; int rem; rem = nbBytes % (sizeof(long)/sizeof(char)); nbBytes /= (sizeof(long)/sizeof(char)); /* long zeroout */ for (; nbBytes > 0; nbBytes--) { *tar++ = 0; } /* byte copy the remaining bytes */ if(rem) { char* target = (char *)(tar-1); target++; for( ; rem > 0; rem--) *target++ = 0; } } void stringCopy( char* target, char* source) { while ((*target++ = *source++) != '\0') ; } void stringNCopy(char* target, char* source, unsigned long int size) { while (((*target++ = *source++) != '\0') && ((--size) > 1)) ; *target = '\0'; } Boolean isStringEqual(char* s1, char* s2, int maxLength) { int i = 0; while (i++ < maxLength) { if (*s1 == *s2) { if (*s1 == '\0') return TRUE; } else { return FALSE; } } return TRUE; } int stringLength(char* s) { int len=0; if (s!=NULL) { while (*s++ != '\0') { len++; } } return len; } #define SIGN_MASK (1UL << (sizeof(long)*8-1)) #define FLAG_SIGNED 1 static void format_long(char **buf, unsigned long val, char type, int prec, int flags) { int base = 10, fillzero=0, fillwidth=0; char tmp[20]; int pos=0, i; static char *digit = "0123456789ABCDEF"; if((flags & FLAG_SIGNED) && (val & SIGN_MASK)) { *(*buf)++ = '-'; val ^= SIGN_MASK; } switch(type) { case 'p': fillzero=1; fillwidth=8; *(*buf)++ = '0'; *(*buf)++ = 'x'; case 'x': case 'X': base=16; break; } if(val==0) { tmp[0]=digit[0]; pos++; } else while(val) { tmp[pos] = digit[val%base]; val = val / base; pos++; } if(fillzero) { for(i=pos; i=0; pos--) { *(*buf)++ = tmp[pos]; } } /* this is far from complete and standard... */ /* kernel must not use floats anyway... (gfa) */ int vsprintf(char *buf, char *fmt, va_list args) { char *str = buf; char *sval; unsigned long lval; int isflag, width, prec, islong, flags; for(; *fmt; fmt++) { if(*fmt != '%') { *str++ = *fmt; continue; } width=0; prec=0; flags=0; islong=0; do { fmt++; isflag=0; switch(*fmt) { case '%': *str++ = '%'; break; case 'c': *str++ = va_arg(args, char); break; case 's': for(sval = va_arg(args, char *); *sval; sval++) *str++ = *sval; break; case 'l': islong=1; isflag=1; break; case 'u': if(islong) lval = va_arg(args, unsigned long); else lval = va_arg(args, unsigned int); format_long(&str, lval, 'd', prec, flags); break; case 'd': if(islong) lval = va_arg(args, long); else lval = va_arg(args, int); format_long(&str, lval, 'd', prec, flags|FLAG_SIGNED); break; case 'p': lval = va_arg(args, unsigned long); format_long(&str, lval, 'p', prec, flags|FLAG_SIGNED); break; default: *str++ = *fmt; break; } } while(*fmt && isflag); } *str = '\0'; return str-buf; } int printk(char *fmt, ...) { va_list ap; unsigned long int len; char buf[200]; va_start(ap, fmt); len = vsprintf(buf, fmt, ap); ioConsolePutString(buf); va_end(ap); return len; }