source: GPL/trunk/lib32/debug.c@ 268

Last change on this file since 268 was 268, checked in by Brendan Oakley, 18 years ago

Make debug buffer larger, and fix alsahlp line endings, from Allan

File size: 17.4 KB
Line 
1/* $Id: debug.c,v 1.1.1.1 2003/07/02 13:57:02 eleph Exp $ */
2/*
3 * COM port debugging functions
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 */
24#define INCL_NOPMAPI
25#define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION
26#include <os2.h>
27
28#include <string.h>
29
30#define CR 0x0d
31#define LF 0x0a
32
33#define LEADING_ZEROES 0x8000
34#define SIGNIFICANT_FIELD 0x0007
35
36BOOL fLineTerminate=TRUE;
37int DebugLevel = 1;
38
39extern int wrOffset;
40extern char *szprintBuf;
41extern int max_buf_size;
42
43char hextab[]="0123456789ABCDEF";
44
45 //-------------------- DecLongToASCII -
46char * DecLongToASCII(char *StrPtr, ULONG lDecVal,USHORT Option)
47{
48 BOOL fNonZero=FALSE;
49 ULONG Digit;
50 ULONG Power=1000000000; // 1 billion
51 LONG lVal = (LONG)lDecVal;
52
53 if(lVal < 0) {
54 *StrPtr = '-';
55 StrPtr++;
56 lDecVal = -lDecVal;
57 }
58
59 while (Power)
60 {
61 Digit=0; // Digit=lDecVal/Power
62 while (lDecVal >=Power) // replaced with while loop
63 {
64 Digit++;
65 lDecVal-=Power;
66 }
67
68 if (Digit)
69 fNonZero=TRUE;
70
71 if (Digit ||
72 fNonZero ||
73 (Option & LEADING_ZEROES) ||
74 ((Power==1) && (fNonZero==FALSE)))
75 {
76 *StrPtr=(char)('0'+Digit);
77 StrPtr++;
78 }
79
80 if (Power==1000000000) // 1 billion
81 Power=100000000;
82 else if (Power==100000000)
83 Power=10000000;
84 else if (Power==10000000)
85 Power=1000000;
86 else if (Power==1000000)
87 Power=100000;
88 else if (Power==100000)
89 Power=10000;
90 else if (Power==10000)
91 Power=1000;
92 else if (Power==1000)
93 Power=100;
94 else if (Power==100)
95 Power=10;
96 else if (Power==10)
97 Power=1;
98 else
99 Power=0;
100 }
101 return (StrPtr);
102}
103 //-------------------- HexWordToASCII -
104 //-------------------- HexLongToASCII -
105char * HexLongToASCII(char *StrPtr, ULONG wHexVal, USHORT Option)
106{
107 BOOL fNonZero=FALSE;
108 ULONG Digit;
109 ULONG Power=0xF0000000;
110 ULONG ShiftVal=28;
111
112 while (Power)
113 {
114 Digit=(wHexVal & Power)>>ShiftVal;
115 if (Digit)
116 fNonZero=TRUE;
117
118 if (Digit ||
119 fNonZero ||
120 (Option & LEADING_ZEROES) ||
121 ((Power==0x0F) && (fNonZero==FALSE)))
122 *StrPtr++=hextab[Digit];
123
124 if (Power==0xF0000000) // 1 billion
125 Power=0xF000000;
126 else if (Power==0xF000000)
127 Power=0xF00000;
128 else if (Power==0xF00000)
129 Power=0xF0000;
130 else if (Power==0xF0000)
131 Power=0xF000;
132 else if (Power==0xF000)
133 Power=0xF00;
134 else if (Power==0xF00)
135 Power=0xF0;
136 else if (Power==0xF0)
137 Power=0xF;
138 else Power=0;
139
140 ShiftVal-=4;
141 } // end while
142
143 return (StrPtr);
144}
145
146#define DEBUG1
147
148#ifdef DEBUG1
149char BuildString[1024];
150#endif // DEBUG
151
152//------------------------- PrintfOut -
153void _cdecl DPD(int level, char *DbgStr, ...)
154{
155#ifdef DEBUG1
156 char *BuildPtr=BuildString;
157 char *pStr=(char *) DbgStr;
158 char *SubStr;
159 union {
160 void *VoidPtr;
161 USHORT *WordPtr;
162 ULONG *LongPtr;
163 ULONG *StringPtr;
164 } Parm;
165 USHORT wBuildOption;
166
167 Parm.VoidPtr=(void *) &DbgStr;
168 Parm.StringPtr++; // skip size of string pointer
169
170 while (*pStr)
171 {
172 // don't overflow target
173 if (BuildPtr >= (char *) &BuildString[1024-2])
174 break;
175
176 switch (*pStr)
177 {
178 case '%':
179 wBuildOption=0;
180 pStr++;
181 if (*pStr=='0')
182 {
183 wBuildOption|=LEADING_ZEROES;
184 pStr++;
185 }
186 if (*pStr=='u') // always unsigned
187 pStr++;
188 if (*pStr=='#')
189 pStr++;
190
191 switch(*pStr)
192 {
193 case 'x':
194 case 'X':
195 case 'p':
196 case 'P':
197 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
198 pStr++;
199 continue;
200
201 case 'd':
202 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
203 pStr++;
204 continue;
205
206 case 's':
207 SubStr=(char *)*Parm.StringPtr;
208 while (*BuildPtr++ = *SubStr++);
209 Parm.StringPtr++;
210 BuildPtr--; // remove the \0
211 pStr++;
212 continue;
213
214 case 'l':
215 pStr++;
216 switch (*pStr)
217 {
218 case 'x':
219 case 'X':
220 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
221 pStr++;
222 continue;
223
224 case 'd':
225 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
226 pStr++;
227 continue;
228 } // end switch
229 continue; // dunno what he wants
230
231 case 0:
232 continue;
233 } // end switch
234 break;
235
236 case '\\':
237 pStr++;
238 switch (*pStr)
239 {
240 case 'n':
241 *BuildPtr++=LF;
242 pStr++;
243 continue;
244
245 case 'r':
246 *BuildPtr++=CR;
247 pStr++;
248 continue;
249
250 case 0:
251 continue;
252 break;
253 } // end switch
254
255 break;
256 } // end switch
257
258 *BuildPtr++=*pStr++;
259 } // end while
260
261 *BuildPtr=0; // cauterize the string
262 StringOut((char *) BuildString); // print to comm port
263#endif //DEBUG
264}
265
266
267void _cdecl DPE(char *DbgStr, ...)
268{
269#ifdef DEBUG1
270 char *BuildPtr=BuildString;
271 char *pStr = (char *) DbgStr;
272 char *SubStr;
273 union {
274 void *VoidPtr;
275 USHORT *WordPtr;
276 ULONG *LongPtr;
277 ULONG *StringPtr;
278 } Parm;
279 USHORT wBuildOption;
280
281 Parm.VoidPtr=(void *) &DbgStr;
282 Parm.StringPtr++; // skip size of string pointer
283
284 while (*pStr)
285 {
286 // don't overflow target
287 if (BuildPtr >= (char *) &BuildString[1024-2])
288 break;
289
290 switch (*pStr)
291 {
292 case '%':
293 wBuildOption=0;
294 pStr++;
295 if (*pStr=='0')
296 {
297 wBuildOption|=LEADING_ZEROES;
298 pStr++;
299 }
300// if (*pStr=='u') // always unsigned
301// pStr++;
302
303 switch(*pStr)
304 {
305 case 'x':
306 case 'X':
307 case 'p':
308 case 'P':
309 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
310 pStr++;
311 continue;
312
313 case 'd':
314 case 'u':
315 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
316 pStr++;
317 continue;
318
319 case 's':
320 SubStr=(char *)*Parm.StringPtr;
321 while (*BuildPtr++ = *SubStr++);
322 Parm.StringPtr++;
323 BuildPtr--; // remove the \0
324 pStr++;
325 continue;
326
327 case 'c':
328 *BuildPtr++ = (char)*Parm.LongPtr;
329 Parm.LongPtr++;
330 pStr++;
331 continue;
332
333 case 'l':
334 pStr++;
335 switch (*pStr)
336 {
337 case 'x':
338 case 'X':
339 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
340 pStr++;
341 continue;
342
343 case 'd':
344 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
345 pStr++;
346 continue;
347 } // end switch
348 continue; // dunno what he wants
349
350 case 0:
351 continue;
352 } // end switch
353 break;
354
355 case '\\':
356 pStr++;
357 switch (*pStr)
358 {
359 case 'n':
360 *BuildPtr++=LF;
361 pStr++;
362 continue;
363
364 case 'r':
365 *BuildPtr++=CR;
366 pStr++;
367 continue;
368
369 case 0:
370 continue;
371 break;
372 } // end switch
373
374 break;
375 } // end switch
376
377 *BuildPtr++=*pStr++;
378 } // end while
379
380 *BuildPtr=0; // cauterize the string
381 StringOut((char *) BuildString); // print to comm port
382#endif //DEBUG
383}
384
385struct snd_info_buffer {
386 char *buffer; /* pointer to begin of buffer */
387 char *curr; /* current position in buffer */
388 unsigned long size; /* current size */
389 unsigned long len; /* total length of buffer */
390 int stop; /* stop flag */
391 int error; /* error code */
392};
393
394typedef struct snd_info_buffer snd_info_buffer_t;
395
396int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
397{
398 char *BuildPtr=buffer->curr;
399 char *pStr=(char *) fmt;
400 char *SubStr;
401 int res;
402 union {
403 void *VoidPtr;
404 USHORT *WordPtr;
405 ULONG *LongPtr;
406 ULONG *StringPtr;
407 } Parm;
408 USHORT wBuildOption;
409
410 Parm.VoidPtr=(void *) &fmt;
411 Parm.StringPtr++; // skip size of string pointer
412
413 if (buffer->stop || buffer->error)
414 return 0;
415
416 while (*pStr)
417 {
418 // don't overflow target
419 if (BuildPtr >= (char *) &buffer->curr[buffer->len - 4])
420 break;
421
422 switch (*pStr)
423 {
424 case '%':
425 wBuildOption=0;
426 pStr++;
427 if (*pStr=='0')
428 {
429 wBuildOption|=LEADING_ZEROES;
430 pStr++;
431 }
432// if (*pStr=='u') // always unsigned
433// pStr++;
434 if (*pStr=='#')
435 pStr++;
436
437 switch(*pStr)
438 {
439 case 'x':
440 case 'X':
441 case 'p':
442 case 'P':
443 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
444 pStr++;
445 continue;
446
447 case 'd':
448 case 'u':
449 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
450 pStr++;
451 continue;
452
453 case 's':
454 SubStr=(char *)*Parm.StringPtr;
455 while (*BuildPtr++ = *SubStr++);
456 Parm.StringPtr++;
457 BuildPtr--; // remove the \0
458 pStr++;
459 continue;
460
461 case 'c':
462 *BuildPtr++ = (char)*Parm.LongPtr;
463 Parm.LongPtr++;
464 pStr++;
465 continue;
466
467 case 'l':
468 pStr++;
469 switch (*pStr)
470 {
471 case 'x':
472 case 'X':
473 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
474 pStr++;
475 continue;
476
477 case 'd':
478 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
479 pStr++;
480 continue;
481 } // end switch
482 continue; // dunno what he wants
483
484 case 0:
485 continue;
486 } // end switch
487 break;
488
489 case '\\':
490 pStr++;
491 switch (*pStr)
492 {
493 case 'n':
494 *BuildPtr++=LF;
495 pStr++;
496 continue;
497
498 case 'r':
499 *BuildPtr++=CR;
500 pStr++;
501 continue;
502
503 case 0:
504 continue;
505 break;
506 } // end switch
507
508 break;
509 } // end switch
510
511 *BuildPtr++=*pStr++;
512 } // end while
513
514 *BuildPtr=0; // cauterize the string
515
516 res = strlen(buffer->curr);
517 if (buffer->size + res >= buffer->len) {
518 buffer->stop = 1;
519 return 0;
520 }
521 buffer->curr += res;
522 buffer->size += res;
523 return res;
524}
525
526#ifdef DEBUG1
527//------------------------- StringOut --------------------------//
528
529#define VMDHA_FIXED 0x0002
530
531extern APIRET VMAlloc(ULONG size, ULONG flags, char NEAR* *pAddr);
532
533/**
534 * Finds the length of a string up to cchMax.
535 * @returns Length.
536 * @param psz Pointer to string.
537 * @param cchMax Max length.
538 */
539static unsigned _strnlen(const char *psz, unsigned cchMax)
540{
541 const char *pszC = psz;
542
543 while (cchMax-- > 0 && *psz != '\0')
544 psz++;
545
546 return psz - pszC;
547}
548
549void StringOut(char *DbgStr)
550{
551 int len;
552#ifdef DEBUG
553 int i;
554#endif /* DEBUG */
555
556 len= _strnlen( DbgStr, 1024 );
557/*
558 while (*DbgStr)
559 CharOut(*DbgStr++);
560 */
561#ifdef DEBUG
562 for( i= 0; i < len; i++ )
563 CharOut( DbgStr[i] );
564
565 if (fLineTerminate)
566 {
567 CharOut(CR); // append carriage return,
568 CharOut(LF); // linefeed
569 }
570#endif
571 if( szprintBuf == 0 )
572 {
573 VMAlloc( max_buf_size, VMDHA_FIXED, &szprintBuf );
574 if( szprintBuf )
575 memset( szprintBuf, 0, max_buf_size );
576 wrOffset= 0;
577 }
578 if( szprintBuf )
579 {
580 if( (len + wrOffset) > max_buf_size )
581 {
582 int cntr;
583 cntr= max_buf_size - wrOffset;
584 memcpy( szprintBuf + wrOffset, DbgStr, cntr );
585 DbgStr+= cntr;
586 len= len - cntr;
587 wrOffset= 0;
588 }
589 if( len )
590 {
591 memcpy( szprintBuf + wrOffset, DbgStr, len );
592 wrOffset= wrOffset + len;
593 if( wrOffset >= max_buf_size )
594 wrOffset= 0;
595 }
596 if (fLineTerminate)
597 {
598// if( (wrOffset+1) >= max_buf_size )
599// wrOffset= 0;
600 szprintBuf[wrOffset]= CR;
601 if( ++wrOffset >= max_buf_size )
602 wrOffset= 0;
603 szprintBuf[wrOffset]= LF;
604 if( ++wrOffset >= max_buf_size )
605 wrOffset= 0;
606 }
607 }
608}
609#endif
610
611#ifdef DEBUG
612short int MAGIC_COMM_PORT = 0x3f8; // pulled from word ptr 40:0
613
614
615#define UART_DATA 0x00 // UART Data port
616#define UART_INT_ENAB 0x01 // UART Interrupt enable
617#define UART_INT_ID 0x02 // interrupt ID
618#define UART_LINE_CTRL 0x03 // line control registers
619#define UART_MODEM_CTRL 0x04 // modem control register
620#define UART_LINE_STAT 0x05 // line status register
621#define UART_MODEM_STAT 0x06 // modem status regiser
622#define UART_DIVISOR_LO 0x00 // divisor latch least sig
623#define UART_DIVISOR_HI 0x01h // divisor latch most sig
624
625#define DELAY nop
626#else
627short int MAGIC_COMM_PORT = 0x0; // pulled from word ptr 40:0
628#endif
629
630#ifdef DEBUG //--------------------------- CharOut -
631void CharOut(char c)
632{
633 if( MAGIC_COMM_PORT )
634 {
635
636 _asm {
637
638 mov dx, MAGIC_COMM_PORT // address of PS/2's first COM port
639 add dx, UART_LINE_STAT
640
641ReadyCheck:
642 in al, dx // wait for comm port ready signal
643
644 DELAY
645 DELAY
646 DELAY
647
648 test al, 020h
649 jz ReadyCheck
650
651 // Send the character
652
653 add dx, UART_DATA - UART_LINE_STAT
654 mov al,c
655 out dx, al
656
657 DELAY
658 DELAY
659 DELAY
660 }
661 }
662}
663#endif
Note: See TracBrowser for help on using the repository browser.