diff options
Diffstat (limited to 'kernel/printf.c')
| -rw-r--r-- | kernel/printf.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/kernel/printf.c b/kernel/printf.c index e1347de..6312689 100644 --- a/kernel/printf.c +++ b/kernel/printf.c @@ -2,6 +2,8 @@ // formatted console output -- printf, panic. // +// TODO Printf to not use mul/div/mod and all that and send stuff to hw-implemented UART + #include <stdarg.h> #include "types.h" @@ -25,13 +27,43 @@ static struct { static char digits[] = "0123456789abcdef"; +int mul(int x, int y) +{ + int ret = x; + for (int tmp = y-1; tmp > 0; tmp--) { + // Add higher and lower 16 bits seperately + // apparently gcc uses muldi3 builtin while adding long long ints + int rettmp = ret; + ret = (((uint16)(x>>16))+((uint16)(rettmp>>16))); + ret += (((uint16)(x&0xffff))+((uint16)(rettmp&0xffff))); + } + return ret; +} + +int mod(int x, int y) +{ + int idx = 0; + for (idx = 0; mul(idx, y) <= x; idx++); + idx = x-mul((idx-1), y); + return idx; +} + +int div(int x, int y) +{ + if (y >= x) + return 0; + int ret = 1; + for (; (x=x-y) >= y; ret++); + return ret; +} + static void printint(int xx, int base, int sign) { char buf[16]; int i; uint x; - + if(sign && (sign = xx < 0)) x = -xx; else @@ -39,8 +71,9 @@ printint(int xx, int base, int sign) i = 0; do { - buf[i++] = digits[x % base]; - } while((x /= base) != 0); + buf[i++] = digits[mod(x, base)]; + x = div(x, base); + } while(x != 0); if(sign) buf[i++] = '-'; @@ -55,8 +88,8 @@ printptr(uint64 x) int i; consputc('0'); consputc('x'); - for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4) - consputc(digits[x >> (sizeof(uint64) * 8 - 4)]); + for (i = 0; i < (mul(sizeof(uint64), 2)); i++, x <<= 4) + consputc(digits[x >> (mul(sizeof(uint64), 8) - 4)]); } // Print to the console. only understands %d, %x, %p, %s. |
