#include <sys/param.h>
#include <sys/systm.h>
#include <sys/cons.h>
#include <sys/ctype.h>
#include <sys/thread2.h>
#include <sys/spinlock2.h>
#include <machine/stdarg.h>
#include <ddb/ddb.h>
#include <ddb/db_output.h>
static int db_output_position = 0;
static int db_last_non_space = 0;
db_expr_t db_tab_stop_width = 8;
#define NEXT_TAB(i) rounddown((i) + db_tab_stop_width, db_tab_stop_width)
db_expr_t db_max_width = 79;
static void db_putchar (int c, void *arg);
void
db_force_whitespace(void)
{
int last_print, next_tab;
last_print = db_last_non_space;
while (last_print < db_output_position) {
next_tab = NEXT_TAB(last_print);
if (next_tab <= db_output_position) {
while (last_print < next_tab) {
cnputc(' ');
last_print++;
}
}
else {
cnputc(' ');
last_print++;
}
}
db_last_non_space = db_output_position;
}
static void
db_putchar(int c, void *arg)
{
if (!db_active) {
if (c == '\r' || c == '\n' || c == '\t' ||
isprint(c)) {
kprintf("%c", c);
} else {
kprintf("?");
}
if (!db_active)
return;
if (c == '\r' || c == '\n')
db_check_interrupt();
return;
}
crit_enter_hard();
if (c > ' ' && c <= '~') {
db_force_whitespace();
cnputc(c);
db_output_position++;
db_last_non_space = db_output_position;
}
else if (c == '\n') {
cnputc(c);
db_output_position = 0;
db_last_non_space = 0;
db_check_interrupt();
}
else if (c == '\r') {
cnputc(c);
db_output_position = 0;
db_last_non_space = 0;
db_check_interrupt();
}
else if (c == '\t') {
db_output_position = NEXT_TAB(db_output_position);
}
else if (c == ' ') {
db_output_position++;
}
else if (c == '\007') {
cnputc(c);
}
crit_exit_hard();
}
int
db_print_position(void)
{
return (db_output_position);
}
void
db_printf(const char *fmt, ...)
{
__va_list listp;
__va_start(listp, fmt);
kvcprintf (fmt, db_putchar, NULL, listp);
__va_end(listp);
}
void
db_vprintf(const char *fmt, __va_list va)
{
kvcprintf (fmt, db_putchar, NULL, va);
}
int db_indent;
void
db_iprintf(const char *fmt,...)
{
int i;
__va_list listp;
for (i = db_indent; i >= 8; i -= 8)
db_printf("\t");
while (--i >= 0)
db_printf(" ");
__va_start(listp, fmt);
kvcprintf (fmt, db_putchar, NULL, listp);
__va_end(listp);
}
void
db_end_line(int field_width)
{
if (db_output_position + field_width > db_max_width)
db_printf("\n");
}
int
db_more(int *nl)
{
++*nl;
if (*nl == 20) {
int c;
db_printf("--More--");
c = cngetc();
db_printf("\r");
switch (c) {
case '\n':
*nl = 19;
break;
case ' ':
*nl = 0;
break;
default:
db_printf("\n");
return(-1);
}
}
return(0);
}
void
db_format_radix(char *buf, size_t bufsiz, quad_t val, int altflag)
{
const char *fmt;
if (db_radix == 16) {
db_format_hex(buf, bufsiz, val, altflag);
return;
}
if (db_radix == 8)
fmt = altflag ? "-%#qo" : "-%qo";
else
fmt = altflag ? "-%#qu" : "-%qu";
if (val < 0)
val = -val;
else
++fmt;
ksnprintf(buf, bufsiz, fmt, val);
}
void
db_format_hex(char *buf, size_t bufsiz, quad_t val, int altflag)
{
const char *fmt = (altflag && val) ? "-%#qx" : "-%qx";
if (val < 0)
val = -val;
else
++fmt;
ksnprintf(buf, bufsiz, fmt, val);
}
#ifdef TEMPORARY_DEBUGGING
static void PCHAR_(int, void * __unused);
void
kprintf0(const char *fmt, ...)
{
__va_list ap;
__va_start(ap, fmt);
kvcprintf(fmt, PCHAR_, NULL, ap);
__va_end(ap);
}
static void
PCHAR_(int c, void *dummy __unused)
{
const int COMC_TXWAIT = 0x40000;
const int COMPORT = 0x2f8;
const int LSR_TXRDY = 0x20;
const int BAUD = 115200;
const int com_lsr = 5;
const int com_data = 0;
int wait;
static int setbaud;
if (setbaud == 0) {
setbaud = 1;
outb(COMPORT+3, 0x83);
outb(COMPORT+0, (115200 / BAUD) & 0xFF);
outb(COMPORT+1, (115200 / BAUD) >> 8);
outb(COMPORT+3, 0x03);
outb(COMPORT+4, 0x03);
outb(COMPORT+2, 0x01);
}
for (wait = COMC_TXWAIT; wait > 0; wait--) {
if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
outb(COMPORT + com_data, (u_char)c);
break;
}
}
}
#endif