home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
mint
/
mint095s
/
debug.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-03
|
7KB
|
362 lines
/*
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_((const 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(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(char *p, const char *s, int *cnt, int width) {
int put = 0;
if (s == 0) s = "(null)";
while (*cnt > 0 && *s) {
*p++ = *s++;
put++;
*cnt -= 1;
width--;
}
while (width-- > 0 && *cnt > 0) {
*p++ = ' ';
put++;
*cnt -= 1;
}
return put;
}
static int
PUTL(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(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 (p - buf);
}
int
ksprintf(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)
const char *s;
{
long r;
while (*s) {
(void)Bconout(out_device, *s);
if (*s == '\n' && out_device != 0 && Bconstat(out_device)) {
r = Bconin(out_device) & 0x00ff0000;
if (r == 0x3b0000)
debug_level++;
else if (r == 0x3c0000)
--debug_level;
else if (r == 0x400000)
DUMPPROC();
else if (r == 0x620000) {
do {
r = Bconin(out_device) & 0x00ff0000;
} while (r != 0x610000);
}
}
s++;
}
}
static void
VDEBUGOUT(s, args)
const 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(const char *s, ...)
{
va_list args;
if (debug_level > 1) {
va_start(args, s);
VDEBUGOUT(s, args);
va_end(args);
}
}
void DEBUG(const char *s, ...)
{
va_list args;
if (debug_level) {
va_start(args, s);
VDEBUGOUT(s, args);
va_end(args);
}
}
void ALERT(const char *s, ...)
{
va_list args;
va_start(args, s);
VDEBUGOUT(s, args);
va_end(args);
}
EXITING
void FATAL(const 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) & 0x00ff0000;
if (r == 0x3b0000)
debug_level++;
else if (r == 0x3c0000)
--debug_level;
else if (r == 0x3d0000) /* F3: cycle to next device */
out_device = out_next[out_device];
else if (r == 0x3e0000)
out_device = 2; /* F4: reset to console */
else if (r == 0x3f0000)
DUMPMEM(core); /* F5: dump memory */
else if (r == 0x400000)
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((void *)tosssp); /* gratuitous (void *) for Lattice */
zeroexit();
}
}
}
/* 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);
break;
case 0x40: /* F6 */
DUMPPROC();
break;
}
}