#include #if 1 static void outbyte(char c) { volatile char * const pc16550 = (char *) IO_TO_LOCAL(0x03f8); # define THR 0 # define LSR 5 # define THRE 0x20 while ((pc16550[LSR] & THRE) == 0) { ; } pc16550[THR] = c; } #else /* printk to memory for debugging */ static void outbyte(char c) { static char *memory_log = (char *) 0x01F00000; *memory_log++ = c; if (memory_log >= (char *) 0x01F80000) { memory_log--; } } #endif /*-------------------------------------------------------------------------+ | printk.c v1.1 - PC386 BSP - 1997/08/07 +--------------------------------------------------------------------------+ | (C) Copyright 1997 - | - NavIST Group - Real-Time Distributed Systems and Industrial Automation | | http://pandora.ist.utl.pt | | Instituto Superior Tecnico * Lisboa * PORTUGAL +--------------------------------------------------------------------------+ | Disclaimer: | | This file is provided "AS IS" without warranty of any kind, either | expressed or implied. +--------------------------------------------------------------------------+ | This code is based on code by: Jose Rufino - IST | | $Id$ +--------------------------------------------------------------------------*/ #include /*-------------------------------------------------------------------------+ | Function: printNum | Description: print number in a given base. | Global Variables: None. | Arguments: num - number to print, base - base used to print the number. | Returns: Nothing. +--------------------------------------------------------------------------*/ static void printNum(long unsigned int num, int base, int sign, int width, int zerofill) { long unsigned int n; int count, negative = 0; char toPrint[80]; char *digits = "0123456789ABCDEF"; if (width > sizeof(toPrint)) { width = sizeof(toPrint); } if ((sign == 1) && ((long) num < 0)) { negative = 1; num = -num; } count = 0; while ((n = num / base) > 0) { toPrint[count++] = digits[num - (n * base)]; num = n; } toPrint[count++] = digits[num]; if (count + negative < width) { /* this needs to be padded out to width */ if (zerofill) { while (count + negative < width) { toPrint[count++] = '0'; } if (negative) { toPrint[count++] = '-'; } } else { if (negative) { toPrint[count++] = '-'; } while (count < width) { toPrint[count++] = ' '; } } } else if (negative) { toPrint[count++] = '-'; } for (n = 0; n < count; n++) { outbyte(toPrint[count - (n + 1)]); } } /*-------------------------------------------------------------------------+ | Function: printk | Description: a simplified version of printf intended for use when the console is not yet initialized or in ISR's. | Global Variables: None. | Arguments: as in printf: fmt - format string, ... - unnamed arguments. | Returns: Nothing. +--------------------------------------------------------------------------*/ int printk_enabled = 1; void printk(char *fmt, ...) { va_list ap; /* points to each unnamed argument in turn */ char c, *str; int lflag, base, sign, width, zero; /* disable interrupts??? */ if (printk_enabled) { va_start(ap, fmt); /* make ap point to 1st unnamed arg */ for (; *fmt != '\0'; fmt++) { lflag = 0; base = 0; sign = 0; width = 0; if (*fmt == '\n') { outbyte('\r'); } if (*fmt == '%') { c = *++fmt; if (c == '0') { zero = 1; c = *++fmt; } else { zero = 0; } for (; c >= '0' && c <= '9'; c = *++fmt) { width = width * 10 + (c - '0'); } if (c == 'l') { lflag = 1; c = *++fmt; } switch (c) { case 'o': case 'O': base = 8; sign = 0; break; case 'd': case 'D': base = 10; sign = 1; break; case 'u': case 'U': base = 10; sign = 0; break; case 'x': case 'X': base = 16; sign = 0; break; case 's': for (str = va_arg(ap, char *); *str; str++) { outbyte(*str); width--; } while (width-- > 0) { outbyte(' '); } break; case 'c': outbyte(va_arg(ap, int)); break; default: outbyte(c); break; } if (base) { printNum(lflag ? va_arg(ap, long int) : (long int) va_arg(ap, int), base, sign, width, zero); } } else { outbyte(*fmt); } } va_end(ap); /* clean up when done */ /* enable interrupts??? */ } }