#define boot_BSD bsd_startup
#include <lib/libsa/stand.h>
#include <atari_stand.h>
#include <libkern.h>
#include <tosdefs.h>
#include <sys/boot_flag.h>
#include <sys/exec.h>
#include <sys/reboot.h>
#include <machine/cpu.h>
typedef int (*bxxx_t)(void *, void *, struct osdsc *);
int bootxx(void *, void *, int);
void boot_BSD(struct kparamb *) __attribute__((noreturn));
int bootxxx(void *, void *, struct osdsc *);
int load_booter(struct osdsc *);
int usr_info(struct osdsc *);
#define BOOTXXX_MAXSIZE (64 * 1024)
#define HEAPSIZE (64 * 1024)
#define HEAPSTART (LOADADDR3 + BOOTXXX_MAXSIZE)
#define HEAPEND (HEAPSTART + HEAPSIZE)
int
bootxx(void *readsector, void *disklabel, int autoboot)
{
static osdsc_t os_desc;
extern char end[], edata[];
osdsc_t *od = &os_desc;
bxxx_t bootxxx = (bxxx_t)(LOADADDR3);
memset(edata, 0, end - edata);
setheap((void *)HEAPSTART, (void *)HEAPEND);
printf("\033v\nNetBSD/atari secondary bootloader"
" ($Revision: 1.18 $)\n\n");
if (init_dskio(readsector, disklabel, -1))
return -1;
for (;;) {
od->rootfs = 0;
od->osname = "/netbsd";
od->ostype = &od->osname[1];
od->boothowto = (RB_RDONLY);
if (!autoboot) {
int pref;
od->boothowto = (RB_RDONLY|RB_SINGLE);
pref = usr_info(od);
if (pref < 0)
continue;
if (pref > 0)
return pref;
}
autoboot = 0;
if (init_dskio(readsector, disklabel, od->rootfs))
continue;
if (load_booter(od))
continue;
(*bootxxx)(readsector, disklabel, od);
}
}
int
usr_info(osdsc_t *od)
{
static char line[800];
char c, *p = line;
printf("\nEnter os-type [.%s] root-fs [:a] kernel [%s]"
" options [none]:\n\033e", od->ostype, od->osname);
kgets(p, sizeof(line));
printf("\033f");
for (;;) {
while (isspace(*p))
*p++ = '\0';
switch (*p++) {
case '\0':
goto done;
case ':':
if ((c = *p) >= 'a' && c <= 'z')
od->rootfs = c - 'a';
else if (c >= 'A' && c <= 'Z')
od->rootfs = c - ('A' - 27);
else
return -1;
if (!od->rootfs)
break;
*p = 'b';
case '-':
if ((c = *p) == 'a')
od->boothowto &= ~RB_SINGLE;
else if (c == 'b')
od->boothowto |= RB_ASKNAME;
else
BOOT_FLAG(c, od->boothowto);
break;
case '.':
od->ostype = p;
break;
case '/':
od->osname = --p;
break;
default:
return -1;
}
while ((c = *p) && !isspace(c))
p += 1;
}
done:
c = od->ostype[0];
if (isupper(c))
c = tolower(c);
switch (c) {
case 'n':
return 0;
case 'l':
return 0x10;
case 'a':
return 0x40;
case 't':
return 0x80;
default:
return -1;
}
}
int
load_booter(osdsc_t *od)
{
int fd = -1;
u_char *bstart = (u_char *)(LOADADDR3);
int bsize;
char *fname;
char *boot_names[] = {
"/boot.atari",
"/boot",
"/boot.ata",
NULL };
for (fname = boot_names[0]; fname != NULL; fname++) {
if ((fd = open(fname, 0)) < 0)
printf("Cannot open '%s'\n", fname);
else
break;
}
if (fd < 0)
return -1;
while ((bsize = read(fd, bstart, 1024)) > 0) {
bstart += bsize;
}
close(fd);
return 0;
}
void
_rtt(void)
{
printf("Halting...\n");
for (;;)
;
}