source: GPL/branches/uniaud32-2.1.x/lib32/debug.c@ 503

Last change on this file since 503 was 484, checked in by David Azarewicz, 15 years ago

Fix for recording hang

File size: 17.3 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#ifdef DEBUG
147#define COMM_DEBUG
148//------------------------- StringOut --------------------------//
149
150#define VMDHA_FIXED 0x0002
151
152extern APIRET VMAlloc(ULONG size, ULONG flags, char NEAR* *pAddr);
153
154/**
155 * Finds the length of a string up to cchMax.
156 * @returns Length.
157 * @param psz Pointer to string.
158 * @param cchMax Max length.
159 */
160static unsigned _strnlen(const char *psz, unsigned cchMax)
161{
162 const char *pszC = psz;
163
164 while (cchMax-- > 0 && *psz != '\0')
165 psz++;
166
167 return psz - pszC;
168}
169
170#ifdef COMM_DEBUG
171short int MAGIC_COMM_PORT = 0; // pulled from word ptr 40:0
172
173
174#define UART_DATA 0x00 // UART Data port
175#define UART_INT_ENAB 0x01 // UART Interrupt enable
176#define UART_INT_ID 0x02 // interrupt ID
177#define UART_LINE_CTRL 0x03 // line control registers
178#define UART_MODEM_CTRL 0x04 // modem control register
179#define UART_LINE_STAT 0x05 // line status register
180#define UART_MODEM_STAT 0x06 // modem status regiser
181#define UART_DIVISOR_LO 0x00 // divisor latch least sig
182#define UART_DIVISOR_HI 0x01h // divisor latch most sig
183
184#define DELAY nop
185
186void CharOut(char c)
187{
188 if( MAGIC_COMM_PORT )
189 {
190
191 _asm {
192
193 mov dx, MAGIC_COMM_PORT // address of PS/2's first COM port
194 add dx, UART_LINE_STAT
195
196ReadyCheck:
197 in al, dx // wait for comm port ready signal
198
199 DELAY
200 DELAY
201 DELAY
202
203 test al, 020h
204 jz ReadyCheck
205
206 // Send the character
207
208 add dx, UART_DATA - UART_LINE_STAT
209 mov al,c
210 out dx, al
211
212 DELAY
213 DELAY
214 DELAY
215 }
216 }
217}
218#endif
219
220void StringOut(char *DbgStr)
221{
222 int len;
223#ifdef COMM_DEBUG
224 int i;
225#endif /* DEBUG */
226
227 len= _strnlen( DbgStr, 1024 );
228/*
229 while (*DbgStr)
230 CharOut(*DbgStr++);
231 */
232#ifdef COMM_DEBUG
233 if (MAGIC_COMM_PORT) //PS+++ If have comport - out to it
234 {
235 for( i= 0; i < len; i++ )
236 CharOut( DbgStr[i] );
237
238 if (fLineTerminate)
239 {
240 CharOut(CR); // append carriage return,
241 CharOut(LF); // linefeed
242 }
243 }
244#endif
245 if( szprintBuf == 0 )
246 {
247 VMAlloc( max_buf_size, VMDHA_FIXED, &szprintBuf );
248 if( szprintBuf )
249 memset( szprintBuf, 0, max_buf_size );
250 wrOffset= 0;
251 }
252 if( szprintBuf )
253 {
254 if( (len + wrOffset) > max_buf_size )
255 {
256 int cntr;
257 cntr= max_buf_size - wrOffset;
258 memcpy( szprintBuf + wrOffset, DbgStr, cntr );
259 DbgStr+= cntr;
260 len= len - cntr;
261 wrOffset= 0;
262 }
263 if( len )
264 {
265 memcpy( szprintBuf + wrOffset, DbgStr, len );
266 wrOffset= wrOffset + len;
267 if( wrOffset >= max_buf_size )
268 wrOffset= 0;
269 }
270 if (fLineTerminate)
271 {
272// if( (wrOffset+1) >= max_buf_size )
273// wrOffset= 0;
274 szprintBuf[wrOffset]= CR;
275 if( ++wrOffset >= max_buf_size )
276 wrOffset= 0;
277 szprintBuf[wrOffset]= LF;
278 if( ++wrOffset >= max_buf_size )
279 wrOffset= 0;
280 }
281 }
282}
283#endif
284
285#ifdef DEBUG
286char BuildString[1024];
287#endif // DEBUG
288
289//------------------------- PrintfOut -
290void _cdecl DPD(int level, char *DbgStr, ...)
291{
292#ifdef DEBUG
293 char *BuildPtr=BuildString;
294 char *pStr=(char *) DbgStr;
295 char *SubStr;
296 union {
297 void *VoidPtr;
298 USHORT *WordPtr;
299 ULONG *LongPtr;
300 ULONG *StringPtr;
301 } Parm;
302 USHORT wBuildOption;
303
304 Parm.VoidPtr=(void *) &DbgStr;
305 Parm.StringPtr++; // skip size of string pointer
306
307 while (*pStr)
308 {
309 // don't overflow target
310 if (BuildPtr >= (char *) &BuildString[1024-2])
311 break;
312
313 switch (*pStr)
314 {
315 case '%':
316 wBuildOption=0;
317 pStr++;
318 if (*pStr=='0')
319 {
320 wBuildOption|=LEADING_ZEROES;
321 pStr++;
322 }
323 if (*pStr=='u') // always unsigned
324 pStr++;
325 if (*pStr=='#')
326 pStr++;
327
328 switch(*pStr)
329 {
330 case 'x':
331 case 'X':
332 case 'p':
333 case 'P':
334 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
335 pStr++;
336 continue;
337
338 case 'd':
339 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
340 pStr++;
341 continue;
342
343 case 's':
344 SubStr=(char *)*Parm.StringPtr;
345 while (*BuildPtr++ = *SubStr++);
346 Parm.StringPtr++;
347 BuildPtr--; // remove the \0
348 pStr++;
349 continue;
350
351 case 'l':
352 pStr++;
353 switch (*pStr)
354 {
355 case 'x':
356 case 'X':
357 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
358 pStr++;
359 continue;
360
361 case 'd':
362 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
363 pStr++;
364 continue;
365 } // end switch
366 continue; // dunno what he wants
367
368 case 0:
369 continue;
370 } // end switch
371 break;
372
373 case '\\':
374 pStr++;
375 switch (*pStr)
376 {
377 case 'n':
378 *BuildPtr++=LF;
379 pStr++;
380 continue;
381
382 case 'r':
383 *BuildPtr++=CR;
384 pStr++;
385 continue;
386
387 case 0:
388 continue;
389 break;
390 } // end switch
391
392 break;
393 } // end switch
394
395 *BuildPtr++=*pStr++;
396 } // end while
397
398 *BuildPtr=0; // cauterize the string
399 StringOut((char *) BuildString);
400#endif //DEBUG
401}
402
403
404void _cdecl DPE(char *DbgStr, ...)
405{
406#ifdef DEBUG
407 char *BuildPtr=BuildString;
408 char *pStr = (char *) DbgStr;
409 char *SubStr;
410 union {
411 void *VoidPtr;
412 USHORT *WordPtr;
413 ULONG *LongPtr;
414 ULONG *StringPtr;
415 } Parm;
416 USHORT wBuildOption;
417
418 Parm.VoidPtr=(void *) &DbgStr;
419 Parm.StringPtr++; // skip size of string pointer
420
421 while (*pStr)
422 {
423 // don't overflow target
424 if (BuildPtr >= (char *) &BuildString[1024-2])
425 break;
426
427 switch (*pStr)
428 {
429 case '%':
430 wBuildOption=0;
431 pStr++;
432 if (*pStr=='0')
433 {
434 wBuildOption|=LEADING_ZEROES;
435 pStr++;
436 }
437// if (*pStr=='u') // always unsigned
438// pStr++;
439
440 switch(*pStr)
441 {
442 case 'x':
443 case 'X':
444 case 'p':
445 case 'P':
446 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
447 pStr++;
448 continue;
449
450 case 'd':
451 case 'u':
452 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
453 pStr++;
454 continue;
455
456 case 's':
457 SubStr=(char *)*Parm.StringPtr;
458 while (*BuildPtr++ = *SubStr++);
459 Parm.StringPtr++;
460 BuildPtr--; // remove the \0
461 pStr++;
462 continue;
463
464 case 'c':
465 *BuildPtr++ = (char)*Parm.LongPtr;
466 Parm.LongPtr++;
467 pStr++;
468 continue;
469
470 case 'l':
471 pStr++;
472 switch (*pStr)
473 {
474 case 'x':
475 case 'X':
476 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
477 pStr++;
478 continue;
479
480 case 'd':
481 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
482 pStr++;
483 continue;
484 } // end switch
485 continue; // dunno what he wants
486
487 case 0:
488 continue;
489 } // end switch
490 break;
491
492 case '\\':
493 pStr++;
494 switch (*pStr)
495 {
496 case 'n':
497 *BuildPtr++=LF;
498 pStr++;
499 continue;
500
501 case 'r':
502 *BuildPtr++=CR;
503 pStr++;
504 continue;
505
506 case 0:
507 continue;
508 break;
509 } // end switch
510
511 break;
512 } // end switch
513
514 *BuildPtr++=*pStr++;
515 } // end while
516
517 *BuildPtr=0; // cauterize the string
518 StringOut((char *) BuildString);
519#endif //DEBUG
520}
521
522struct snd_info_buffer {
523 char *buffer; /* pointer to begin of buffer */
524 char *curr; /* current position in buffer */
525 unsigned long size; /* current size */
526 unsigned long len; /* total length of buffer */
527 int stop; /* stop flag */
528 int error; /* error code */
529};
530
531typedef struct snd_info_buffer snd_info_buffer_t;
532
533int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
534{
535 char *BuildPtr=buffer->curr;
536 char *pStr=(char *) fmt;
537 char *SubStr;
538 int res;
539 union {
540 void *VoidPtr;
541 USHORT *WordPtr;
542 ULONG *LongPtr;
543 ULONG *StringPtr;
544 } Parm;
545 USHORT wBuildOption;
546
547 Parm.VoidPtr=(void *) &fmt;
548 Parm.StringPtr++; // skip size of string pointer
549
550 if (buffer->stop || buffer->error)
551 return 0;
552
553 while (*pStr)
554 {
555 // don't overflow target
556 if (BuildPtr >= (char *) &buffer->curr[buffer->len - 4])
557 break;
558
559 switch (*pStr)
560 {
561 case '%':
562 wBuildOption=0;
563 pStr++;
564 if (*pStr=='0')
565 {
566 wBuildOption|=LEADING_ZEROES;
567 pStr++;
568 }
569// if (*pStr=='u') // always unsigned
570// pStr++;
571 if (*pStr=='#')
572 pStr++;
573
574 switch(*pStr)
575 {
576 case 'x':
577 case 'X':
578 case 'p':
579 case 'P':
580 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
581 pStr++;
582 continue;
583
584 case 'd':
585 case 'u':
586 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
587 pStr++;
588 continue;
589
590 case 's':
591 SubStr=(char *)*Parm.StringPtr;
592 while (*BuildPtr++ = *SubStr++);
593 Parm.StringPtr++;
594 BuildPtr--; // remove the \0
595 pStr++;
596 continue;
597
598 case 'c':
599 *BuildPtr++ = (char)*Parm.LongPtr;
600 Parm.LongPtr++;
601 pStr++;
602 continue;
603
604 case 'l':
605 pStr++;
606 switch (*pStr)
607 {
608 case 'x':
609 case 'X':
610 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
611 pStr++;
612 continue;
613
614 case 'd':
615 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
616 pStr++;
617 continue;
618 } // end switch
619 continue; // dunno what he wants
620
621 case 0:
622 continue;
623 } // end switch
624 break;
625
626 case '\\':
627 pStr++;
628 switch (*pStr)
629 {
630 case 'n':
631 *BuildPtr++=LF;
632 pStr++;
633 continue;
634
635 case 'r':
636 *BuildPtr++=CR;
637 pStr++;
638 continue;
639
640 case 0:
641 continue;
642 break;
643 } // end switch
644
645 break;
646 } // end switch
647
648 *BuildPtr++=*pStr++;
649 } // end while
650
651 *BuildPtr=0; // cauterize the string
652
653 res = strlen(buffer->curr);
654 if (buffer->size + res >= buffer->len) {
655 buffer->stop = 1;
656 return 0;
657 }
658 buffer->curr += res;
659 buffer->size += res;
660 return res;
661}
662
Note: See TracBrowser for help on using the repository browser.