Purely whitespace changes bringing this file closer to style(9).

Curiously, changing whitespace seems to cause the md5 of the .o files to differ
these days hence the following testing strategy:

Tested by:	objdump -d | md5 (both in-tree clang and lang/gcc6)
This commit is contained in:
Benno Rice 2018-02-21 18:10:50 +00:00
parent 7dcffa9042
commit 50d519d9fb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=329737

View File

@ -72,33 +72,33 @@ extern uint32_t _end;
static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */ static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
static const unsigned char flags[NOPT] = { static const unsigned char flags[NOPT] = {
RBX_DUAL, RBX_DUAL,
RBX_SERIAL, RBX_SERIAL,
RBX_ASKNAME, RBX_ASKNAME,
RBX_CDROM, RBX_CDROM,
RBX_CONFIG, RBX_CONFIG,
RBX_KDB, RBX_KDB,
RBX_GDB, RBX_GDB,
RBX_MUTE, RBX_MUTE,
RBX_NOINTR, RBX_NOINTR,
RBX_PAUSE, RBX_PAUSE,
RBX_QUIET, RBX_QUIET,
RBX_DFLTROOT, RBX_DFLTROOT,
RBX_SINGLE, RBX_SINGLE,
RBX_VERBOSE RBX_VERBOSE
}; };
static const char *const dev_nm[NDEV] = {"ad", "da", "fd"}; static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
static const unsigned char dev_maj[NDEV] = {30, 4, 2}; static const unsigned char dev_maj[NDEV] = {30, 4, 2};
static struct dsk { static struct dsk {
unsigned drive; unsigned drive;
unsigned type; unsigned type;
unsigned unit; unsigned unit;
uint8_t slice; uint8_t slice;
uint8_t part; uint8_t part;
unsigned start; unsigned start;
int init; int init;
} dsk; } dsk;
static char cmd[512], cmddup[512], knamebuf[1024]; static char cmd[512], cmddup[512], knamebuf[1024];
static const char *kname; static const char *kname;
@ -126,18 +126,19 @@ static void memcpy(void *, const void *, int);
static void static void
memcpy(void *dst, const void *src, int len) memcpy(void *dst, const void *src, int len)
{ {
const char *s = src; const char *s = src;
char *d = dst; char *d = dst;
while (len--) while (len--)
*d++ = *s++; *d++ = *s++;
} }
static inline int static inline int
strcmp(const char *s1, const char *s2) strcmp(const char *s1, const char *s2)
{ {
for (; *s1 == *s2 && *s1; s1++, s2++);
return (unsigned char)*s1 - (unsigned char)*s2; for (; *s1 == *s2 && *s1; s1++, s2++);
return (unsigned char)*s1 - (unsigned char)*s2;
} }
#define UFS_SMALL_CGBASE #define UFS_SMALL_CGBASE
@ -146,501 +147,512 @@ strcmp(const char *s1, const char *s2)
static int static int
xfsread(ufs_ino_t inode, void *buf, size_t nbyte) xfsread(ufs_ino_t inode, void *buf, size_t nbyte)
{ {
if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
printf("Invalid %s\n", "format"); if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
return -1; printf("Invalid %s\n", "format");
} return -1;
return 0; }
return 0;
} }
static inline void static inline void
getstr(void) getstr(void)
{ {
char *s; char *s;
int c; int c;
s = cmd; s = cmd;
for (;;) { for (;;) {
switch (c = xgetc(0)) { switch (c = xgetc(0)) {
case 0: case 0:
break; break;
case '\177': case '\177':
case '\b': case '\b':
if (s > cmd) { if (s > cmd) {
s--; s--;
printf("\b \b"); printf("\b \b");
} }
break; break;
case '\n': case '\n':
case '\r': case '\r':
*s = 0; *s = 0;
return; return;
default: default:
if (s - cmd < sizeof(cmd) - 1) if (s - cmd < sizeof(cmd) - 1)
*s++ = c; *s++ = c;
putchar(c); putchar(c);
}
} }
}
} }
static inline void static inline void
putc(int c) putc(int c)
{ {
v86.addr = 0x10;
v86.eax = 0xe00 | (c & 0xff); v86.addr = 0x10;
v86.ebx = 0x7; v86.eax = 0xe00 | (c & 0xff);
v86int(); v86.ebx = 0x7;
v86int();
} }
int int
main(void) main(void)
{ {
uint8_t autoboot; uint8_t autoboot;
ufs_ino_t ino; ufs_ino_t ino;
size_t nbyte; size_t nbyte;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
v86.ctl = V86_FLAGS; v86.ctl = V86_FLAGS;
v86.efl = PSL_RESERVED_DEFAULT | PSL_I; v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
dsk.drive = *(uint8_t *)PTOV(ARGS); dsk.drive = *(uint8_t *)PTOV(ARGS);
dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD; dsk.type = dsk.drive & DRV_HARD ? TYPE_AD : TYPE_FD;
dsk.unit = dsk.drive & DRV_MASK; dsk.unit = dsk.drive & DRV_MASK;
dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1; dsk.slice = *(uint8_t *)PTOV(ARGS + 1) + 1;
bootinfo.bi_version = BOOTINFO_VERSION; bootinfo.bi_version = BOOTINFO_VERSION;
bootinfo.bi_size = sizeof(bootinfo); bootinfo.bi_size = sizeof(bootinfo);
/* Process configuration file */ /* Process configuration file */
autoboot = 1; autoboot = 1;
if ((ino = lookup(PATH_CONFIG)) || if ((ino = lookup(PATH_CONFIG)) ||
(ino = lookup(PATH_DOTCONFIG))) { (ino = lookup(PATH_DOTCONFIG))) {
nbyte = fsread(ino, cmd, sizeof(cmd) - 1); nbyte = fsread(ino, cmd, sizeof(cmd) - 1);
cmd[nbyte] = '\0'; cmd[nbyte] = '\0';
}
if (*cmd) {
memcpy(cmddup, cmd, sizeof(cmd));
if (parse())
autoboot = 0;
if (!OPT_CHECK(RBX_QUIET))
printf("%s: %s", PATH_CONFIG, cmddup);
/* Do not process this command twice */
*cmd = 0;
}
/*
* Try to exec stage 3 boot loader. If interrupted by a keypress,
* or in case of failure, try to load a kernel directly instead.
*/
if (!kname) {
kname = PATH_LOADER;
if (autoboot && !keyhit(3*SECOND)) {
load();
kname = PATH_KERNEL;
} }
}
/* Present the user with the boot2 prompt. */ if (*cmd) {
memcpy(cmddup, cmd, sizeof(cmd));
if (parse())
autoboot = 0;
if (!OPT_CHECK(RBX_QUIET))
printf("%s: %s", PATH_CONFIG, cmddup);
/* Do not process this command twice */
*cmd = 0;
}
for (;;) { /*
if (!autoboot || !OPT_CHECK(RBX_QUIET)) * Try to exec stage 3 boot loader. If interrupted by a keypress,
printf("\nFreeBSD/x86 boot\n" * or in case of failure, try to load a kernel directly instead.
"Default: %u:%s(%u,%c)%s\n" */
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit, if (!kname) {
'a' + dsk.part, kname); kname = PATH_LOADER;
if (DO_SIO) if (autoboot && !keyhit(3*SECOND)) {
sio_flush(); load();
if (!autoboot || keyhit(3*SECOND)) kname = PATH_KERNEL;
getstr(); }
else if (!autoboot || !OPT_CHECK(RBX_QUIET)) }
putchar('\n');
autoboot = 0; /* Present the user with the boot2 prompt. */
if (parse())
putchar('\a'); for (;;) {
else if (!autoboot || !OPT_CHECK(RBX_QUIET))
load(); printf("\nFreeBSD/x86 boot\n"
} "Default: %u:%s(%u,%c)%s\n"
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
'a' + dsk.part, kname);
if (DO_SIO)
sio_flush();
if (!autoboot || keyhit(3*SECOND))
getstr();
else if (!autoboot || !OPT_CHECK(RBX_QUIET))
putchar('\n');
autoboot = 0;
if (parse())
putchar('\a');
else
load();
}
} }
/* XXX - Needed for btxld to link the boot2 binary; do not remove. */ /* XXX - Needed for btxld to link the boot2 binary; do not remove. */
void void
exit(int x) exit(int x)
{ {
} }
static void static void
load(void) load(void)
{ {
union { union {
struct exec ex; struct exec ex;
Elf32_Ehdr eh; Elf32_Ehdr eh;
} hdr; } hdr;
static Elf32_Phdr ep[2]; static Elf32_Phdr ep[2];
static Elf32_Shdr es[2]; static Elf32_Shdr es[2];
caddr_t p; caddr_t p;
ufs_ino_t ino; ufs_ino_t ino;
uint32_t addr; uint32_t addr;
int k; int k;
uint8_t i, j; uint8_t i, j;
if (!(ino = lookup(kname))) { if (!(ino = lookup(kname))) {
if (!ls) if (!ls)
printf("No %s\n", kname); printf("No %s\n", kname);
return;
}
if (xfsread(ino, &hdr, sizeof(hdr)))
return;
if (N_GETMAGIC(hdr.ex) == ZMAGIC) {
addr = hdr.ex.a_entry & 0xffffff;
p = PTOV(addr);
fs_off = PAGE_SIZE;
if (xfsread(ino, p, hdr.ex.a_text))
return;
p += roundup2(hdr.ex.a_text, PAGE_SIZE);
if (xfsread(ino, p, hdr.ex.a_data))
return;
} else if (IS_ELF(hdr.eh)) {
fs_off = hdr.eh.e_phoff;
for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) {
if (xfsread(ino, ep + j, sizeof(ep[0])))
return;
if (ep[j].p_type == PT_LOAD)
j++;
}
for (i = 0; i < 2; i++) {
p = PTOV(ep[i].p_paddr & 0xffffff);
fs_off = ep[i].p_offset;
if (xfsread(ino, p, ep[i].p_filesz))
return; return;
} }
p += roundup2(ep[1].p_memsz, PAGE_SIZE); if (xfsread(ino, &hdr, sizeof(hdr)))
bootinfo.bi_symtab = VTOP(p);
if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
(hdr.eh.e_shstrndx + 1);
if (xfsread(ino, &es, sizeof(es)))
return; return;
for (i = 0; i < 2; i++) {
*(Elf32_Word *)p = es[i].sh_size;
p += sizeof(es[i].sh_size);
fs_off = es[i].sh_offset;
if (xfsread(ino, p, es[i].sh_size))
return;
p += es[i].sh_size;
}
}
addr = hdr.eh.e_entry & 0xffffff;
bootinfo.bi_esymtab = VTOP(p);
} else {
printf("Invalid %s\n", "format");
return;
}
bootinfo.bi_kernelname = VTOP(kname); if (N_GETMAGIC(hdr.ex) == ZMAGIC) {
bootinfo.bi_bios_dev = dsk.drive; addr = hdr.ex.a_entry & 0xffffff;
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK), p = PTOV(addr);
MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part), fs_off = PAGE_SIZE;
0, 0, 0, VTOP(&bootinfo)); if (xfsread(ino, p, hdr.ex.a_text))
return;
p += roundup2(hdr.ex.a_text, PAGE_SIZE);
if (xfsread(ino, p, hdr.ex.a_data))
return;
} else if (IS_ELF(hdr.eh)) {
fs_off = hdr.eh.e_phoff;
for (j = k = 0; k < hdr.eh.e_phnum && j < 2; k++) {
if (xfsread(ino, ep + j, sizeof(ep[0])))
return;
if (ep[j].p_type == PT_LOAD)
j++;
}
for (i = 0; i < 2; i++) {
p = PTOV(ep[i].p_paddr & 0xffffff);
fs_off = ep[i].p_offset;
if (xfsread(ino, p, ep[i].p_filesz))
return;
}
p += roundup2(ep[1].p_memsz, PAGE_SIZE);
bootinfo.bi_symtab = VTOP(p);
if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
(hdr.eh.e_shstrndx + 1);
if (xfsread(ino, &es, sizeof(es)))
return;
for (i = 0; i < 2; i++) {
*(Elf32_Word *)p = es[i].sh_size;
p += sizeof(es[i].sh_size);
fs_off = es[i].sh_offset;
if (xfsread(ino, p, es[i].sh_size))
return;
p += es[i].sh_size;
}
}
addr = hdr.eh.e_entry & 0xffffff;
bootinfo.bi_esymtab = VTOP(p);
} else {
printf("Invalid %s\n", "format");
return;
}
bootinfo.bi_kernelname = VTOP(kname);
bootinfo.bi_bios_dev = dsk.drive;
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&bootinfo));
} }
static int static int
parse() parse()
{ {
char *arg = cmd; char *arg = cmd;
char *ep, *p, *q; char *ep, *p, *q;
const char *cp; const char *cp;
unsigned int drv; unsigned int drv;
int c, i, j; int c, i, j;
size_t k; size_t k;
while ((c = *arg++)) { while ((c = *arg++)) {
if (c == ' ' || c == '\t' || c == '\n') if (c == ' ' || c == '\t' || c == '\n')
continue; continue;
for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
ep = p; ep = p;
if (*p) if (*p)
*p++ = 0; *p++ = 0;
if (c == '-') { if (c == '-') {
while ((c = *arg++)) { while ((c = *arg++)) {
if (c == 'P') { if (c == 'P') {
if (*(uint8_t *)PTOV(0x496) & 0x10) { if (*(uint8_t *)PTOV(0x496) & 0x10) {
cp = "yes"; cp = "yes";
} else { } else {
opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL); opts |= OPT_SET(RBX_DUAL) |
cp = "no"; OPT_SET(RBX_SERIAL);
} cp = "no";
printf("Keyboard: %s\n", cp); }
continue; printf("Keyboard: %s\n", cp);
continue;
#if SERIAL #if SERIAL
} else if (c == 'S') { } else if (c == 'S') {
j = 0; j = 0;
while ((unsigned int)(i = *arg++ - '0') <= 9) while ((u_int)(i = *arg++ - '0') <= 9)
j = j * 10 + i; j = j * 10 + i;
if (j > 0 && i == -'0') { if (j > 0 && i == -'0') {
comspeed = j; comspeed = j;
break; break;
} }
/* Fall through to error below ('S' not in optstr[]). */ /*
* Fall through to error below
* ('S' not in optstr[]).
*/
#endif #endif
} }
for (i = 0; c != optstr[i]; i++) for (i = 0; c != optstr[i]; i++)
if (i == NOPT - 1) if (i == NOPT - 1)
return -1; return -1;
opts ^= OPT_SET(flags[i]); opts ^= OPT_SET(flags[i]);
} }
#if SERIAL #if SERIAL
ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
if (DO_SIO) { if (DO_SIO) {
if (sio_init(115200 / comspeed) != 0) if (sio_init(115200 / comspeed) != 0)
ioctrl &= ~IO_SERIAL; ioctrl &= ~IO_SERIAL;
} }
#endif #endif
} else { } else {
for (q = arg--; *q && *q != '('; q++); for (q = arg--; *q && *q != '('; q++);
if (*q) { if (*q) {
drv = -1; drv = -1;
if (arg[1] == ':') { if (arg[1] == ':') {
drv = *arg - '0'; drv = *arg - '0';
if (drv > 9) if (drv > 9)
return (-1); return (-1);
arg += 2; arg += 2;
}
if (q - arg != 2)
return (-1);
for (i = 0; arg[0] != dev_nm[i][0] ||
arg[1] != dev_nm[i][1]; i++)
if (i == NDEV - 1)
return -1;
dsk.type = i;
arg += 3;
dsk.unit = *arg - '0';
if (arg[1] != ',' || dsk.unit > 9)
return -1;
arg += 2;
dsk.slice = WHOLE_DISK_SLICE;
if (arg[1] == ',') {
dsk.slice = *arg - '0' + 1;
if (dsk.slice > NDOSPART + 1)
return -1;
arg += 2;
}
if (arg[1] != ')')
return -1;
dsk.part = *arg - 'a';
if (dsk.part > 7)
return (-1);
arg += 2;
if (drv == -1)
drv = dsk.unit;
dsk.drive = (dsk.type <= TYPE_MAXHARD
? DRV_HARD : 0) + drv;
dsk_meta = 0;
}
k = ep - arg;
if (k > 0) {
if (k >= sizeof(knamebuf))
return -1;
memcpy(knamebuf, arg, k + 1);
kname = knamebuf;
}
} }
if (q - arg != 2) arg = p;
return -1;
for (i = 0; arg[0] != dev_nm[i][0] ||
arg[1] != dev_nm[i][1]; i++)
if (i == NDEV - 1)
return -1;
dsk.type = i;
arg += 3;
dsk.unit = *arg - '0';
if (arg[1] != ',' || dsk.unit > 9)
return -1;
arg += 2;
dsk.slice = WHOLE_DISK_SLICE;
if (arg[1] == ',') {
dsk.slice = *arg - '0' + 1;
if (dsk.slice > NDOSPART + 1)
return -1;
arg += 2;
}
if (arg[1] != ')')
return -1;
dsk.part = *arg - 'a';
if (dsk.part > 7)
return (-1);
arg += 2;
if (drv == -1)
drv = dsk.unit;
dsk.drive = (dsk.type <= TYPE_MAXHARD
? DRV_HARD : 0) + drv;
dsk_meta = 0;
}
k = ep - arg;
if (k > 0) {
if (k >= sizeof(knamebuf))
return -1;
memcpy(knamebuf, arg, k + 1);
kname = knamebuf;
}
} }
arg = p; return 0;
}
return 0;
} }
static int static int
dskread(void *buf, unsigned lba, unsigned nblk) dskread(void *buf, unsigned lba, unsigned nblk)
{ {
struct dos_partition *dp; struct dos_partition *dp;
struct disklabel *d; struct disklabel *d;
char *sec; char *sec;
unsigned i; unsigned i;
uint8_t sl; uint8_t sl;
const char *reason; const char *reason;
if (!dsk_meta) { if (!dsk_meta) {
sec = dmadat->secbuf; sec = dmadat->secbuf;
dsk.start = 0; dsk.start = 0;
if (drvread(sec, DOSBBSECTOR, 1)) if (drvread(sec, DOSBBSECTOR, 1))
return -1; return -1;
dp = (void *)(sec + DOSPARTOFF); dp = (void *)(sec + DOSPARTOFF);
sl = dsk.slice; sl = dsk.slice;
if (sl < BASE_SLICE) { if (sl < BASE_SLICE) {
for (i = 0; i < NDOSPART; i++) for (i = 0; i < NDOSPART; i++)
if (dp[i].dp_typ == DOSPTYP_386BSD && if (dp[i].dp_typ == DOSPTYP_386BSD &&
(dp[i].dp_flag & 0x80 || sl < BASE_SLICE)) { (dp[i].dp_flag & 0x80 || sl < BASE_SLICE)) {
sl = BASE_SLICE + i; sl = BASE_SLICE + i;
if (dp[i].dp_flag & 0x80 || if (dp[i].dp_flag & 0x80 ||
dsk.slice == COMPATIBILITY_SLICE) dsk.slice == COMPATIBILITY_SLICE)
break; break;
}
if (dsk.slice == WHOLE_DISK_SLICE)
dsk.slice = sl;
}
if (sl != WHOLE_DISK_SLICE) {
if (sl != COMPATIBILITY_SLICE)
dp += sl - BASE_SLICE;
if (dp->dp_typ != DOSPTYP_386BSD) {
reason = "slice";
goto error;
}
dsk.start = dp->dp_start;
}
if (drvread(sec, dsk.start + LABELSECTOR, 1))
return -1;
d = (void *)(sec + LABELOFFSET);
if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
if (dsk.part != RAW_PART) {
reason = "label";
goto error;
}
} else {
if (!dsk.init) {
if (d->d_type == DTYPE_SCSI)
dsk.type = TYPE_DA;
dsk.init++;
}
if (dsk.part >= d->d_npartitions ||
!d->d_partitions[dsk.part].p_size) {
reason = "partition";
goto error;
}
dsk.start += d->d_partitions[dsk.part].p_offset;
dsk.start -= d->d_partitions[RAW_PART].p_offset;
} }
if (dsk.slice == WHOLE_DISK_SLICE)
dsk.slice = sl;
} }
if (sl != WHOLE_DISK_SLICE) { return drvread(buf, dsk.start + lba, nblk);
if (sl != COMPATIBILITY_SLICE)
dp += sl - BASE_SLICE;
if (dp->dp_typ != DOSPTYP_386BSD) {
reason = "slice";
goto error;
}
dsk.start = dp->dp_start;
}
if (drvread(sec, dsk.start + LABELSECTOR, 1))
return -1;
d = (void *)(sec + LABELOFFSET);
if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
if (dsk.part != RAW_PART) {
reason = "label";
goto error;
}
} else {
if (!dsk.init) {
if (d->d_type == DTYPE_SCSI)
dsk.type = TYPE_DA;
dsk.init++;
}
if (dsk.part >= d->d_npartitions ||
!d->d_partitions[dsk.part].p_size) {
reason = "partition";
goto error;
}
dsk.start += d->d_partitions[dsk.part].p_offset;
dsk.start -= d->d_partitions[RAW_PART].p_offset;
}
}
return drvread(buf, dsk.start + lba, nblk);
error: error:
printf("Invalid %s\n", reason); printf("Invalid %s\n", reason);
return -1; return -1;
} }
static void static void
printf(const char *fmt,...) printf(const char *fmt,...)
{ {
va_list ap; va_list ap;
static char buf[10]; static char buf[10];
char *s; char *s;
unsigned u; unsigned u;
int c; int c;
va_start(ap, fmt); va_start(ap, fmt);
while ((c = *fmt++)) { while ((c = *fmt++)) {
if (c == '%') { if (c == '%') {
c = *fmt++; c = *fmt++;
switch (c) { switch (c) {
case 'c': case 'c':
putchar(va_arg(ap, int)); putchar(va_arg(ap, int));
continue; continue;
case 's': case 's':
for (s = va_arg(ap, char *); *s; s++) for (s = va_arg(ap, char *); *s; s++)
putchar(*s); putchar(*s);
continue; continue;
case 'u': case 'u':
u = va_arg(ap, unsigned); u = va_arg(ap, unsigned);
s = buf; s = buf;
do do
*s++ = '0' + u % 10U; *s++ = '0' + u % 10U;
while (u /= 10U); while (u /= 10U);
while (--s >= buf) while (--s >= buf)
putchar(*s); putchar(*s);
continue; continue;
} }
}
putchar(c);
} }
putchar(c); va_end(ap);
} return;
va_end(ap);
return;
} }
static void static void
putchar(int c) putchar(int c)
{ {
if (c == '\n')
xputc('\r'); if (c == '\n')
xputc(c); xputc('\r');
xputc(c);
} }
static int static int
drvread(void *buf, unsigned lba, unsigned nblk) drvread(void *buf, unsigned lba, unsigned nblk)
{ {
static unsigned c = 0x2d5c7c2f; static unsigned c = 0x2d5c7c2f;
if (!OPT_CHECK(RBX_QUIET)) { if (!OPT_CHECK(RBX_QUIET)) {
xputc(c = c << 8 | c >> 24); xputc(c = c << 8 | c >> 24);
xputc('\b'); xputc('\b');
} }
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
v86.addr = XREADORG; /* call to xread in boot1 */ v86.addr = XREADORG; /* call to xread in boot1 */
v86.es = VTOPSEG(buf); v86.es = VTOPSEG(buf);
v86.eax = lba; v86.eax = lba;
v86.ebx = VTOPOFF(buf); v86.ebx = VTOPOFF(buf);
v86.ecx = lba >> 16; v86.ecx = lba >> 16;
v86.edx = nblk << 8 | dsk.drive; v86.edx = nblk << 8 | dsk.drive;
v86int(); v86int();
v86.ctl = V86_FLAGS; v86.ctl = V86_FLAGS;
if (V86_CY(v86.efl)) { if (V86_CY(v86.efl)) {
printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba); printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
return -1; return -1;
} }
return 0; return 0;
} }
static int static int
keyhit(unsigned ticks) keyhit(unsigned ticks)
{ {
uint32_t t0, t1; uint32_t t0, t1;
if (OPT_CHECK(RBX_NOINTR)) if (OPT_CHECK(RBX_NOINTR))
return 0; return 0;
t0 = 0; t0 = 0;
for (;;) { for (;;) {
if (xgetc(1)) if (xgetc(1))
return 1; return 1;
t1 = *(uint32_t *)PTOV(0x46c); t1 = *(uint32_t *)PTOV(0x46c);
if (!t0) if (!t0)
t0 = t1; t0 = t1;
if ((uint32_t)(t1 - t0) >= ticks) if ((uint32_t)(t1 - t0) >= ticks)
return 0; return 0;
} }
} }
static int static int
xputc(int c) xputc(int c)
{ {
if (DO_KBD)
putc(c); if (DO_KBD)
if (DO_SIO) putc(c);
sio_putc(c); if (DO_SIO)
return c; sio_putc(c);
return c;
} }
static int static int
getc(int fn) getc(int fn)
{ {
v86.addr = 0x16;
v86.eax = fn << 8; v86.addr = 0x16;
v86int(); v86.eax = fn << 8;
return fn == 0 ? v86.eax & 0xff : !V86_ZR(v86.efl); v86int();
return fn == 0 ? v86.eax & 0xff : !V86_ZR(v86.efl);
} }
static int static int
xgetc(int fn) xgetc(int fn)
{ {
if (OPT_CHECK(RBX_NOINTR))
return 0; if (OPT_CHECK(RBX_NOINTR))
for (;;) { return 0;
if (DO_KBD && getc(1)) for (;;) {
return fn ? 1 : getc(0); if (DO_KBD && getc(1))
if (DO_SIO && sio_ischar()) return fn ? 1 : getc(0);
return fn ? 1 : sio_getc(); if (DO_SIO && sio_ischar())
if (fn) return fn ? 1 : sio_getc();
return 0; if (fn)
} return 0;
}
} }