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