summaryrefslogtreecommitdiff
path: root/kernel/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/printf.c')
-rw-r--r--kernel/printf.c43
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.