nckernel  0.1
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
debug.c
Go to the documentation of this file.
1 #include <sys/types.h>
2 #include <stdio.h>
3 #include <stddef.h>
4 #include <stdarg.h>
5 #include <debug.h>
6 
7 #define VIDEORAM 0xb8000
8 #define COLS 80
9 #define ROWS 25
10 #define MAXCOL 2000
11 #define TABSIZE 7
12 #define BGCOLOR 0x70
13 
14 /* only for x86 and debugging */
15 static inline int hex_to_rstr(unsigned d, char *out)
16 {
17  const char *hex_table = "0123456789abcdef";
18  int ret;
19 
20  ret = 0;
21  while (d / 16) {
22  out[ret++] = hex_table[(d % 16)];
23  d /= 16;
24  }
25 
26  out[ret++] = hex_table[(d % 16)];
27  return ret;
28 }
29 
30 static inline int unsigned_to_rstr(unsigned d, char *out)
31 {
32  int ret;
33 
34  ret = 0;
35  while (d / 10) {
36  out[ret++] = (d % 10) + '0';
37  d /= 10;
38  }
39 
40  out[ret++] = (d % 10) + '0';
41  return ret;
42 }
43 
44 static inline int signed_to_rstr(int d, char *out)
45 {
46  int ret;
47 
48  ret = 0;
49  while (d / 10) {
50  out[ret++] = ((d % 10) * (d < 0 ? -1 : 1)) + '0';
51  d /= 10;
52  }
53 
54  out[ret++] = ((d % 10) * (d < 0 ? -1 : 1)) + '0';
55 
56  if (d < 0) {
57  out[ret++] = '-';
58  }
59  return ret;
60 }
61 
62 static inline int dbg_putc(char ch, off_t *offset)
63 {
64  char *video = (char*)VIDEORAM;
65 
66  switch (ch) {
67  case '\t':
68  *offset += TABSIZE;
69  break;
70  case '\n':
71  *offset += (COLS - ((*offset) % COLS));
72  break;
73  case '\r':
74  *offset -= (*offset % COLS);
75  break;
76  default:
77  video += (*offset << 1);
78  *video++ = ch;
79  *video = BGCOLOR;
80  (*offset)++;
81  break;
82  }
83 
84  if (*offset == MAXCOL) {
85  *offset = 0;
86  }
87 
88  return 0;
89 }
90 
91 static inline int dbg_vfprintf(off_t *offset, const char *format, va_list ap)
92 {
93  int ret;
94  int pntsz;
95  register int i;
96  register int j;
97  const char *fmt;
98  char *str;
99  char ch;
100  char digit[12];
101  enum state {
102  NORMAL,
103  ARG,
104  } state;
105 
106  i = 0;
107  pntsz = 0;
108  fmt = format;
109  state = NORMAL;
110  while (fmt[i]) {
111  ch = fmt[i];
112 
113  switch (ch) {
114  case '%':
115  state = ARG;
116  break;
117  default:
118  if (state == NORMAL) {
119  dbg_putc(ch, offset);
120  pntsz++;
121  break;
122  }
123 
124  switch (ch) {
125  case '%':
126  dbg_putc(ch, offset);
127  pntsz++;
128  break;
129  case 'p':
130  dbg_putc('0', offset);
131  dbg_putc('x', offset);
132  pntsz += 2;
133  case 'x':
134  j = hex_to_rstr(
135  va_arg(ap, unsigned), digit);
136  while (j-- > 0) {
137  ret = dbg_putc(digit[j], offset);
138  if (ret < 0) {
139  return ret;
140  }
141  pntsz++;
142  }
143  break;
144  case 'u':
145  j = unsigned_to_rstr(
146  va_arg(ap, unsigned), digit);
147  while (j-- > 0) {
148  ret = dbg_putc(digit[j], offset);
149  if (ret < 0) {
150  return ret;
151  }
152  pntsz++;
153  }
154  break;
155  case 'd':
156  j = signed_to_rstr(va_arg(ap, int), digit);
157  while (j-- > 0) {
158  ret = dbg_putc(digit[j], offset);
159  if (ret < 0) {
160  return ret;
161  }
162  pntsz++;
163  }
164  break;
165  case 's':
166  str = (char*)va_arg(ap, char*);
167  while (*str) {
168  ret = dbg_putc(*str++, offset);
169  if (ret < 0) {
170  return ret;
171  }
172  pntsz++;
173  }
174  break;
175  case 'c':
176  ch = (char)va_arg(ap, unsigned int);
177  ret = dbg_putc(ch, offset);
178  if (ret < 0) {
179  return ret;
180  }
181  pntsz++;
182  break;
183  default:
184  break;
185  }
186 
187  state = NORMAL;
188  break;
189  }
190 
191  i++;
192  }
193 
194  return pntsz;
195 }
196 
197 int dbg_printf(const char *format, ...)
198 {
199  va_list ap;
200  static off_t offset = 0;
201  int ret;
202 
203  va_start(ap, format);
204  ret = dbg_vfprintf(&offset, format, ap);
205  va_end(ap);
206 
207  return ret;
208 }
209 
210 /* End of a file */