add fmt.c for print function
don't process 64-bit format such as '%llu' in print function.
This commit is contained in:
parent
c9c820840f
commit
b1f7092fe2
@ -5,7 +5,7 @@ PROG = boot
|
|||||||
SRCS = srt0.S gdt.S boot.c
|
SRCS = srt0.S gdt.S boot.c
|
||||||
OBJS = srt0.o gdt.o boot.o
|
OBJS = srt0.o gdt.o boot.o
|
||||||
|
|
||||||
ESRCS = pccon.c sricon.c print.c a20.c time.c mem.c
|
ESRCS = pccon.c sricon.c print.c fmt.c a20.c time.c mem.c
|
||||||
OBJS += $(ESRCS:.c=.o)
|
OBJS += $(ESRCS:.c=.o)
|
||||||
|
|
||||||
include $(SDIR)/Makefile.inc
|
include $(SDIR)/Makefile.inc
|
||||||
|
|||||||
11
boot/dat.h
11
boot/dat.h
@ -2,6 +2,7 @@
|
|||||||
// 0x60 Read/Write Data Port
|
// 0x60 Read/Write Data Port
|
||||||
// 0x64 Read Status Register
|
// 0x64 Read Status Register
|
||||||
// 0x64 Write Command Register
|
// 0x64 Write Command Register
|
||||||
|
#define TABWIDTH 8
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
CON_PC,
|
CON_PC,
|
||||||
@ -42,6 +43,16 @@ typedef struct{
|
|||||||
u32 type; /* Type of block */
|
u32 type; /* Type of block */
|
||||||
} __attribute__((packed)) BIOSmmap;
|
} __attribute__((packed)) BIOSmmap;
|
||||||
|
|
||||||
|
// fmt.c
|
||||||
|
typedef struct{
|
||||||
|
int ucase;
|
||||||
|
int padch;
|
||||||
|
char *p;
|
||||||
|
char *ep;
|
||||||
|
int f1, f2, f3;
|
||||||
|
va_list ap;
|
||||||
|
}Op;
|
||||||
|
|
||||||
// gdt.S
|
// gdt.S
|
||||||
extern volatile struct BIOSreg BIOSreg;
|
extern volatile struct BIOSreg BIOSreg;
|
||||||
|
|
||||||
|
|||||||
304
boot/fmt.c
Normal file
304
boot/fmt.c
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
#include <u.h>
|
||||||
|
#include "dat.h"
|
||||||
|
#include "fn.h"
|
||||||
|
|
||||||
|
#define MAXCON 30
|
||||||
|
#define IDIGIT 30
|
||||||
|
|
||||||
|
enum{
|
||||||
|
FLONG = (1<<0),
|
||||||
|
FSHORT = (1<<2),
|
||||||
|
FUNSIGN = (1<<3),
|
||||||
|
};
|
||||||
|
|
||||||
|
static Op put(Op, int);
|
||||||
|
static Op noconv(Op);
|
||||||
|
static Op cconv(Op);
|
||||||
|
static Op dconv(Op);
|
||||||
|
static Op hconv(Op);
|
||||||
|
static Op lconv(Op);
|
||||||
|
static Op sconv(Op);
|
||||||
|
static Op uconv(Op);
|
||||||
|
static Op xconv(Op);
|
||||||
|
static Op Xconv(Op);
|
||||||
|
static Op percent(Op);
|
||||||
|
|
||||||
|
static Op (*fmtconv[MAXCON])(Op) = {
|
||||||
|
noconv,
|
||||||
|
cconv, dconv, hconv, lconv,
|
||||||
|
sconv, uconv, xconv, Xconv,
|
||||||
|
percent,
|
||||||
|
};
|
||||||
|
|
||||||
|
int fmtindex[128] = {
|
||||||
|
['c'] = 1,
|
||||||
|
['d'] = 2,
|
||||||
|
['h'] = 3,
|
||||||
|
['l'] = 4,
|
||||||
|
['s'] = 5,
|
||||||
|
['u'] = 6,
|
||||||
|
['x'] = 7,
|
||||||
|
['X'] = 8,
|
||||||
|
['%'] = 9,
|
||||||
|
};
|
||||||
|
int convcnt = 11;
|
||||||
|
|
||||||
|
int
|
||||||
|
strlen(char *s)
|
||||||
|
{
|
||||||
|
char *p = s;
|
||||||
|
|
||||||
|
while(*p)
|
||||||
|
++p;
|
||||||
|
return p-s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fmtinstall(int c, Op (*f)(Op))
|
||||||
|
{
|
||||||
|
c &= 0177;
|
||||||
|
if(fmtindex[c] == 0){
|
||||||
|
if(convcnt + 1 >= MAXCON)
|
||||||
|
return -1;
|
||||||
|
fmtindex[c] = convcnt++;
|
||||||
|
}
|
||||||
|
fmtconv[fmtindex[c]] = f;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
doprint(char *p, char *ep, char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int sf1, c;
|
||||||
|
Op o = { .p = p, .ep = ep, .ap = ap };
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
c = *fmt++;
|
||||||
|
if(c != '%'){
|
||||||
|
if(c == 0){
|
||||||
|
if(o.p < o.ep)
|
||||||
|
*o.p = 0;
|
||||||
|
return o.p;
|
||||||
|
}
|
||||||
|
o = put(o, c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
o.f2 = -1;
|
||||||
|
o.f1 = o.f3 = 0;
|
||||||
|
o.padch = sf1 = 0;
|
||||||
|
c = *fmt++;
|
||||||
|
if(c == '-'){
|
||||||
|
sf1 = 1;
|
||||||
|
c = *fmt++;
|
||||||
|
}else if(c == '0' || c == ' '){
|
||||||
|
o.padch = c;
|
||||||
|
c = *fmt++;
|
||||||
|
}
|
||||||
|
while(c >= '0' && c <= '9'){
|
||||||
|
o.f1 = o.f1*10 + c-'0';
|
||||||
|
c = *fmt++;
|
||||||
|
}
|
||||||
|
if(sf1)
|
||||||
|
o.f1 = -o.f1;
|
||||||
|
if(c != '.')
|
||||||
|
goto conv;
|
||||||
|
c = *fmt++;
|
||||||
|
while(c >= '0' && c <= '9'){
|
||||||
|
if(o.f2 < 0)
|
||||||
|
o.f2 = 0;
|
||||||
|
o.f2 = o.f2*10 + c-'0';
|
||||||
|
c = *fmt++;
|
||||||
|
}
|
||||||
|
conv:
|
||||||
|
if(c == 0)
|
||||||
|
fmt -= 1;
|
||||||
|
o = (*fmtconv[fmtindex[c&0177]])(o);
|
||||||
|
if(o.f3){
|
||||||
|
c = *fmt++;
|
||||||
|
goto conv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
strconv(char *o, Op op, int f1, int f2)
|
||||||
|
{
|
||||||
|
int n, c;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
n = strlen(o);
|
||||||
|
if(f1 >= 0)
|
||||||
|
while(n < f1){
|
||||||
|
op = put(op, op.padch);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
for(p=o; (c = *p++);)
|
||||||
|
if(f2){
|
||||||
|
op = put(op, c);
|
||||||
|
f2 -= 1;
|
||||||
|
}
|
||||||
|
if(f1 < 0){
|
||||||
|
f1 = -f1;
|
||||||
|
while(n < f1){
|
||||||
|
op = put(op, ' ');
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
numconv(Op op, int base)
|
||||||
|
{
|
||||||
|
char b[IDIGIT];
|
||||||
|
int i,f,n;
|
||||||
|
long v;
|
||||||
|
short h;
|
||||||
|
|
||||||
|
i = IDIGIT-1;
|
||||||
|
f = 0;
|
||||||
|
b[i] = 0;
|
||||||
|
switch(op.f3 & (FLONG|FSHORT|FUNSIGN)){
|
||||||
|
case FLONG:
|
||||||
|
v = va_arg(op.ap, long);
|
||||||
|
break;
|
||||||
|
case FUNSIGN|FLONG:
|
||||||
|
v = va_arg(op.ap, ulong);
|
||||||
|
break;
|
||||||
|
case FSHORT:
|
||||||
|
v = h = va_arg(op.ap, short);
|
||||||
|
break;
|
||||||
|
case FUNSIGN|FSHORT:
|
||||||
|
h = va_arg(op.ap, ushort);
|
||||||
|
v = (ushort)h;
|
||||||
|
break;
|
||||||
|
case FUNSIGN:
|
||||||
|
v = va_arg(op.ap, unsigned);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
v = va_arg(op.ap, long);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if((op.f3 & FUNSIGN) && v < 0){
|
||||||
|
v = -v;
|
||||||
|
f = 1;
|
||||||
|
}
|
||||||
|
while(--i){
|
||||||
|
n = v % base;
|
||||||
|
n += '0';
|
||||||
|
if(n > '9'){
|
||||||
|
n += 'a' - ('9'+1);
|
||||||
|
if(op.ucase)
|
||||||
|
n += 'A'-'a';
|
||||||
|
}
|
||||||
|
b[i] = n;
|
||||||
|
v = (ulong)v / base;
|
||||||
|
if(i < 2)
|
||||||
|
break;
|
||||||
|
if(op.f2 >= 0 && i >= IDIGIT - op.f2)
|
||||||
|
continue;
|
||||||
|
if(v <= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(f)
|
||||||
|
b[--i] = '-';
|
||||||
|
op.f3 = 0;
|
||||||
|
return strconv(b+i, op, op.f1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
noconv(Op op)
|
||||||
|
{
|
||||||
|
return strconv("***ERROR: noconv***", op, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
cconv(Op op)
|
||||||
|
{
|
||||||
|
char b[2];
|
||||||
|
|
||||||
|
b[0] = va_arg(op.ap, char);
|
||||||
|
b[1] = 0;
|
||||||
|
return strconv(b, op, op.f1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
dconv(Op op)
|
||||||
|
{
|
||||||
|
return numconv(op, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
hconv(Op op)
|
||||||
|
{
|
||||||
|
op.f3 |= FSHORT;
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
lconv(Op op)
|
||||||
|
{
|
||||||
|
op.f3 |= FLONG;
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
uconv(Op op)
|
||||||
|
{
|
||||||
|
op.f3 |= FUNSIGN;
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
sconv(Op op)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = va_arg(op.ap, char*);
|
||||||
|
return strconv(p?p:"<nil>", op, op.f1, op.f2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
xconv(Op op)
|
||||||
|
{
|
||||||
|
return numconv(op, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
Xconv(Op op)
|
||||||
|
{
|
||||||
|
op.ucase = 1;
|
||||||
|
op = numconv(op, 16);
|
||||||
|
op.ucase = 0;
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
percent(Op op)
|
||||||
|
{
|
||||||
|
return put(op, '%');
|
||||||
|
}
|
||||||
|
|
||||||
|
static Op
|
||||||
|
put(Op o, int c)
|
||||||
|
{
|
||||||
|
static int pos;
|
||||||
|
int opos;
|
||||||
|
|
||||||
|
if(c == 0)
|
||||||
|
return o;
|
||||||
|
if(c == '\t'){
|
||||||
|
opos = pos;
|
||||||
|
pos = (opos+TABWIDTH) & (~(TABWIDTH-1));
|
||||||
|
while(opos++ < pos && o.p < o.ep)
|
||||||
|
*o.p++ = ' ';
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
if(o.p < o.ep){
|
||||||
|
*o.p++ = c;
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
if(c == '\n')
|
||||||
|
pos = 0;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
@ -11,10 +11,17 @@ int comprobe(ConDev *d);
|
|||||||
int comgetc(int dev);
|
int comgetc(int dev);
|
||||||
void computc(int dev, int c);
|
void computc(int dev, int c);
|
||||||
|
|
||||||
|
// fmt.c
|
||||||
|
int fmtinstall(int c, Op (*f)(Op));
|
||||||
|
char *doprint(char *p, char *ep, char *fmt, va_list ap);
|
||||||
|
int strlen(char *s);
|
||||||
|
|
||||||
// print.c
|
// print.c
|
||||||
void putchar(int c);
|
void putchar(int c);
|
||||||
|
void putstr(char *s, int l);
|
||||||
int getchar(void);
|
int getchar(void);
|
||||||
void print(const char *fmt, ...);
|
int print(char *fmt, ...);
|
||||||
|
int snprint(char *buf, int len, char *fmt, ...);
|
||||||
|
|
||||||
// a20.c
|
// a20.c
|
||||||
void a20up(void);
|
void a20up(void);
|
||||||
|
|||||||
15
boot/mem.c
15
boot/mem.c
@ -42,13 +42,13 @@ dumpmem(BIOSmmap *m)
|
|||||||
ulong tot = 0;
|
ulong tot = 0;
|
||||||
|
|
||||||
for(BIOSmmap *p=m; p->type != MAP_END; ++p){
|
for(BIOSmmap *p=m; p->type != MAP_END; ++p){
|
||||||
print("MEM %u type %u size %lldKB at 0x%llx\n",
|
print("MEM % 2ud type %ud size % 10udKB at %08x:%08x\n",
|
||||||
p-m, p->type, p->size/1024, p->addr);
|
p-m, p->type, (uint)(p->size/1024), (uint)(p->addr>>32), (uint)p->addr);
|
||||||
if(p->type == MAP_FREE)
|
if(p->type == MAP_FREE)
|
||||||
tot += p->size/1024;
|
tot += p->size/1024;
|
||||||
}
|
}
|
||||||
print("RAM low:%dKB high:%dKB\n", cnvmem, extmem);
|
print("RAM low:%udKB high:%udKB\n", cnvmem, extmem);
|
||||||
print("Total free memory: %dKB\n", tot);
|
print("Total free memory: %udKB\n", tot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -70,13 +70,12 @@ memprobe(void)
|
|||||||
m->type = MAP_END;
|
m->type = MAP_END;
|
||||||
for(m = biosmmap; m->type != MAP_END; ++m){
|
for(m = biosmmap; m->type != MAP_END; ++m){
|
||||||
if(m->type != MAP_FREE || m->size <= 0)
|
if(m->type != MAP_FREE || m->size <= 0)
|
||||||
continue;
|
continue;
|
||||||
if(m->addr < IOMEM_BEGIN)
|
if(m->addr < IOMEM_BEGIN)
|
||||||
cnvmem = MAX(cnvmem, m->addr + m->size)/1024;
|
cnvmem = MAX(cnvmem, m->addr + m->size)/1024;
|
||||||
if(m->addr >= IOMEM_END)
|
if(m->addr >= IOMEM_END)
|
||||||
extmem += m->size/1024;
|
extmem += m->size/1024;
|
||||||
}
|
}
|
||||||
dumpmem(biosmmap);
|
dumpmem(biosmmap);
|
||||||
print("A20:%d", isa20done());
|
print("A20:%s\n", isa20done() ? "ok" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
86
boot/print.c
86
boot/print.c
@ -2,61 +2,42 @@
|
|||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
|
|
||||||
#define TABWIDTH 4
|
#define BUFSIZE 1024
|
||||||
|
|
||||||
static void conputc(int c);
|
static void conputc(int);
|
||||||
static int congetc(void);
|
static int congetc(void);
|
||||||
static void doprint(void (*put)(int), const char *fmt, va_list ap);
|
|
||||||
static void putint(void (*put)(int), int n, const char *sym, int base);
|
|
||||||
static int pos = 0;
|
|
||||||
|
|
||||||
void
|
int
|
||||||
print(const char *fmt, ...)
|
print(char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
char buf[BUFSIZE], *p;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
doprint(putchar, fmt, args);
|
p = doprint(buf, buf+sizeof(buf), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
putstr(buf, p-buf);
|
||||||
|
return p-buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int
|
||||||
doprint(void (*put)(int), const char *s, va_list ap)
|
snprint(char *buf, int len, char *fmt, ...)
|
||||||
{
|
{
|
||||||
while(*s){
|
char *p;
|
||||||
if(*s != '%'){
|
va_list args;
|
||||||
put(*s++);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++s;
|
|
||||||
switch(*s){
|
|
||||||
case 'd':
|
|
||||||
putint(put, va_arg(ap,int), "0123456789", 10);
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
putint(put, va_arg(ap,int), "0123456789abcdef", 16);
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
putint(put, va_arg(ap,int), "0123456789ABCDEF", 16);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
for(char *p=va_arg(ap,char*); *p; ++p)
|
|
||||||
put(*p);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
++s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
p = doprint(buf, buf+len, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return p-buf;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
getchar(void)
|
getchar(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = congetc();
|
c = congetc();
|
||||||
if(c == '\r')
|
if(c == '\r')
|
||||||
c = '\n';
|
c = '\n';
|
||||||
if((c < ' ' && c != '\n') || c == '\177')
|
if((c < ' ' && c != '\n') || c == '\177')
|
||||||
@ -65,6 +46,13 @@ getchar(void)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putstr(char *s, int l)
|
||||||
|
{
|
||||||
|
while(l--)
|
||||||
|
putchar(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
putchar(int c)
|
putchar(int c)
|
||||||
{
|
{
|
||||||
@ -72,24 +60,20 @@ putchar(int c)
|
|||||||
case '\177':
|
case '\177':
|
||||||
conputc('\b');
|
conputc('\b');
|
||||||
conputc(' ');
|
conputc(' ');
|
||||||
|
break;
|
||||||
case '\b':
|
case '\b':
|
||||||
conputc('\b');
|
conputc('\b');
|
||||||
if(pos > 0)
|
|
||||||
--pos;
|
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
do{
|
for(int i = 0; i < TABWIDTH; ++i)
|
||||||
conputc(' ');
|
conputc(' ');
|
||||||
}while(++pos % TABWIDTH);
|
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
conputc(c);
|
conputc(c);
|
||||||
pos = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
conputc(c);
|
conputc(c);
|
||||||
++pos;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,20 +92,4 @@ static int
|
|||||||
congetc(void)
|
congetc(void)
|
||||||
{
|
{
|
||||||
return con->getc(con->dev);
|
return con->getc(con->dev);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
putint(void (*put)(int), int n, const char *sym, int base)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char buf[16];
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
do{
|
|
||||||
buf[i++] = n%base;
|
|
||||||
n /= base;
|
|
||||||
}while(n);
|
|
||||||
do{
|
|
||||||
put((int)sym[(int)buf[--i]]);
|
|
||||||
}while(i);
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user