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

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

Updates from Pasha to improve IRQ handling and resolve long delays at startup in APIC mode when using ACPI

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
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//PS+++ Changes for right debug output
549#ifdef DEBUG
550short int MAGIC_COMM_PORT = 0; // pulled from word ptr 40:0
551
552
553#define UART_DATA 0x00 // UART Data port
554#define UART_INT_ENAB 0x01 // UART Interrupt enable
555#define UART_INT_ID 0x02 // interrupt ID
556#define UART_LINE_CTRL 0x03 // line control registers
557#define UART_MODEM_CTRL 0x04 // modem control register
558#define UART_LINE_STAT 0x05 // line status register
559#define UART_MODEM_STAT 0x06 // modem status regiser
560#define UART_DIVISOR_LO 0x00 // divisor latch least sig
561#define UART_DIVISOR_HI 0x01h // divisor latch most sig
562
563#define DELAY nop
564#else
565short int MAGIC_COMM_PORT = 0x0; // pulled from word ptr 40:0
566#endif
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) //PS+++ If have comport - out to it
582 {
583 for( i= 0; i < len; i++ )
584 CharOut( DbgStr[i] );
585
586 if (fLineTerminate)
587 {
588 CharOut(CR); // append carriage return,
589 CharOut(LF); // linefeed
590 }
591 }
592#endif
593 if( szprintBuf == 0 )
594 {
595 VMAlloc( max_buf_size, VMDHA_FIXED, &szprintBuf );
596 if( szprintBuf )
597 memset( szprintBuf, 0, max_buf_size );
598 wrOffset= 0;
599 }
600 if( szprintBuf )
601 {
602 if( (len + wrOffset) > max_buf_size )
603 {
604 int cntr;
605 cntr= max_buf_size - wrOffset;
606 memcpy( szprintBuf + wrOffset, DbgStr, cntr );
607 DbgStr+= cntr;
608 len= len - cntr;
609 wrOffset= 0;
610 }
611 if( len )
612 {
613 memcpy( szprintBuf + wrOffset, DbgStr, len );
614 wrOffset= wrOffset + len;
615 if( wrOffset >= max_buf_size )
616 wrOffset= 0;
617 }
618 if (fLineTerminate)
619 {
620// if( (wrOffset+1) >= max_buf_size )
621// wrOffset= 0;
622 szprintBuf[wrOffset]= CR;
623 if( ++wrOffset >= max_buf_size )
624 wrOffset= 0;
625 szprintBuf[wrOffset]= LF;
626 if( ++wrOffset >= max_buf_size )
627 wrOffset= 0;
628 }
629 }
630}
631#endif
632
633
634#ifdef DEBUG //--------------------------- CharOut -
635void CharOut(char c)
636{
637 if( MAGIC_COMM_PORT )
638 {
639
640 _asm {
641
642 mov dx, MAGIC_COMM_PORT // address of PS/2's first COM port
643 add dx, UART_LINE_STAT
644
645ReadyCheck:
646 in al, dx // wait for comm port ready signal
647
648 DELAY
649 DELAY
650 DELAY
651
652 test al, 020h
653 jz ReadyCheck
654
655 // Send the character
656
657 add dx, UART_DATA - UART_LINE_STAT
658 mov al,c
659 out dx, al
660
661 DELAY
662 DELAY
663 DELAY
664 }
665 }
666}
667#endif
Note: See TracBrowser for help on using the repository browser.