|
|
1.1 root 1: /*
2:
3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
4:
5: */
6:
7:
8:
9: /* MiNT debugging output routines */
10:
11: /* also, ksprintf is put here, for lack of any better place to put it */
12:
13:
14:
15: #include "mint.h"
16:
17: #include <stdarg.h>
18:
19:
20:
21: static void VDEBUGOUT P_((const char *, va_list));
22:
23:
24:
25: /*
26:
27: * ksprintf implements a very crude sprintf() function that provides only
28:
29: * what MiNT needs...
30:
31: *
32:
33: * NOTE: this sprintf probably doesn't conform to any standard at
34:
35: * all. It's only use in life is that it won't overflow fixed
36:
37: * size buffers (i.e. it won't try to write more than SPRINTF_MAX
38:
39: * characters into a string)
40:
41: */
42:
43:
44:
45: static int
46:
47: PUTC(char *p, int c, int *cnt, int width) {
48:
49: int put = 1;
50:
51:
52:
53: if (*cnt <= 0) return 0;
54:
55: *p++ = c;
56:
57: *cnt -= 1;
58:
59: while (*cnt > 0 && --width > 0) {
60:
61: *p++ = ' ';
62:
63: *cnt -= 1;
64:
65: put++;
66:
67: }
68:
69: return put;
70:
71: }
72:
73:
74:
75: static int
76:
77: PUTS(char *p, const char *s, int *cnt, int width) {
78:
79: int put = 0;
80:
81:
82:
83: if (s == 0) s = "(null)";
84:
85:
86:
87: while (*cnt > 0 && *s) {
88:
89: *p++ = *s++;
90:
91: put++;
92:
93: *cnt -= 1;
94:
95: width--;
96:
97: }
98:
99: while (width-- > 0 && *cnt > 0) {
100:
101: *p++ = ' ';
102:
103: put++;
104:
105: *cnt -= 1;
106:
107: }
108:
109: return put;
110:
111: }
112:
113:
114:
115: static int
116:
117: PUTL(char *p, unsigned long u, int base, int *cnt, int width, int fill_char)
118:
119: {
120:
121: int put = 0;
122:
123: static char obuf[32];
124:
125: char *t;
126:
127:
128:
129: t = obuf;
130:
131:
132:
133: do {
134:
135: *t++ = "0123456789abcdef"[u % base];
136:
137: u /= base;
138:
139: width--;
140:
141: } while (u > 0);
142:
143:
144:
145: while (width-- > 0 && *cnt > 0) {
146:
147: *p++ = fill_char;
148:
149: put++;
150:
151: *cnt -= 1;
152:
153: }
154:
155: while (*cnt > 0 && t != obuf) {
156:
157: *p++ = *--t;
158:
159: put++;
160:
161: *cnt -= 1;
162:
163: }
164:
165: return put;
166:
167: }
168:
169:
170:
171: int
172:
173: vksprintf(char *buf, const char *fmt, va_list args)
174:
175: {
176:
177: char *p = buf, c, fill_char;
178:
179: char *s_arg;
180:
181: int i_arg;
182:
183: long l_arg;
184:
185: int cnt;
186:
187: int width, long_flag;
188:
189:
190:
191: cnt = SPRINTF_MAX - 1;
192:
193: while( (c = *fmt++) != 0 ) {
194:
195: if (c != '%') {
196:
197: p += PUTC(p, c, &cnt, 1);
198:
199: continue;
200:
201: }
202:
203: c = *fmt++;
204:
205: width = 0;
206:
207: long_flag = 0;
208:
209: fill_char = ' ';
210:
211: if (c == '0') fill_char = '0';
212:
213: while (c && isdigit(c)) {
214:
215: width = 10*width + (c-'0');
216:
217: c = *fmt++;
218:
219: }
220:
221: if (c == 'l' || c == 'L') {
222:
223: long_flag = 1;
224:
225: c = *fmt++;
226:
227: }
228:
229: if (!c) break;
230:
231:
232:
233: switch (c) {
234:
235: case '%':
236:
237: p += PUTC(p, c, &cnt, width);
238:
239: break;
240:
241: case 'c':
242:
243: i_arg = va_arg(args, int);
244:
245: p += PUTC(p, i_arg, &cnt, width);
246:
247: break;
248:
249: case 's':
250:
251: s_arg = va_arg(args, char *);
252:
253: p += PUTS(p, s_arg, &cnt, width);
254:
255: break;
256:
257: case 'd':
258:
259: if (long_flag) {
260:
261: l_arg = va_arg(args, long);
262:
263: } else {
264:
265: l_arg = va_arg(args, int);
266:
267: }
268:
269: if (l_arg < 0) {
270:
271: p += PUTC(p, '-', &cnt, 1);
272:
273: width--;
274:
275: l_arg = -l_arg;
276:
277: }
278:
279: p += PUTL(p, l_arg, 10, &cnt, width, fill_char);
280:
281: break;
282:
283: case 'o':
284:
285: if (long_flag) {
286:
287: l_arg = va_arg(args, long);
288:
289: } else {
290:
291: l_arg = va_arg(args, unsigned int);
292:
293: }
294:
295: p += PUTL(p, l_arg, 8, &cnt, width, fill_char);
296:
297: break;
298:
299: case 'x':
300:
301: if (long_flag) {
302:
303: l_arg = va_arg(args, long);
304:
305: } else {
306:
307: l_arg = va_arg(args, unsigned int);
308:
309: }
310:
311: p += PUTL(p, l_arg, 16, &cnt, width, fill_char);
312:
313: break;
314:
315: case 'u':
316:
317: if (long_flag) {
318:
319: l_arg = va_arg(args, long);
320:
321: } else {
322:
323: l_arg = va_arg(args, unsigned int);
324:
325: }
326:
327: p += PUTL(p, l_arg, 10, &cnt, width, fill_char);
328:
329: break;
330:
331:
332:
333: }
334:
335: }
336:
337: *p = 0;
338:
1.1.1.2 ! root 339: return (int)(p - buf);
1.1 root 340:
341: }
342:
343:
344:
1.1.1.2 ! root 345: int ARGS_ON_STACK
1.1 root 346:
347: ksprintf(char *buf, const char *fmt, ...)
348:
349: {
350:
351: va_list args;
352:
353: int foo;
354:
355:
356:
357: va_start(args, fmt);
358:
359: foo = vksprintf(buf, fmt, args);
360:
361: va_end(args);
362:
363: return foo;
364:
365: }
366:
367:
368:
369: int debug_level = 0; /* how much debugging info should we print? */
370:
371: int out_device = 2; /* BIOS device to write errors to */
372:
373:
374:
375: /*
376:
377: * out_next[i] is the out_device value to use when the current
378:
379: * device is i and the user hits F3.
380:
381: * Cycle is CON -> PRN -> AUX -> MIDI -> 6 -> 7 -> 8 -> 9 -> CON
382:
383: * (Note: BIOS devices 6-8 exist on Mega STe and TT, 9 on TT.)
384:
385: *
386:
387: * out_device and this table are exported to bios.c and used here in HALT().
388:
389: */
390:
391:
392:
393: /* 0 1 2 3 4 5 6 7 8 9 */
394:
395: char out_next[] = { 1, 3, 0, 6, 0, 0, 7, 8, 9, 2 };
396:
397:
398:
399: void
400:
401: debug_ws(s)
402:
403: const char *s;
404:
405: {
406:
407: long r;
408:
409:
410:
411: while (*s) {
412:
413: (void)Bconout(out_device, *s);
414:
415: if (*s == '\n' && out_device != 0 && Bconstat(out_device)) {
416:
1.1.1.2 ! root 417: r = Bconin(out_device) & 0x00ff0000L;
1.1 root 418:
1.1.1.2 ! root 419: if (r == 0x3b0000L)
1.1 root 420:
421: debug_level++;
422:
1.1.1.2 ! root 423: else if (r == 0x3c0000L)
1.1 root 424:
425: --debug_level;
426:
1.1.1.2 ! root 427: else if (r == 0x400000L)
1.1 root 428:
429: DUMPPROC();
430:
1.1.1.2 ! root 431: else if (r == 0x620000L) {
1.1 root 432:
433: do {
434:
1.1.1.2 ! root 435: r = Bconin(out_device) & 0x00ff0000L;
1.1 root 436:
1.1.1.2 ! root 437: } while (r != 0x610000L);
1.1 root 438:
439: }
440:
441: }
442:
443: s++;
444:
445: }
446:
447: }
448:
449:
450:
451: static void
452:
453: VDEBUGOUT(s, args)
454:
455: const char *s;
456:
457: va_list args;
458:
459: {
460:
461: char buf[SPRINTF_MAX];
462:
463:
464:
465: ksprintf(buf, "pid %d (%s): ", curproc->pid, curproc->name);
466:
467: debug_ws(buf);
468:
469: vksprintf(buf, s, args);
470:
471: debug_ws(buf);
472:
473: debug_ws("\r\n");
474:
475: }
476:
477:
478:
1.1.1.2 ! root 479: void ARGS_ON_STACK Trace(const char *s, ...)
1.1 root 480:
481: {
482:
483: va_list args;
484:
485:
486:
487: if (debug_level > 1) {
488:
489: va_start(args, s);
490:
491: VDEBUGOUT(s, args);
492:
493: va_end(args);
494:
495: }
496:
497: }
498:
499:
500:
1.1.1.2 ! root 501: void ARGS_ON_STACK Debug(const char *s, ...)
1.1 root 502:
503: {
504:
505: va_list args;
506:
507:
508:
509: if (debug_level) {
510:
511: va_start(args, s);
512:
513: VDEBUGOUT(s, args);
514:
515: va_end(args);
516:
517: }
518:
519: }
520:
521:
522:
1.1.1.2 ! root 523: void ARGS_ON_STACK ALERT(const char *s, ...)
1.1 root 524:
525: {
526:
527: va_list args;
528:
529:
530:
531: va_start(args, s);
532:
533: VDEBUGOUT(s, args);
534:
535: va_end(args);
536:
537: }
538:
539:
540:
541: EXITING
542:
1.1.1.2 ! root 543: void ARGS_ON_STACK FATAL(const char *s, ...)
1.1 root 544:
545: {
546:
547: va_list args;
548:
549:
550:
551: va_start(args, s);
552:
553: VDEBUGOUT(s, args);
554:
555: va_end(args);
556:
557: HALT();
558:
559: }
560:
561:
562:
563:
564:
565: EXITING
566:
567: void HALT()
568:
569: {
570:
571: long r;
572:
573: extern long tosssp; /* in main.c */
574:
575:
576:
577: restr_intr(); /* restore interrupts to normal */
578:
579: debug_ws("Fatal MiNT error: adjust debug level and hit a key...\r\n");
580:
581: sys_q[READY_Q] = 0; /* prevent context switches */
582:
583:
584:
585: for(;;) {
586:
1.1.1.2 ! root 587: r = Bconin(2) & 0x00ff0000L;
1.1 root 588:
1.1.1.2 ! root 589: if (r == 0x3b0000L)
1.1 root 590:
591: debug_level++;
592:
1.1.1.2 ! root 593: else if (r == 0x3c0000L)
1.1 root 594:
595: --debug_level;
596:
1.1.1.2 ! root 597: else if (r == 0x3d0000L) /* F3: cycle to next device */
1.1 root 598:
599: out_device = out_next[out_device];
600:
1.1.1.2 ! root 601: else if (r == 0x3e0000L)
1.1 root 602:
603: out_device = 2; /* F4: reset to console */
604:
1.1.1.2 ! root 605: else if (r == 0x3f0000L) {
1.1 root 606:
607: DUMPMEM(core); /* F5: dump memory */
608:
1.1.1.2 ! root 609: DUMPMEM(alt);
! 610:
! 611: }
! 612:
! 613: else if (r == 0x400000L)
1.1 root 614:
615: DUMPPROC();
616:
617: else
618:
619: break;
620:
621: }
622:
623: for(;;) {
624:
625: debug_ws("System halted. Press 'x' to exit, or else reboot\r\n");
626:
627: r = Bconin(2);
628:
629:
630:
631: if ( (r & 0x0ff) == 'x' ) {
632:
633: close_filesys();
634:
635: (void)Super((void *)tosssp); /* gratuitous (void *) for Lattice */
636:
1.1.1.2 ! root 637: #ifdef PROFILING
! 638:
! 639: _exit(0);
! 640:
! 641: #else
! 642:
! 643: Pterm0();
! 644:
! 645: #endif
1.1 root 646:
647: }
648:
649: }
650:
651: }
652:
653:
654:
655:
656:
657: /* some key definitions */
658:
659: #define CTRLALT 0xc
660:
661: #define DEL 0x53 /* scan code of delete key */
662:
663: #define UNDO 0x61 /* scan code of undo key */
664:
665:
666:
667: void
668:
669: do_func_key(scan)
670:
671: int scan;
672:
673: {
674:
675: extern struct tty con_tty;
676:
677:
678:
679: switch (scan) {
680:
681: case DEL:
682:
683: reboot();
684:
685: break;
686:
687: case UNDO:
688:
689: killgroup(con_tty.pgrp, SIGQUIT);
690:
691: break;
692:
1.1.1.2 ! root 693: #ifndef NO_DEBUG_INFO
! 694:
1.1 root 695: case 0x3b: /* F1 */
696:
697: debug_level++;
698:
699: break;
700:
701: case 0x3c: /* F2 */
702:
703: if (debug_level > 0)
704:
705: --debug_level;
706:
707: break;
708:
709: case 0x3d: /* F3 */
710:
711: out_device = out_next[out_device];
712:
713: break;
714:
715: case 0x3e: /* F4 */
716:
717: out_device = 2;
718:
719: break;
720:
721: case 0x3f: /* F5 */
722:
723: DUMPMEM(core);
724:
1.1.1.2 ! root 725: DUMPMEM(alt);
! 726:
1.1 root 727: break;
728:
729: case 0x40: /* F6 */
730:
731: DUMPPROC();
732:
733: break;
734:
1.1.1.2 ! root 735: #endif
! 736:
1.1 root 737: }
738:
739: }
740:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.