source: GPL/branches/uniaud32-next/lib32/debug.c@ 660

Last change on this file since 660 was 549, checked in by David Azarewicz, 14 years ago

Fixes for changin interrupts in APIC mode

File size: 10.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#include <dbgos2.h>
30
31#define COMM_DEBUG
32
33#define CR 0x0d
34#define LF 0x0a
35
36#define LEADING_ZEROES 0x8000
37#define SIGNIFICANT_FIELD 0x0007
38
39int DebugLevel;
40
41char hextab[]="0123456789ABCDEF";
42
43DBGINT DbgInt;
44 //-------------------- DecLongToASCII -
45char * DecLongToASCII(char *StrPtr, ULONG lDecVal,USHORT Option)
46{
47 BOOL fNonZero=FALSE;
48 ULONG Digit;
49 ULONG Power=1000000000; // 1 billion
50 LONG lVal = (LONG)lDecVal;
51
52 if(lVal < 0) {
53 *StrPtr = '-';
54 StrPtr++;
55 lDecVal = -lDecVal;
56 }
57
58 while (Power)
59 {
60 Digit=0; // Digit=lDecVal/Power
61 while (lDecVal >=Power) // replaced with while loop
62 {
63 Digit++;
64 lDecVal-=Power;
65 }
66
67 if (Digit)
68 fNonZero=TRUE;
69
70 if (Digit ||
71 fNonZero ||
72 (Option & LEADING_ZEROES) ||
73 ((Power==1) && (fNonZero==FALSE)))
74 {
75 *StrPtr=(char)('0'+Digit);
76 StrPtr++;
77 }
78
79 if (Power==1000000000) // 1 billion
80 Power=100000000;
81 else if (Power==100000000)
82 Power=10000000;
83 else if (Power==10000000)
84 Power=1000000;
85 else if (Power==1000000)
86 Power=100000;
87 else if (Power==100000)
88 Power=10000;
89 else if (Power==10000)
90 Power=1000;
91 else if (Power==1000)
92 Power=100;
93 else if (Power==100)
94 Power=10;
95 else if (Power==10)
96 Power=1;
97 else
98 Power=0;
99 }
100 return (StrPtr);
101}
102 //-------------------- HexWordToASCII -
103 //-------------------- HexLongToASCII -
104char * HexLongToASCII(char *StrPtr, ULONG wHexVal, USHORT Option)
105{
106 BOOL fNonZero=FALSE;
107 ULONG Digit;
108 ULONG Power=0xF0000000;
109 ULONG ShiftVal=28;
110
111 while (Power)
112 {
113 Digit=(wHexVal & Power)>>ShiftVal;
114 if (Digit)
115 fNonZero=TRUE;
116
117 if (Digit ||
118 fNonZero ||
119 (Option & LEADING_ZEROES) ||
120 ((Power==0x0F) && (fNonZero==FALSE)))
121 *StrPtr++=hextab[Digit];
122
123 if (Power==0xF0000000) // 1 billion
124 Power=0xF000000;
125 else if (Power==0xF000000)
126 Power=0xF00000;
127 else if (Power==0xF00000)
128 Power=0xF0000;
129 else if (Power==0xF0000)
130 Power=0xF000;
131 else if (Power==0xF000)
132 Power=0xF00;
133 else if (Power==0xF00)
134 Power=0xF0;
135 else if (Power==0xF0)
136 Power=0xF;
137 else Power=0;
138
139 ShiftVal-=4;
140 } // end while
141
142 return (StrPtr);
143}
144
145/**
146 * Finds the length of a string up to cchMax.
147 * @returns Length.
148 * @param psz Pointer to string.
149 * @param cchMax Max length.
150 */
151static unsigned _strnlen(const char *psz, unsigned cchMax)
152{
153 const char *pszC = psz;
154
155 while (cchMax-- > 0 && *psz != '\0')
156 psz++;
157
158 return psz - pszC;
159}
160
161#ifdef COMM_DEBUG
162short int MAGIC_COMM_PORT = 0; // pulled from word ptr 40:0
163
164
165#define UART_DATA 0x00 // UART Data port
166#define UART_INT_ENAB 0x01 // UART Interrupt enable
167#define UART_INT_ID 0x02 // interrupt ID
168#define UART_LINE_CTRL 0x03 // line control registers
169#define UART_MODEM_CTRL 0x04 // modem control register
170#define UART_LINE_STAT 0x05 // line status register
171#define UART_MODEM_STAT 0x06 // modem status regiser
172#define UART_DIVISOR_LO 0x00 // divisor latch least sig
173#define UART_DIVISOR_HI 0x01h // divisor latch most sig
174
175#define DELAY nop
176
177void CharOut(char c)
178{
179 if( MAGIC_COMM_PORT )
180 {
181
182 _asm {
183
184 mov dx, MAGIC_COMM_PORT // address of PS/2's first COM port
185 add dx, UART_LINE_STAT
186
187ReadyCheck:
188 in al, dx // wait for comm port ready signal
189
190 DELAY
191 DELAY
192 DELAY
193
194 test al, 020h
195 jz ReadyCheck
196
197 // Send the character
198
199 add dx, UART_DATA - UART_LINE_STAT
200 mov al,c
201 out dx, al
202
203 DELAY
204 DELAY
205 DELAY
206 }
207 }
208}
209#endif
210
211//------------------------- StringOut --------------------------//
212void StringOut(char *DbgStr)
213{
214 int len;
215
216 len= _strnlen( DbgStr, 1024 );
217
218#ifdef COMM_DEBUG
219 if (MAGIC_COMM_PORT) {
220 int i;
221
222 for( i= 0; i < len; i++ ) CharOut( DbgStr[i] );
223
224 CharOut(CR); // append carriage return,
225 CharOut(LF); // linefeed
226 }
227#endif
228
229 if (szprintBuf == 0) return;
230
231 if( (len + wrOffset) > DBG_MAX_BUF_SIZE ) {
232 int cntr;
233 cntr = DBG_MAX_BUF_SIZE - wrOffset;
234 memcpy( szprintBuf + wrOffset, DbgStr, cntr );
235 DbgStr += cntr;
236 len = len - cntr;
237 wrOffset= 0;
238 }
239
240 if ( len ) {
241 memcpy( szprintBuf + wrOffset, DbgStr, len );
242 wrOffset= wrOffset + len;
243 if( wrOffset >= DBG_MAX_BUF_SIZE ) wrOffset= 0;
244 }
245
246 if ( (wrOffset+1) >= DBG_MAX_BUF_SIZE ) wrOffset= 0;
247 szprintBuf[wrOffset]= CR;
248 if ( ++wrOffset >= DBG_MAX_BUF_SIZE ) wrOffset= 0;
249 szprintBuf[wrOffset]= LF;
250 if ( ++wrOffset >= DBG_MAX_BUF_SIZE ) wrOffset= 0;
251}
252
253struct snd_info_buffer {
254 char *buffer; /* pointer to begin of buffer */
255 char *curr; /* current position in buffer */
256 unsigned long size; /* current size */
257 unsigned long len; /* total length of buffer */
258 int stop; /* stop flag */
259 int error; /* error code */
260};
261
262typedef struct snd_info_buffer snd_info_buffer_t;
263
264int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
265{
266 char *BuildPtr=buffer->curr;
267 char *pStr=(char *) fmt;
268 char *SubStr;
269 int res;
270 union {
271 void *VoidPtr;
272 USHORT *WordPtr;
273 ULONG *LongPtr;
274 ULONG *StringPtr;
275 } Parm;
276 USHORT wBuildOption;
277
278 Parm.VoidPtr=(void *) &fmt;
279 Parm.StringPtr++; // skip size of string pointer
280
281 if (buffer->stop || buffer->error)
282 return 0;
283
284 while (*pStr)
285 {
286 // don't overflow target
287 if (BuildPtr >= (char *) &buffer->curr[buffer->len - 4])
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 if (*pStr=='#')
303 pStr++;
304
305 switch(*pStr)
306 {
307 case 'x':
308 case 'X':
309 case 'p':
310 case 'P':
311 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
312 pStr++;
313 continue;
314
315 case 'd':
316 case 'u':
317 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
318 pStr++;
319 continue;
320
321 case 's':
322 SubStr=(char *)*Parm.StringPtr;
323 while (*BuildPtr++ = *SubStr++);
324 Parm.StringPtr++;
325 BuildPtr--; // remove the \0
326 pStr++;
327 continue;
328
329 case 'c':
330 *BuildPtr++ = (char)*Parm.LongPtr;
331 Parm.LongPtr++;
332 pStr++;
333 continue;
334
335 case 'l':
336 pStr++;
337 switch (*pStr)
338 {
339 case 'x':
340 case 'X':
341 BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
342 pStr++;
343 continue;
344
345 case 'd':
346 BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption);
347 pStr++;
348 continue;
349 } // end switch
350 continue; // dunno what he wants
351
352 case 0:
353 continue;
354 } // end switch
355 break;
356
357 case '\\':
358 pStr++;
359 switch (*pStr)
360 {
361 case 'n':
362 *BuildPtr++=LF;
363 pStr++;
364 continue;
365
366 case 'r':
367 *BuildPtr++=CR;
368 pStr++;
369 continue;
370
371 case 0:
372 continue;
373 break;
374 } // end switch
375
376 break;
377 } // end switch
378
379 *BuildPtr++=*pStr++;
380 } // end while
381
382 *BuildPtr=0; // cauterize the string
383
384 res = strlen(buffer->curr);
385 if (buffer->size + res >= buffer->len) {
386 buffer->stop = 1;
387 return 0;
388 }
389 buffer->curr += res;
390 buffer->size += res;
391 return res;
392}
393
394void DbgPrintIrq(void) {
395 rprintf(("Init=%ld/%ld Between=%ld/%ld Complete=%ld/%ld",
396 DbgInt.ulIntServiced[0], DbgInt.ulIntUnserviced[0],
397 DbgInt.ulIntServiced[1], DbgInt.ulIntUnserviced[1],
398 DbgInt.ulIntServiced[2], DbgInt.ulIntUnserviced[2]));
399}
400
Note: See TracBrowser for help on using the repository browser.