File:  [Atari MiNT] / MiNT / src / debugold.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:55:42 2018 UTC (8 years, 1 month ago) by root
Branches: mint, MAIN
CVS tags: mint096, HEAD
MiNT 0.96 pl14

/*

Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.

*/



/* MiNT debugging output routines */

/* also, ksprintf is put here, for lack of any better place to put it */



#include "mint.h"

#include <stdarg.h>



static void VDEBUGOUT P_((char *, va_list));



/*

 * ksprintf implements a very crude sprintf() function that provides only

 * what MiNT needs...

 *

 * NOTE: this sprintf probably doesn't conform to any standard at

 * all. It's only use in life is that it won't overflow fixed

 * size buffers (i.e. it won't try to write more than SPRINTF_MAX

 * characters into a string)

 */



static int

PUTC(p, c, cnt, width)

	char *p;

	int c;

	int *cnt;

	int width;

{

	int put = 1;



	if (*cnt <= 0) return 0;

	*p++ = c;

	*cnt -= 1;

	while (*cnt > 0 && --width > 0) {

		*p++ = ' ';

		*cnt -= 1;

		put++;

	}

	return put;

}



static int

PUTS(p, s, cnt, width)

	char *p, *s;

	int *cnt;

	int width;

{

	int put = 0;



	while (*cnt > 0 && *s) {

		*p++ = *s++;

		put++;

		*cnt -= 1;

		width--;

	}

	while (width-- > 0 && *cnt > 0) {

		*p++ = ' ';

		put++;

		*cnt -= 1;

	}

	return put;

}



static int

PUTL(p, u, base, cnt, width, fill_char)

	char *p;

	unsigned long u;

	int base;

	int *cnt;

	int width;

	int fill_char;

{

	int put = 0;

	static char obuf[32];

	char *t;



	t = obuf;



	do {

		*t++ = "0123456789abcdef"[u % base];

		u /= base;

		width--;

	} while (u > 0);



	while (width-- > 0 && *cnt > 0) {

		*p++ = fill_char;

		put++;

		*cnt -= 1;

	}

	while (*cnt > 0 && t != obuf) {

		*p++ = *--t;

		put++;

		*cnt -= 1;

	}

	return put;

}



int

vksprintf(buf, fmt, args)

	char *buf;

	const char *fmt;

	va_list args;

{

	char *p = buf, c, fill_char;

	char *s_arg;

	int i_arg;

	long l_arg;

	int cnt;

	int width, long_flag;



	cnt = SPRINTF_MAX - 1;

	while( (c = *fmt++) != 0 ) {

		if (c != '%') {

			p += PUTC(p, c, &cnt, 1);

			continue;

		}

		c = *fmt++;

		width = 0;

		long_flag = 0;

		fill_char = ' ';

		if (c == '0') fill_char = '0';

		while (c && isdigit(c)) {

			width = 10*width + (c-'0');

			c = *fmt++;

		}

		if (c == 'l' || c == 'L') {

			long_flag = 1;

			c = *fmt++;

		}

		if (!c) break;



		switch (c) {

		case '%':

			p += PUTC(p, c, &cnt, width);

			break;

		case 'c':

			i_arg = va_arg(args, int);

			p += PUTC(p, i_arg, &cnt, width);

			break;

		case 's':

			s_arg = va_arg(args, char *);

			p += PUTS(p, s_arg, &cnt, width);

			break;

		case 'd':

			if (long_flag) {

				l_arg = va_arg(args, long);

			} else {

				l_arg = va_arg(args, int);

			}

			if (l_arg < 0) {

				p += PUTC(p, '-', &cnt, 1);

				width--;

				l_arg = -l_arg;

			}

			p += PUTL(p, l_arg, 10, &cnt, width, fill_char);

			break;

		case 'o':

			if (long_flag) {

				l_arg = va_arg(args, long);

			} else {

				l_arg = va_arg(args, unsigned int);

			}

			p += PUTL(p, l_arg, 8, &cnt, width, fill_char);

			break;

		case 'x':

			if (long_flag) {

				l_arg = va_arg(args, long);

			} else {

				l_arg = va_arg(args, unsigned int);

			}

			p += PUTL(p, l_arg, 16, &cnt, width, fill_char);

			break;

		case 'u':

			if (long_flag) {

				l_arg = va_arg(args, long);

			} else {

				l_arg = va_arg(args, unsigned int);

			}

			p += PUTL(p, l_arg, 10, &cnt, width, fill_char);

			break;



		}

	}

	*p = 0;

	return (int)(p - buf);

}



int

ksprintf(buf, fmt)

	char *buf;

	const char *fmt;

{

	va_list args;

	int foo;



	va_start(args, fmt);

	foo = vksprintf(buf, fmt, args);	

	va_end(args);

	return foo;

}



int debug_level = 0;	/* how much debugging info should we print? */

int out_device = 2;	/* BIOS device to write errors to */



/*

 * out_next[i] is the out_device value to use when the current

 * device is i and the user hits F3.

 * Cycle is CON -> PRN -> AUX -> MIDI -> 6 -> 7 -> 8 -> 9 -> CON

 * (Note: BIOS devices 6-8 exist on Mega STe and TT, 9 on TT.)

 *

 * out_device and this table are exported to bios.c and used here in HALT().

 */



/*		    0  1  2  3  4  5  6  7  8  9 */

char out_next[] = { 1, 3, 0, 6, 0, 0, 7, 8, 9, 2 };



void

debug_ws(s)

	char *s;

{

	long r;



	while (*s) {

		(void)Bconout(out_device, *s);

		if (*s == '\n' && out_device != 0 && Bconstat(out_device)) {

			r = Bconin(out_device) & 0x00ff0000L;

			if (r == 0x3b0000L)

				debug_level++;

			else if (r == 0x3c0000L)

				--debug_level;

			else if (r == 0x400000L)

				DUMPPROC();

			else if (r == 0x620000L) {

				do {

					r = Bconin(out_device) & 0x00ff0000L;

				} while (r != 0x610000L);

			}

		}

		s++;

	}

}



static void

VDEBUGOUT(s, args)

	char *s;

	va_list args;

{

	char buf[SPRINTF_MAX];



	ksprintf(buf, "pid %d (%s): ", curproc->pid, curproc->name);

	debug_ws(buf);

	vksprintf(buf, s, args);

	debug_ws(buf);

	debug_ws("\r\n");

}



void Trace(s)

	char *s;

{

	va_list args;



	if (debug_level > 1) {

		va_start(args, s);

		VDEBUGOUT(s, args);

		va_end(args);

	}

}



void Debug(s)

	char *s;

{

	va_list args;



	if (debug_level) {

		va_start(args, s);

		VDEBUGOUT(s, args);

		va_end(args);

	}

}



void ALERT(s)

	char *s;

{

	va_list args;



	va_start(args, s);

	VDEBUGOUT(s, args);

	va_end(args);

}



EXITING

void FATAL(s)

	char *s;

{

	va_list args;



	va_start(args, s);

	VDEBUGOUT(s, args);

	va_end(args);

	HALT();

}





EXITING 

void HALT()

{

	long r;

	extern long tosssp;	/* in main.c */



	restr_intr();	/* restore interrupts to normal */

	debug_ws("Fatal MiNT error: adjust debug level and hit a key...\r\n");

	sys_q[READY_Q] = 0;	/* prevent context switches */



	for(;;) {

		r = Bconin(2) & 0x00ff0000L;

		if (r == 0x3b0000L)

			debug_level++;

		else if (r == 0x3c0000L)

			--debug_level;

		else if (r == 0x3d0000L)		/* F3: cycle to next device */

			out_device = out_next[out_device];

		else if (r == 0x3e0000L)

			out_device = 2;		/* F4: reset to console */

		else if (r == 0x3f0000L) {

			DUMPMEM(core);		/* F5: dump memory */

			DUMPMEM(alt);

		}

		else if (r == 0x400000L)	

			DUMPPROC();

		else

			break;

	}

	for(;;) {

	debug_ws("System halted. Press 'x' to exit, or else reboot\r\n");

		r = Bconin(2);



		if ( (r & 0x0ff) == 'x' ) {

			close_filesys();

			(void)Super(tosssp);

#ifdef PROFILING

			_exit(0);

#else

			Pterm0();

#endif

		}

	}

}



/* some key definitions */

#define CTRLALT 0xc

#define DEL 0x53	/* scan code of delete key */

#define UNDO 0x61	/* scan code of undo key */



void

do_func_key(scan)

	int scan;

{

	extern struct tty con_tty;



	switch (scan) {

	case DEL:

		reboot();

		break;

	case UNDO:

		killgroup(con_tty.pgrp, SIGQUIT);

		break;

	case 0x3b:		/* F1 */

		debug_level++;

		break;

	case 0x3c:		/* F2 */

		if (debug_level > 0)

			--debug_level;

		break;

	case 0x3d:		/* F3 */

		out_device = out_next[out_device];

		break;

	case 0x3e:		/* F4 */

		out_device = 2;

		break;

	case 0x3f:		/* F5 */

		DUMPMEM(core);

		DUMPMEM(alt);

		break;

	case 0x40:		/* F6 */

		DUMPPROC();

		break;

	}

}




unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.