Make the debugging functions slightly more portable.
[reactos.git] / reactos / boot / freeldr / freeldr / debug.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21
22 #include <debug.h>
23
24 #ifdef DEBUG
25
26 //#define DEBUG_ALL
27 //#define DEBUG_INIFILE
28 //#define DEBUG_REACTOS
29 //#define DEBUG_CUSTOM
30 #define DEBUG_NONE
31
32 #if defined (DEBUG_ALL)
33 ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
34 DPRINT_UI | DPRINT_DISK | DPRINT_CACHE | DPRINT_REACTOS |
35 DPRINT_LINUX | DPRINT_HWDETECT;
36 #elif defined (DEBUG_INIFILE)
37 ULONG DebugPrintMask = DPRINT_INIFILE;
38 #elif defined (DEBUG_REACTOS)
39 ULONG DebugPrintMask = DPRINT_REACTOS | DPRINT_REGISTRY;
40 #elif defined (DEBUG_CUSTOM)
41 ULONG DebugPrintMask = DPRINT_WARNING|DPRINT_FILESYSTEM|DPRINT_MEMORY|DPRINT_LINUX;
42 #else //#elif defined (DEBUG_NONE)
43 ULONG DebugPrintMask = 0;
44 #endif
45
46 #define SCREEN 1
47 #define RS232 2
48 #define BOCHS 4
49
50 #define COM1 1
51 #define COM2 2
52 #define COM3 3
53 #define COM4 4
54
55 #define BOCHS_OUTPUT_PORT 0xe9
56
57 ULONG DebugPort = RS232;
58 //ULONG DebugPort = SCREEN;
59 //ULONG DebugPort = BOCHS;
60 //ULONG DebugPort = SCREEN|BOCHS;
61 ULONG ComPort = COM1;
62 //ULONG BaudRate = 19200;
63 ULONG BaudRate = 115200;
64
65 BOOL DebugStartOfLine = TRUE;
66
67 VOID DebugInit(VOID)
68 {
69 if (DebugPort & RS232)
70 {
71 Rs232PortInitialize(ComPort, BaudRate);
72 }
73 }
74
75 VOID DebugPrintChar(UCHAR Character)
76 {
77 if (Character == '\n')
78 {
79 DebugStartOfLine = TRUE;
80 }
81
82 if (DebugPort & RS232)
83 {
84 if (Character == '\n')
85 {
86 Rs232PortPutByte('\r');
87 }
88 Rs232PortPutByte(Character);
89 }
90 if (DebugPort & BOCHS)
91 {
92 WRITE_PORT_UCHAR((PUCHAR)BOCHS_OUTPUT_PORT, Character);
93 }
94 if (DebugPort & SCREEN)
95 {
96 MachConsPutChar(Character);
97 }
98 }
99
100 VOID DebugPrintHeader(ULONG Mask)
101 {
102 /* No header */
103 if (Mask == 0)
104 return;
105
106 switch (Mask)
107 {
108 case DPRINT_WARNING:
109 DebugPrintChar('W');
110 DebugPrintChar('A');
111 DebugPrintChar('R');
112 DebugPrintChar('N');
113 DebugPrintChar('I');
114 DebugPrintChar('N');
115 DebugPrintChar('G');
116 DebugPrintChar(':');
117 DebugPrintChar(' ');
118 break;
119 case DPRINT_MEMORY:
120 DebugPrintChar('M');
121 DebugPrintChar('E');
122 DebugPrintChar('M');
123 DebugPrintChar('O');
124 DebugPrintChar('R');
125 DebugPrintChar('Y');
126 DebugPrintChar(':');
127 DebugPrintChar(' ');
128 break;
129 case DPRINT_FILESYSTEM:
130 DebugPrintChar('F');
131 DebugPrintChar('I');
132 DebugPrintChar('L');
133 DebugPrintChar('E');
134 DebugPrintChar('S');
135 DebugPrintChar('Y');
136 DebugPrintChar('S');
137 DebugPrintChar(':');
138 DebugPrintChar(' ');
139 break;
140 case DPRINT_INIFILE:
141 DebugPrintChar('I');
142 DebugPrintChar('N');
143 DebugPrintChar('I');
144 DebugPrintChar('F');
145 DebugPrintChar('I');
146 DebugPrintChar('L');
147 DebugPrintChar('E');
148 DebugPrintChar(':');
149 DebugPrintChar(' ');
150 break;
151 case DPRINT_UI:
152 DebugPrintChar('U');
153 DebugPrintChar('I');
154 DebugPrintChar(':');
155 DebugPrintChar(' ');
156 break;
157 case DPRINT_DISK:
158 DebugPrintChar('D');
159 DebugPrintChar('I');
160 DebugPrintChar('S');
161 DebugPrintChar('K');
162 DebugPrintChar(':');
163 DebugPrintChar(' ');
164 break;
165 case DPRINT_CACHE:
166 DebugPrintChar('C');
167 DebugPrintChar('A');
168 DebugPrintChar('C');
169 DebugPrintChar('H');
170 DebugPrintChar('E');
171 DebugPrintChar(':');
172 DebugPrintChar(' ');
173 break;
174 case DPRINT_REGISTRY:
175 DebugPrintChar('R');
176 DebugPrintChar('E');
177 DebugPrintChar('G');
178 DebugPrintChar('I');
179 DebugPrintChar('S');
180 DebugPrintChar('T');
181 DebugPrintChar('R');
182 DebugPrintChar('Y');
183 DebugPrintChar(':');
184 DebugPrintChar(' ');
185 break;
186 case DPRINT_REACTOS:
187 DebugPrintChar('R');
188 DebugPrintChar('E');
189 DebugPrintChar('A');
190 DebugPrintChar('C');
191 DebugPrintChar('T');
192 DebugPrintChar('O');
193 DebugPrintChar('S');
194 DebugPrintChar(':');
195 DebugPrintChar(' ');
196 break;
197 case DPRINT_LINUX:
198 DebugPrintChar('L');
199 DebugPrintChar('I');
200 DebugPrintChar('N');
201 DebugPrintChar('U');
202 DebugPrintChar('X');
203 DebugPrintChar(':');
204 DebugPrintChar(' ');
205 break;
206 case DPRINT_HWDETECT:
207 DebugPrintChar('H');
208 DebugPrintChar('W');
209 DebugPrintChar('D');
210 DebugPrintChar('E');
211 DebugPrintChar('T');
212 DebugPrintChar('E');
213 DebugPrintChar('C');
214 DebugPrintChar('T');
215 DebugPrintChar(':');
216 DebugPrintChar(' ');
217 break;
218 default:
219 DebugPrintChar('U');
220 DebugPrintChar('N');
221 DebugPrintChar('K');
222 DebugPrintChar('N');
223 DebugPrintChar('O');
224 DebugPrintChar('W');
225 DebugPrintChar('N');
226 DebugPrintChar(':');
227 DebugPrintChar(' ');
228 break;
229 }
230 }
231
232 VOID DebugPrint(ULONG Mask, char *format, ...)
233 {
234 va_list ap;
235 char Buffer[4096];
236 char *ptr = Buffer;
237
238 // Mask out unwanted debug messages
239 if (!(Mask & DebugPrintMask))
240 {
241 return;
242 }
243
244 // Print the header if we have started a new line
245 if (DebugStartOfLine)
246 {
247 DebugPrintHeader(Mask);
248 DebugStartOfLine = FALSE;
249 }
250
251 va_start(ap, format);
252 vsprintf(Buffer, format, ap);
253 va_end(ap);
254 while (*ptr)
255 {
256 DebugPrintChar(*ptr++);
257 }
258 }
259
260 VOID DebugPrint1(char *format, ...)
261 {
262 va_list ap;
263 char Buffer[4096];
264 char *ptr = Buffer;
265
266 va_start(ap, format);
267 vsprintf(Buffer, format, ap);
268 va_end(ap);
269 while (*ptr)
270 {
271 DebugPrintChar(*ptr++);
272 }
273 }
274
275 VOID DebugDumpBuffer(ULONG Mask, PVOID Buffer, ULONG Length)
276 {
277 PUCHAR BufPtr = (PUCHAR)Buffer;
278 ULONG Idx;
279 ULONG Idx2;
280
281 // Mask out unwanted debug messages
282 if (!(Mask & DebugPrintMask))
283 {
284 return;
285 }
286
287 DebugStartOfLine = FALSE; // We don't want line headers
288 DebugPrint(Mask, "Dumping buffer at 0x%x with length of %d bytes:\n", Buffer, Length);
289
290 for (Idx=0; Idx<Length; )
291 {
292 DebugStartOfLine = FALSE; // We don't want line headers
293
294 if (Idx < 0x0010)
295 {
296 DebugPrint(Mask, "000%x:\t", Idx);
297 }
298 else if (Idx < 0x0100)
299 {
300 DebugPrint(Mask, "00%x:\t", Idx);
301 }
302 else if (Idx < 0x1000)
303 {
304 DebugPrint(Mask, "0%x:\t", Idx);
305 }
306 else
307 {
308 DebugPrint(Mask, "%x:\t", Idx);
309 }
310
311 for (Idx2=0; Idx2<16; Idx2++,Idx++)
312 {
313 if (BufPtr[Idx] < 0x10)
314 {
315 DebugPrint(Mask, "0");
316 }
317 DebugPrint(Mask, "%x", BufPtr[Idx]);
318
319 if (Idx2 == 7)
320 {
321 DebugPrint(Mask, "-");
322 }
323 else
324 {
325 DebugPrint(Mask, " ");
326 }
327 }
328
329 Idx -= 16;
330 DebugPrint(Mask, " ");
331
332 for (Idx2=0; Idx2<16; Idx2++,Idx++)
333 {
334 if ((BufPtr[Idx] > 20) && (BufPtr[Idx] < 0x80))
335 {
336 DebugPrint(Mask, "%c", BufPtr[Idx]);
337 }
338 else
339 {
340 DebugPrint(Mask, ".");
341 }
342 }
343
344 DebugPrint(Mask, "\n");
345 }
346 }
347
348 #endif // defined DEBUG