1
0
Files
2022-09-29 17:59:04 +03:00

641 lines
17 KiB
C

/*
* -------------------------------------------------------------
* $Revision: 1.1 $
* $Date: 1997/08/18 20:42:21 $
* -------------------------------------------------------------
* a simple printf function,
*/
#include <stdarg.h>
#include <inttypes.h>
#include <st16c1451.h>
#define Bhex 4
#define Shex 12
#define Ihex 28
#define Lhex 60
#define Boct 3
#define Soct 15
#define Ioct 30
#define Loct 63
#define CTRL(x) ((x)&0x1f)
#define DEL 0x7f
#define INTR CTRL('C')
#define BELL 0x7
#define LINESIZE 128
#define PROMPT "? "
#define SCALABLE 'I'
char digit[] = "0123456789abcdef" ;
/*
* Function: gethdec()
* Get all the pending chars and xtranlate it
* into a number (ibase=16, obase=10), anything
* greater the int size will be transcated, i.e.
* only the last 8 characters will be honored.
*/
#ifdef UNIXSIM
#define GETC getchar
#else
#define GETC getc
#endif
/*
* Function: Getting a decimal number from tty
*/
uint64_t
getdec ()
{
register char datain ;
register int ccount ;
register int64_t value ;
datain = '!' ;
ccount = value = 0x0 ;
while (((datain = (char) GETC ()) != '\012') && (datain != '\015')) {
if ((datain == '\010') && (ccount > 0)) {
ccount -= 1 ; /* decrement the char count. */
value = value / 10 ; /* remove previous char. */
putchar ('\010');
putchar (' ');
putchar ('\010');
} else {
putchar (datain) ; /* Echo what we got. */
if ((datain >= '0') && (datain <= '9')) {
ccount += 1 ;
value = (value * 10) + (datain - '0') ;
} else {
/* we simply ignore the invalid input characters. */
/* or we can terminate the get process ????? */
return -1 ;
}
}
}
if (ccount == 0x0) value = -1 ; /* no valid input character. */
return ((uint64_t)value) ;
}
/*
* Function: Getting a hex number from tty.
*/
uint64_t
gethex ()
{
register char datain ;
register int ccount ;
register int64_t value ;
datain = '!' ;
ccount = value = 0x0 ;
while (((datain = (char) GETC ()) != '\012') && (datain != '\015')) {
if ((datain == '\010') && (ccount > 0)) {
ccount -= 1 ; /* decrement the char count. */
value = value >> 4 ; /* remove previous char. */
putchar ('\010');
putchar (' ');
putchar ('\010');
} else {
putchar (datain) ; /* Echo what we got. */
if ((datain >= '0') && (datain <= '9')) {
ccount += 1 ;
value = (value << 4) + (datain - '0') ;
} else if ((datain >= 'a') && (datain <= 'f')) {
ccount += 1 ;
value = (value << 4) + (datain - 'a' + 10) ;
} else if ((datain >= 'A') && (datain <= 'F')) {
ccount += 1 ;
value = (value << 4) + (datain - 'A' + 10) ;
} /* we simply ignore the invalid input characters. */
/* or we can terminate the get process ????? */
}
}
if (ccount == 0x0) value = -1 ; /* no valid input character. */
return ((uint64_t)value) ;
}
/*
* Function: printudec(uint64_t val, int position)
*/
void
printudec (uint64_t val, int ovr, int size)
{
char dc[22], c ;
register int ptr, indx, indx1 ;
register uint64_t v, rem ;
if ((val == 0) && (ovr == 0)) {
putchar ('0') ;
return ;
}
for (rem = 0 ; rem < 22 ; dc[rem++] = '0') ;
ptr = 0 ;
v = val ;
while (v >= 10) {
rem = v/10 ;
indx = v - (rem * 10) ;
dc[ptr] = digit[indx] ;
v = rem ;
if (indx != 0) indx1 = ptr ;
ptr += 1 ;
}
dc[ptr] = digit[v] ;
if (v != 0) indx1 = ptr ; /* the leading non zero digit. */
if ((ovr != 0) && (size != 0x0)) ptr = size ;
else ptr = indx1 ; /* don't print leading 0s' */
while (ptr >= 0) {
putchar (dc[ptr]) ;
ptr -= 1 ;
}
}
/*
* Function: printdec(uint64_t val, int position)
*/
void
printdec (int64_t val, int ovr, int size)
{
char dc[22], c ;
register int ptr, indx, indx1 ;
register int64_t v, rem ;
if ((val == 0) && (ovr == 0)) {
putchar ('0') ;
return ;
}
for (rem = 0 ; rem < 22 ; rem++) dc[rem] = '0' ;
ptr = 0 ;
if (val < 0) {
c = '-' ;
v = -val ;
} else {
c = ' ' ;
v = val ;
}
while (v >= 10) {
rem = v/10 ;
indx = v - (rem * 10) ;
dc[ptr] = digit[indx] ;
v = rem ;
if (indx != 0) indx1 = ptr ;
ptr += 1 ;
}
dc[ptr] = digit[v] ;
if (v != 0) indx1 = ptr ; /* the leading non zero digit. */
if ((ovr != 0) && (size != 0x0)) ptr = size ;
else ptr = indx1 ; /* don't print leading 0s' */
if (c == '-') putchar (c) ;
while (ptr >= 0) {
putchar (dc[ptr]) ;
ptr -= 1 ;
}
}
/*
* Function: printhex(uint64_t val, int position)
*/
void
printhex (uint64_t val, int ovr, int pos, char C)
{
register char c ;
register int pcount, nonzero ;
pcount = pos ;
nonzero = 0 ;
if ((val == 0) && (ovr == 0)) {
putchar ('0') ;
return ;
}
while (pcount >= 0) {
if (pcount == 0) c = digit[val & 0xF] ;
else c = digit[(val >> pcount) & 0xF] ;
if ((C == 'X') && (c > '9')) c = c - 'a' + 'A' ;
if (c == '0') {
if ((nonzero > 0) || (ovr != 0)) {
putchar (c);
}
} else {
nonzero++;
putchar (c);
}
pcount -= 4 ;
}
return ;
}
/*
* Function: printoct(uint64_t val, int position)
*/
void
printoct (uint64_t val, int ovr, int pos)
{
register char c ;
register int pcount, indx ;
pcount = pos ;
indx = 0 ;
if ((val == 0) && (ovr == 0)) {
putchar ('0') ;
return ;
}
while (pcount >= 0) {
if (pcount == 0) c = digit[val & 0x7] ;
else c = digit[(val >> pcount) & 0x7] ;
if (c != '0') {
indx += 1 ;
putchar (c) ;
} else {
if ((ovr != 0) && (indx != 0)) putchar (c) ;
}
pcount -= 3 ;
}
return ;
}
/*
* Function: printbin(uint64_t val, int position)
*/
void
printbin (uint64_t val, int size)
{
register char c ;
register int pcount ;
pcount = size;
while (pcount >= 0) {
if (pcount == 0) c = digit[val & 0x1] ;
else c = digit[(val >> pcount) & 0x1] ;
putchar (c) ;
pcount -= 1 ;
}
}
/*
* Function: char *cachefmt(char *), move the string to cache
* then return the address.
*/
void
cachefmt (uint64_t val, int size)
{
register char c ;
register int pcount ;
pcount = size;
while (pcount >= 0) {
if (pcount == 0) c = digit[val & 0x1] ;
else c = digit[(val >> pcount) & 0x1] ;
putchar (c) ;
pcount -= 1 ;
}
}
/*
* This printf only suppot decimal (%d), octal (%o), hexdecimal (%x),
* and string (%s), also binary (%b) and long long (64 bit %l).
*/
void
printf (char *fmt, ...)
{
va_list args ;
char *str, *p, errQ[3] ;
register int state, i, size, errP ;
register int ovr ;
va_start (args, fmt) ;
state = 0 ;
ovr = 0 ;
p = fmt ;
errP = 0 ;
while (*p) {
switch (state) {
case 0:
if (*p != '%') {
if ((*p == '\r') || (*p == '\n')) {
putchar ('\r');
putchar ('\n');
} else putchar (*p) ;
} else {
errQ[errP++] = '%' ;
state = 1 ;
}
p++ ; /* point to next character, this also skip */
break ; /* the '%' character. */
case 1: /* check the 0 pedding after '%' - '0' */
state = 2 ; /* to the correct state. */
if (*p == '0') {
errQ[errP++] = '0' ;
ovr = 1 ; /* set the 0 pedding flag. */
p++ ; /* get the next character. */
} else ovr = 0 ;/* no 0 pedding. */
break ;
case 2: /* check the size of the obj to be printed. */
state = 3 ;
switch (*p) {
case 'l':
errQ[errP++] = 'l' ;
size = 64 ; /* set to 64 bit data size. */
p++ ; /* move to next character. */
break ;
case 'h':
errQ[errP++] = 'h' ;
size = 16 ; /* set to 16 bit data size. */
p++ ; /* point to next character. */
break ;
case 'b':
errQ[errP++] = 'b' ;
size = 8 ; /* set to 8 bit data size. */
p++ ; /* point to next character. */
break ;
default:
size = 32 ; /* set to default data size. */
break ;
}
break ;
case 3: /* this is the heart of the printf. */
switch (*p) {
case '%':
putchar ('%') ;
break ;
case 'd': /* object type is integer, base 10. */
case 'i': /* object type is integer, base 10. */
switch (size) { /* get the right size of the object */
case 64: /* long long */
printdec ((uint64_t)va_arg(args, int64_t), ovr, 18) ;
break ;
case 16: /* short */
printdec ((uint64_t)va_arg(args, int16_t), ovr, 4) ;
break ;
case 8: /* byte */
printdec ((uint64_t)va_arg(args, int8_t), ovr, 2) ;
break ;
default: /* int */
printdec ((uint64_t)va_arg(args, int32_t), ovr, 9) ;
break ;
}
break ;
case 'u': /* object type is unsigned integer, base 10. */
switch (size) { /* get the right size of the object */
case 64: /* long long */
printudec ((uint64_t)va_arg(args, uint64_t), ovr, 0) ;
break ;
case 16: /* short */
printudec ((uint64_t)va_arg(args, uint16_t), ovr, 4) ;
break ;
case 8: /* byte */
printudec ((uint64_t)va_arg(args, uint8_t), ovr, 3) ;
break ;
default: /* int */
printudec ((uint64_t)va_arg(args, uint32_t), ovr, 9) ;
break ;
}
break ;
case 'o': /* object type is unsigned integer, base 8. */
switch (size) { /* get the right size of the object */
case 64: /* long long */
printoct ((uint64_t)va_arg(args, uint64_t), ovr, Loct) ;
break ;
case 16: /* short */
printoct ((uint64_t)va_arg(args, uint16_t), ovr, Soct) ;
break ;
case 8: /* byte */
printoct ((uint64_t)va_arg(args, uint8_t), ovr, Boct) ;
break ;
default: /* int */
printoct ((uint64_t)va_arg(args, uint32_t), ovr, Ioct) ;
break ;
}
break ;
case 'x': /* object type is unsigned integer, base 16. */
case 'X': /* object type is unsigned integer, base 16. */
switch (size) { /* get the right size of the object */
case 64: /* long long */
printhex ((uint64_t)va_arg(args, uint64_t),ovr,Lhex,*p) ;
break ;
case 16: /* short */
printhex ((uint64_t)va_arg(args, uint16_t),ovr,Shex,*p) ;
break ;
case 8: /* byte */
printhex ((uint64_t)va_arg(args, uint8_t),ovr,Bhex,*p) ;
break ;
default: /* int */
printhex ((uint64_t)va_arg(args, uint32_t),ovr,Ihex,*p) ;
break ;
}
break ;
case 'c': /* object type is unsigned char. */
putchar ((char)va_arg(args, char)) ;
break ;
case 's': /* object type is a address point to a char. */
str = (char *) va_arg(args, unsigned int) ;
while (*str != '\0') {
if ((*str == '\r') || (*str == '\n')) {
putchar ('\r');
putchar ('\n');
} else putchar (*str) ;
str++;
}
break ;
case '0': /* I consider this an error condition. */
case 'l': /* I consider this an error condition. */
case 'h': /* I consider this an error condition. */
default: /* This also indicate an error. */
for (i = 0 ; i < 3 ; i++) putchar (errQ[i]) ;
putchar (*p++) ; /* move to next character. */
break ;
}
state = 0 ; /* reset the state machine. */
size = 0 ; /* and reset the size. */
ovr = 0 ; /* and 0 pedding flag. */
errP = 0 ; /* reset the errQ. */
p++ ; /* point to next character. */
}
}
return ;
}
#if defined(UARTIOworks)
/*
* showchar -- print character in visible manner
*/
void
showchar(int c)
{
c &= 0xff;
if (isprint(c))
putchar(c);
else switch (c) {
case '\b':
puts("\\b");
break;
case '\f':
puts("\\f");
break;
case '\n':
puts("\\n");
break;
case '\r':
puts("\\r");
break;
case '\t':
puts("\\t");
break;
default:
putchar('\\');
putchar(((c&0300) >> 6) + '0');
putchar(((c&070) >> 3) + '0');
putchar((c&07) + '0');
break;
}
}
/*
* like stdio fgets, but fd instead of FILE ptr, and has all
* the echo'ing, etc. that is needed for standalone.
*/
char *
ttygets(char *buf, int len)
{
int c;
char *bufp, *rvalp=NULL;
bufp = buf;
for (;;) {
switch (c = getc()) {
case CTRL('V'): /* quote next char */
c = getc();
/*
* Make sure there's room for this character
* plus a trailing \n and 0 byte
*/
if (bufp < &buf[len-3]) {
*bufp++ = (char)c;
showchar(c);
} else
putchar(BELL);
break;
case CTRL('D'): /* handle ^D for eof */
case EOF:
if(bufp == buf) {
buf[0] = '\0';
rvalp = NULL;
break;
} /* else fall through */
case '\n':
case '\r':
putchar('\r');
putchar('\n');
*bufp = 0;
rvalp = buf;
break;
case CTRL('H'):
case DEL:
/*
* Change this to a hardcopy erase????
*/
if (bufp > buf) {
if (*(bufp-1) == '\t') {
bufp--;
goto ctrl_R;
}
*--bufp = 0;
putchar(CTRL('H'));
putchar(' ');
putchar(CTRL('H'));
}
break;
case CTRL('R'):
ctrl_R:
*bufp = '\0';
printf("^R\n%s%s",PROMPT, buf);
break;
case CTRL('U'):
if (bufp > buf) {
printf("^U\n%s", PROMPT);
bufp = buf;
}
break;
case '\t':
*bufp++ = (char)c;
putchar(c);
break;
default:
/*
* Make sure there's room for this character
* plus a trailing \n and 0 byte
*/
if (isprint(c) && bufp < &buf[len-3]) {
*bufp++ = (char)c;
putchar(c);
} else
putchar(BELL);
break;
}
if (rvalp) break ;
}
return(rvalp);
}
/* assume max len of LINESIZE, which is correct for almost all callers */
char *
gets(char *buf)
{
return ttygets(buf, LINESIZE);
}
#endif
/*
* -------------------------------------------------------------
*
* $Log: uartio.c,v $
* Revision 1.1 1997/08/18 20:42:21 philw
* updated file from bonsai/patch2039 tree
*
* Revision 1.4 1996/10/31 21:51:55 kuang
* Bring Bonsai IP32 debugcard up to the level of IP32 debugcard v2.4 on Pulpwood
*
* Revision 1.3 1995/12/30 03:28:28 kuang
* First moosehead lab bringup checkin, corresponding to 12-29-95 d15
*
* Revision 1.2 1995/11/28 02:20:47 kuang
* General cleanup and fixed several bugs in the printhex routine.
*
* Revision 1.1 1995/11/15 00:42:49 kuang
* initial checkin
*
* Revision 1.2 1995/11/14 23:33:39 kuang
* Rearranged the rcs keyword a bit and get ready for
* ptool checkin
*
* Revision 1.1 1995/11/01 21:31:48 kuang
* Initial revision
*
* -------------------------------------------------------------
*/
/* END OF FILE */