source: GPL/branches/uniaud32-2.0/lib32/debug.c@ 420

Last change on this file since 420 was 420, checked in by Paul Smedley, 16 years ago

Disable output to comport if com = 0 (default) fix build probs

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