summaryrefslogtreecommitdiffstats
path: root/sys/pc98
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1997-08-17 05:13:27 +0000
committerkato <kato@FreeBSD.org>1997-08-17 05:13:27 +0000
commit560fba7fed4b828c2975b9b5f289713de0f5b4b1 (patch)
treed22e4886b8610134718d70e2026940aa385763c5 /sys/pc98
parent88a74fed356a66a6e7fa7ceb5cc947a55bc3346e (diff)
downloadFreeBSD-src-560fba7fed4b828c2975b9b5f289713de0f5b4b1.zip
FreeBSD-src-560fba7fed4b828c2975b9b5f289713de0f5b4b1.tar.gz
Synchronize with foolowing files in sys/i386/boot/netboot:
1.12 Makefile 1.14 bootmenu.c 1.20 main.c 1.3 makerom.c 1.3 misc.c 1.12 netboot.h 1.11 ns8390.c 1.1 ns8390.h 1.3 rpc.c 1.6 start2.S Submitted by: H. Nokubi <h-nokubi@nmit.mt.nec.co.jp>
Diffstat (limited to 'sys/pc98')
-rw-r--r--sys/pc98/boot/netboot/Makefile10
-rw-r--r--sys/pc98/boot/netboot/bootmenu.c143
-rw-r--r--sys/pc98/boot/netboot/main.c148
-rw-r--r--sys/pc98/boot/netboot/makerom.c4
-rw-r--r--sys/pc98/boot/netboot/misc.c169
-rw-r--r--sys/pc98/boot/netboot/netboot.h23
-rw-r--r--sys/pc98/boot/netboot/ns8390.c155
-rw-r--r--sys/pc98/boot/netboot/ns8390.h36
-rw-r--r--sys/pc98/boot/netboot/rpc.c19
-rw-r--r--sys/pc98/boot/netboot/start2.S397
10 files changed, 916 insertions, 188 deletions
diff --git a/sys/pc98/boot/netboot/Makefile b/sys/pc98/boot/netboot/Makefile
index 340df03..19d13af 100644
--- a/sys/pc98/boot/netboot/Makefile
+++ b/sys/pc98/boot/netboot/Makefile
@@ -37,16 +37,14 @@ SRCS= start2.S main.c misc.c bootmenu.c rpc.c
BINDIR= /usr/mdec
BINMODE= 555
-#CFLAGS= -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR} -DASK_BOOT
-CFLAGS= -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR} # -DASK_BOOT
+CFLAGS= -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR} -DASK_BOOT
CFLAGS+= -DPC98
#CFLAGS += -DPCI -DPCI_VENDOR=${PCI_VENDOR} -DPCI_DEVICE=${PCI_DEVICE}
#CFLAGS += -DPCI_CLASS=${PCI_CLASS} -DASK_BOOT
#NS8390= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
-#NS8390= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xD0000
#NS8390= -DINCLUDE_NE
#NS8390+= -DINCLUDE_3COM -D_3COM_BASE=0x300
-NS8390= -DINCLUDE_LGY -DNE_BASE=0xd0
+NS8390= -DINCLUDE_EGY -DNE_BASE=0xd0
CLEANFILES+= netboot.com
CLEANFILES+= makerom start2.ro 3c509.o ns8390.o
LDFLAGS+= -N -T ${RELOCADDR} -e _start -nostdlib
@@ -63,10 +61,10 @@ RELOCADDR=0x90000
${CC} ${CFLAGS} -DBOOTROM -o ${.TARGET} -c ${.IMPSRC}
ns8390.o: ns8390.c
- ${CC} $(CFLAGS) $(NS8390) -o ${.TARGET} -c $<
+ ${CC} ${CFLAGS} $(NS8390) -o ${.TARGET} -c $<
makerom: makerom.c
- ${CC} -o ${.TARGET} -DROMSIZE=${ROMSIZE} ${.CURDIR}/makerom.c
+ ${CC} ${CFLAGS} -o ${.TARGET} -DROMSIZE=${ROMSIZE} ${.CURDIR}/makerom.c
nb8390.rom: makerom start2.ro ${SRCS:N*.h:R:S/$/.o/g} ns8390.o
${LD} ${LDFLAGS} -o ${.TARGET} ${OBJS:S/start2.o/start2.ro/} ns8390.o
diff --git a/sys/pc98/boot/netboot/bootmenu.c b/sys/pc98/boot/netboot/bootmenu.c
index d8f2330..94f8444 100644
--- a/sys/pc98/boot/netboot/bootmenu.c
+++ b/sys/pc98/boot/netboot/bootmenu.c
@@ -40,7 +40,7 @@ struct bootcmds_t {
{"diskboot", exit, " boot from disk"},
{"autoboot", NULL, " continue"},
{"trans", cmd_aui, "<on|off> turn transceiver on|off"},
- {"flags", cmd_flags, "[bcdhsv] set boot flags"},
+ {"flags", cmd_flags, "[bcdghsv] set boot flags"},
{NULL, NULL, NULL}
};
@@ -50,9 +50,9 @@ CMD_HELP - Display help screen
cmd_help()
{
struct bootcmds_t *cmd = bootcmds;
- printf("\r\n");
+ printf("\n");
while (cmd->name) {
- printf("%s %s\n\r",cmd->name,cmd->help);
+ printf("%s %s\n",cmd->name,cmd->help);
cmd++;
}
}
@@ -65,7 +65,7 @@ cmd_ip(p)
{
int i;
if (!setip(p, &arptable[ARP_CLIENT].ipaddr)) {
- printf("IP address is %I\r\n",
+ printf("IP address is %I\n",
arptable[ARP_CLIENT].ipaddr);
} else default_netmask();
}
@@ -86,7 +86,7 @@ cmd_aui(p)
eth_reset();
return(0);
}
- printf ("Transceiver is %s\r\n",aui ? "off" : "on");
+ printf ("Transceiver is %s\n",aui ? "off" : "on");
}
/**************************************************************************
@@ -97,7 +97,7 @@ cmd_gateway(p)
{
int i;
if (!setip(p, &arptable[ARP_GATEWAY].ipaddr)) {
- printf("Server IP address is %I\r\n",
+ printf("Server IP address is %I\n",
arptable[ARP_GATEWAY].ipaddr);
} else /* Need to clear arp entry if we change IP address */
for (i=0; i<6; i++) arptable[ARP_GATEWAY].node[i] = 0;
@@ -111,7 +111,7 @@ cmd_server(p)
{
int i;
if (!setip(p, &arptable[ARP_SERVER].ipaddr)) {
- printf("Server IP address is %I\r\n",
+ printf("Server IP address is %I\n",
arptable[ARP_SERVER].ipaddr);
} else /* Need to clear arp entry if we change IP address */
for (i=0; i<6; i++) arptable[ARP_SERVER].node[i] = 0;
@@ -126,7 +126,7 @@ cmd_netmask(p)
int i;
if (!setip(p, &netmask)) {
netmask = ntohl(netmask);
- printf("netmask is %I\r\n", netmask);
+ printf("netmask is %I\n", netmask);
}
netmask = htonl(netmask);
}
@@ -139,7 +139,7 @@ cmd_swapsize(p)
{
int blks = getdec(&p);
if (blks > 0) nfsdiskless.swap_nblks = blks;
- else printf("Swap size is: %d blocks\r\n",nfsdiskless.swap_nblks);
+ else printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks);
}
extern char kernel_buf[], *kernel;
@@ -150,7 +150,7 @@ cmd_kernel(p)
char *p;
{
if (*p) sprintf(kernel = kernel_buf,"%s",p);
- printf("Bootfile is: %s\r\n", kernel);
+ printf("Bootfile is: %s\n", kernel);
}
@@ -161,7 +161,7 @@ cmd_rootfs(p)
char *p;
{
if (!setip(p, &arptable[ARP_ROOTSERVER].ipaddr)) {
- printf("Root filesystem is %I:%s\r\n",
+ printf("Root filesystem is %I:%s\n",
nfsdiskless.root_saddr.sin_addr,
nfsdiskless.root_hostnam);
} else {
@@ -180,7 +180,7 @@ cmd_swapfs(p)
char *p;
{
if (!setip(p, &arptable[ARP_SWAPSERVER].ipaddr)) {
- printf("Swap filesystem is %I:%s\r\n",
+ printf("Swap filesystem is %I:%s\n",
nfsdiskless.swap_saddr.sin_addr,
nfsdiskless.swap_hostnam);
} else {
@@ -201,47 +201,57 @@ cmd_hostname(p)
if (*p)
hostnamelen = ((sprintf(&nfsdiskless.my_hostnam,"%s",p) -
(char*)&nfsdiskless.my_hostnam) + 3) & ~3;
- else printf("Hostname is: %s\r\n",nfsdiskless.my_hostnam);
+ else printf("Hostname is: %s\n",nfsdiskless.my_hostnam);
}
+
+static void mountopts(prefix,args,p)
+ char *prefix;
+ struct onfs_args *args;
+ char *p;
+{
+ char *tmp;
+
+ if (*p) {
+ args->flags = NFSMNT_RSIZE | NFSMNT_WSIZE | NFSMNT_RESVPORT;
+ args->sotype = SOCK_DGRAM;
+ if ((tmp = (char *)substr(p,"rsize=")))
+ args->rsize=getdec(&tmp);
+ if ((tmp = (char *)substr(p,"wsize=")))
+ args->wsize=getdec(&tmp);
+ if ((tmp = (char *)substr(p,"intr")))
+ args->flags |= NFSMNT_INT;
+ if ((tmp = (char *)substr(p,"soft")))
+ args->flags |= NFSMNT_SOFT;
+ if ((tmp = (char *)substr(p,"noconn")))
+ args->flags |= NFSMNT_NOCONN;
+ if ((tmp = (char *)substr(p, "tcp")))
+ args->sotype = SOCK_STREAM;
+ } else {
+ printf("%s mount options: rsize=%d,wsize=%d,resvport",
+ prefix,
+ args->rsize,
+ args->wsize);
+ if (args->flags & NFSMNT_INT)
+ printf (",intr");
+ if (args->flags & NFSMNT_SOFT)
+ printf (",soft");
+ if (args->flags & NFSMNT_NOCONN)
+ printf (",noconn");
+ if (args->sotype == SOCK_STREAM)
+ printf (",tcp");
+ else
+ printf (",udp");
+ printf ("\n");
+ }
+}
+
/**************************************************************************
CMD_ROOTOPTS - Set root mount options
**************************************************************************/
cmd_rootopts(p)
char *p;
{
- char *tmp;
-
- if (*p) {
- nfsdiskless.root_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
- nfsdiskless.root_args.sotype = SOCK_DGRAM;
- if ((tmp = (char *)substr(p,"rsize=")))
- nfsdiskless.root_args.rsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"wsize=")))
- nfsdiskless.root_args.wsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"resvport")))
- nfsdiskless.root_args.flags |= NFSMNT_RESVPORT;
- if ((tmp = (char *)substr(p,"intr")))
- nfsdiskless.root_args.flags |= NFSMNT_INT;
- if ((tmp = (char *)substr(p,"soft")))
- nfsdiskless.root_args.flags |= NFSMNT_SOFT;
- if ((tmp = (char *)substr(p, "tcp")))
- nfsdiskless.root_args.sotype = SOCK_STREAM;
- } else {
- printf("Rootfs mount options: rsize=%d,wsize=%d",
- nfsdiskless.root_args.rsize,
- nfsdiskless.root_args.wsize);
- if (nfsdiskless.root_args.flags & NFSMNT_RESVPORT)
- printf (",resvport");
- if (nfsdiskless.root_args.flags & NFSMNT_SOFT)
- printf (",soft");
- if (nfsdiskless.root_args.flags & NFSMNT_INT)
- printf (",intr");
- if (nfsdiskless.root_args.sotype == SOCK_STREAM)
- printf (",tcp");
- else
- printf (",udp");
- printf ("\r\n");
- }
+ mountopts("Rootfs",&nfsdiskless.root_args,p);
}
/**************************************************************************
@@ -250,39 +260,7 @@ CMD_SWAPOPTS - Set swap mount options
cmd_swapopts(p)
char *p;
{
- char *tmp;
-
- if (*p) {
- nfsdiskless.swap_args.flags = NFSMNT_RSIZE | NFSMNT_WSIZE;
- nfsdiskless.swap_args.sotype = SOCK_DGRAM;
- if ((tmp = (char *)substr(p,"rsize=")))
- nfsdiskless.swap_args.rsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"wsize=")))
- nfsdiskless.swap_args.wsize=getdec(&tmp);
- if ((tmp = (char *)substr(p,"resvport")))
- nfsdiskless.swap_args.flags |= NFSMNT_RESVPORT;
- if ((tmp = (char *)substr(p,"intr")))
- nfsdiskless.swap_args.flags |= NFSMNT_INT;
- if ((tmp = (char *)substr(p,"soft")))
- nfsdiskless.swap_args.flags |= NFSMNT_SOFT;
- if ((tmp = (char *)substr(p, "tcp")))
- nfsdiskless.swap_args.sotype = SOCK_STREAM;
- } else {
- printf("Swapfs mount options: rsize=%d,wsize=%d",
- nfsdiskless.swap_args.rsize,
- nfsdiskless.swap_args.wsize);
- if (nfsdiskless.swap_args.flags & NFSMNT_RESVPORT)
- printf (",resvport");
- if (nfsdiskless.swap_args.flags & NFSMNT_SOFT)
- printf (",soft");
- if (nfsdiskless.swap_args.flags & NFSMNT_INT)
- printf (",intr");
- if (nfsdiskless.swap_args.sotype == SOCK_STREAM)
- printf (",tcp");
- else
- printf (",udp");
- printf ("\r\n");
- }
+ mountopts("Swapfs",&nfsdiskless.swap_args,p);
}
/**************************************************************************
@@ -299,6 +277,7 @@ cmd_flags(buf)
case 'b': flags |= RB_HALT; break;
case 'c': flags |= RB_CONFIG; break;
case 'd': flags |= RB_KDB; break;
+ case 'g': flags |= RB_GDB; break;
case 'h': flags ^= RB_SERIAL; break;
case 's': flags |= RB_SINGLE; break;
case 'v': flags |= RB_VERBOSE; break;
@@ -337,7 +316,7 @@ execute(buf)
} else
cmd++;
}
- printf("bad command - type 'help' for list\n\r");
+ printf("bad command - type 'help' for list\n");
return(0);
}
@@ -348,7 +327,7 @@ bootmenu()
{
char cmd[80];
int ptr, c;
- printf("\r\n");
+ printf("\n");
while (1) {
ptr = 0;
printf("boot> ");
@@ -367,7 +346,7 @@ bootmenu()
}
}
cmd[ptr] = 0;
- printf("\r\n");
+ printf("\n");
if (execute(cmd)) break;
}
eth_reset();
diff --git a/sys/pc98/boot/netboot/main.c b/sys/pc98/boot/netboot/main.c
index 2ae5c6e..0ef141e 100644
--- a/sys/pc98/boot/netboot/main.c
+++ b/sys/pc98/boot/netboot/main.c
@@ -37,12 +37,11 @@ MAIN - Kick off routine
main()
{
int c;
- char *p;
extern char edata[], end[];
- for (p=edata; p<end; p++) *p = 0; /* Zero BSS */
+ bzero(edata,end-edata); /* Zero BSS */
#ifdef ASK_BOOT
while (1) {
- printf("\n\rBoot from Network (Y/N) ? ");
+ printf("\nBoot from Network (Y/N) ? ");
c = getchar();
if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
if (c == '\r') break;
@@ -51,18 +50,31 @@ main()
exit(0);
if (c == 'Y')
break;
- printf(" - bad response\n\r");
+ printf(" - bad response\n");
}
#endif
+
+ /* get the bios's idea about the disks geometry */
+#ifdef PC98
+ for(c = 0; c < 2; c ++) {
+ if (*(unsigned char*)0xa155d & (1 << c)) { /* check DISK_EQUIP */
+ bootinfo.bi_bios_geom[c] = get_diskinfo(c + 0x80);
+ }
+ }
+#else /* IBM-PC */
+ for(c = 0; c < N_BIOS_GEOM; c ++)
+ bootinfo.bi_bios_geom[c] = get_diskinfo(c + 0x80);
+#endif /* PC98 */
+
gateA20();
#ifdef PC98
/* set machine type to PC98_SYSTEM_PARAMETER */
- /* machine_check(); */
+ machine_check();
#endif
- printf("\r\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n\r");
- printf("\r\nSearching for adapter...");
+ printf("\nBOOTP/TFTP/NFS bootstrap loader ESC for menu\n"
+ "\nSearching for adapter...");
if (!eth_probe()) {
- printf("No adapter found.\r\n");
+ printf("No adapter found.\n");
exit(0);
}
kernel = DEFAULT_BOOTFILE;
@@ -110,8 +122,10 @@ load()
char cmd_line[80];
int err, read_size, i;
long addr, broadcast;
+ int swsize;
unsigned long pad;
+ config_buffer[0]='\0'; /* clear; bootp might fill this up */
/* Initialize this early on */
nfsdiskless.root_args.rsize = 8192;
@@ -119,20 +133,22 @@ load()
nfsdiskless.swap_args.rsize = 8192;
nfsdiskless.swap_args.wsize = 8192;
nfsdiskless.root_args.sotype = SOCK_DGRAM;
- nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE);
+ nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE |
+ NFSMNT_RESVPORT);
nfsdiskless.swap_args.sotype = SOCK_DGRAM;
- nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE);
+ nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE |
+ NFSMNT_RESVPORT);
/* Find a server to get BOOTP reply from */
if (!arptable[ARP_CLIENT].ipaddr || !arptable[ARP_SERVER].ipaddr) {
- printf("\r\nSearching for server...\r\n");
+ printf("\nSearching for server...\n");
if (!bootp()) {
- printf("No Server found.\r\n");
+ printf("No Server found.\n");
longjmp(jmp_bootmenu,1);
}
}
- printf("My IP %I, Server IP %I, GW IP %I\r\n",
+ printf("My IP %I, Server IP %I, GW IP %I\n",
arptable[ARP_CLIENT].ipaddr,
arptable[ARP_SERVER].ipaddr,
arptable[ARP_GATEWAY].ipaddr);
@@ -141,6 +157,10 @@ load()
printf("\n=>>"); getchar();
#endif
+ /*** check if have got info from bootp ***/
+ if (config_buffer[0])
+ goto cfg_done;
+#ifndef NO_TFTP
/* Now use TFTP to load configuration file */
sprintf(cfg,"/tftpboot/freebsd.%I",arptable[ARP_CLIENT].ipaddr);
if (tftp(cfg) || tftp(cfg+10))
@@ -151,9 +171,11 @@ load()
sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr);
if (tftp(cfg) || tftp(cfg+10))
goto cfg_done;
+#endif
+ /* not found; using default values... */
sprintf(config_buffer,"rootfs %I:/usr/diskless_root",
arptable[ARP_SERVER].ipaddr);
- printf("Unable to load config file, guessing:\r\n\t%s\r\n",
+ printf("Unable to load config file, guessing:\n\t%s\n",
config_buffer);
cfg_done:
@@ -166,7 +188,7 @@ cfg_done:
q = cmd_line;
while ((*p != '\n') && (*p)) *(q++) = *(p++);
*q = 0;
- printf("%s\r\n",cmd_line);
+ printf("%s\n",cmd_line);
execute(cmd_line);
if (*p) p++;
}
@@ -177,7 +199,7 @@ cfg_done:
/* Check to make sure we've got a rootfs */
if (!arptable[ARP_ROOTSERVER].ipaddr) {
- printf("No ROOT filesystem server!\r\n");
+ printf("No ROOT filesystem server!\n");
longjmp(jmp_bootmenu,1);
}
@@ -211,7 +233,7 @@ cfg_done:
swap_nfs_port = rpclookup(ARP_SWAPSERVER, PROG_NFS, 2);
swap_mount_port = rpclookup(ARP_SWAPSERVER, PROG_MOUNT, 1);
if ((swap_nfs_port == -1) || (swap_mount_port == -1)) {
- printf("Unable to get SWAP NFS/MOUNT ports\r\n");
+ printf("Unable to get SWAP NFS/MOUNT ports\n");
longjmp(jmp_bootmenu,1);
}
if (err = nfs_mount(ARP_SWAPSERVER, swap_mount_port,
@@ -222,11 +244,15 @@ cfg_done:
}
sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr);
if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port,
- &swapfs_fh, swapfile, &nfsdiskless.swap_fh)) {
+ &swapfs_fh, swapfile, &nfsdiskless.swap_fh, &swsize)) {
printf("Unable to open %s: ",swapfile);
nfs_err(err);
longjmp(jmp_bootmenu,1);
}
+ if (!nfsdiskless.swap_nblks) {
+ nfsdiskless.swap_nblks = swsize / 1024;
+ printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks);
+ }
nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in);
nfsdiskless.swap_saddr.sin_family = AF_INET;
nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port);
@@ -240,7 +266,7 @@ cfg_done:
root_nfs_port = rpclookup(ARP_ROOTSERVER, PROG_NFS, 2);
root_mount_port = rpclookup(ARP_ROOTSERVER, PROG_MOUNT, 1);
if ((root_nfs_port == -1) || (root_mount_port == -1)) {
- printf("Unable to get ROOT NFS/MOUNT ports\r\n");
+ printf("Unable to get ROOT NFS/MOUNT ports\n");
longjmp(jmp_bootmenu,1);
}
if (err = nfs_mount(ARP_ROOTSERVER, root_mount_port,
@@ -260,14 +286,14 @@ cfg_done:
if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port,
&nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel,
- &kernel_handle)) {
+ &kernel_handle, NULL)) {
printf("Unable to open %s: ",kernel);
nfs_err(err);
longjmp(jmp_bootmenu,1);
}
/* Load the kernel using NFS */
- printf("Loading %s...\r\n",kernel);
+ printf("Loading %s...\n",kernel);
if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, &kernel_handle, 0,
sizeof(struct exec), &head)) < 0) {
printf("Unable to read %s: ",kernel);
@@ -275,12 +301,15 @@ cfg_done:
longjmp(jmp_bootmenu,1);
}
if (N_BADMAG(head)) {
- printf("Bad executable format!\r\n");
+ printf("Bad executable format!\n");
longjmp(jmp_bootmenu, 1);
}
loadpoint = (char *)0x100000;
offset = N_TXTOFF(head);
printf("text=0x%X, ",head.a_text);
+#ifdef PC98
+ set_twiddle_max(8);
+#endif
nfsload(head.a_text);
while (((int)loadpoint) & PAGE_MASK)
*(loadpoint++) = 0;
@@ -312,7 +341,7 @@ cfg_done:
nfsload(i);
bootinfo.bi_esymtab = (int) loadpoint;
- printf("entry=0x%X.\n\r",head.a_entry);
+ printf("entry=0x%X.\n",head.a_entry);
/* Jump to kernel */
bootinfo.bi_version = BOOTINFO_VERSION;
@@ -393,19 +422,19 @@ udp_transmit(destip, srcsock, destsock, len, buf)
printf("%I is not in my arp table!\n");
return(0);
}
- for (i = 0; i<ETHER_ADDR_SIZE; i++)
+ for (i = 0; i<ETHER_ADDR_LEN; i++)
if (arptable[arpentry].node[i]) break;
- if (i == ETHER_ADDR_SIZE) { /* Need to do arp request */
+ if (i == ETHER_ADDR_LEN) { /* Need to do arp request */
arpreq.hwtype = htons(1);
arpreq.protocol = htons(IP);
- arpreq.hwlen = ETHER_ADDR_SIZE;
+ arpreq.hwlen = ETHER_ADDR_LEN;
arpreq.protolen = 4;
arpreq.opcode = htons(ARP_REQUEST);
bcopy(arptable[ARP_CLIENT].node, arpreq.shwaddr,
- ETHER_ADDR_SIZE);
+ ETHER_ADDR_LEN);
convert_ipaddr(arpreq.sipaddr,
&arptable[ARP_CLIENT].ipaddr);
- bzero(arpreq.thwaddr, ETHER_ADDR_SIZE);
+ bzero(arpreq.thwaddr, ETHER_ADDR_LEN);
convert_ipaddr(arpreq.tipaddr, &destip);
while (retry--) {
eth_transmit(broadcast, ARP, sizeof(arpreq),
@@ -433,7 +462,7 @@ tftp(name)
unsigned short len, block=1;
struct tftp_t tp;
int code;
- printf("Loading %s...\r\n",name);
+ printf("Loading %s...\n",name);
isocket++;
tp.opcode = htons(TFTP_RRQ);
len = (sprintf((char *)tp.u.rrq,"%s%c%s",name,0,"octet")
@@ -442,9 +471,9 @@ tftp(name)
if (!udp_transmit(arptable[ARP_SERVER].ipaddr, isocket, osocket,
len, &tp)) return(0);
if (await_reply(AWAIT_TFTP, isocket, NULL)) {
- tr = (struct tftp_t *)&packet[ETHER_HDR_SIZE];
+ tr = (struct tftp_t *)&packet[ETHER_HDR_LEN];
if (tr->opcode == ntohs(TFTP_ERROR)) {
- printf("TFTP error %d (%s)\r\n",
+ printf("TFTP error %d (%s)\n",
ntohs(tr->u.err.errcode),
tr->u.err.errmsg);
return(0);
@@ -456,7 +485,7 @@ tftp(name)
osocket, TFTP_MIN_PACKET_SIZE, &tp);
len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
if (len >= 512) {
- printf("Config file too large.\r\n");
+ printf("Config file too large.\n");
config_buffer[0] = 0;
return(0);
} else {
@@ -480,9 +509,9 @@ bootp()
bzero(&bp, sizeof(struct bootp_t));
bp.bp_op = BOOTP_REQUEST;
bp.bp_htype = 1;
- bp.bp_hlen = ETHER_ADDR_SIZE;
+ bp.bp_hlen = ETHER_ADDR_LEN;
bp.bp_xid = starttime = currticks();
- bcopy(arptable[ARP_CLIENT].node, bp.bp_hwaddr, ETHER_ADDR_SIZE);
+ bcopy(arptable[ARP_CLIENT].node, bp.bp_hwaddr, ETHER_ADDR_LEN);
while(retry--) {
udp_transmit(IP_BROADCAST, 0, BOOTP_SERVER,
sizeof(struct bootp_t), &bp);
@@ -508,7 +537,7 @@ await_reply(type, ival, ptr)
struct bootp_t *bootpreply;
struct rpc_t *rpc;
- int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
+ int protohdrlen = ETHER_HDR_LEN + sizeof(struct iphdr) +
sizeof(struct udphdr);
time = currticks() + TIMEOUT;
while(time > currticks()) {
@@ -516,16 +545,16 @@ await_reply(type, ival, ptr)
if (eth_poll()) { /* We have something! */
/* Check for ARP - No IP hdr */
if ((type == AWAIT_ARP) &&
- (packetlen >= ETHER_HDR_SIZE +
+ (packetlen >= ETHER_HDR_LEN +
sizeof(struct arprequest)) &&
(((packet[12] << 8) | packet[13]) == ARP)) {
arpreply = (struct arprequest *)
- &packet[ETHER_HDR_SIZE];
+ &packet[ETHER_HDR_LEN];
if ((arpreply->opcode == ntohs(ARP_REPLY)) &&
bcompare(arpreply->sipaddr, ptr, 4)) {
bcopy(arpreply->shwaddr,
arptable[ival].node,
- ETHER_ADDR_SIZE);
+ ETHER_ADDR_LEN);
return(1);
}
continue;
@@ -534,17 +563,17 @@ await_reply(type, ival, ptr)
/* Anything else has IP header */
if ((packetlen < protohdrlen) ||
(((packet[12] << 8) | packet[13]) != IP)) continue;
- ip = (struct iphdr *)&packet[ETHER_HDR_SIZE];
+ ip = (struct iphdr *)&packet[ETHER_HDR_LEN];
if ((ip->verhdrlen != 0x45) ||
ipchksum(ip, sizeof(struct iphdr)) ||
(ip->protocol != IP_UDP)) continue;
- udp = (struct udphdr *)&packet[ETHER_HDR_SIZE +
+ udp = (struct udphdr *)&packet[ETHER_HDR_LEN +
sizeof(struct iphdr)];
/* BOOTP ? */
- bootpreply = (struct bootp_t *)&packet[ETHER_HDR_SIZE];
+ bootpreply = (struct bootp_t *)&packet[ETHER_HDR_LEN];
if ((type == AWAIT_BOOTP) &&
- (packetlen >= (ETHER_HDR_SIZE +
+ (packetlen >= (ETHER_HDR_LEN +
sizeof(struct bootp_t))) &&
(ntohs(udp->dest) == BOOTP_CLIENT) &&
(bootpreply->bp_op == BOOTP_REPLY)) {
@@ -554,11 +583,11 @@ await_reply(type, ival, ptr)
convert_ipaddr(&arptable[ARP_SERVER].ipaddr,
bootpreply->bp_siaddr);
bzero(arptable[ARP_SERVER].node,
- ETHER_ADDR_SIZE); /* Kill arp */
+ ETHER_ADDR_LEN); /* Kill arp */
convert_ipaddr(&arptable[ARP_GATEWAY].ipaddr,
bootpreply->bp_giaddr);
bzero(arptable[ARP_GATEWAY].node,
- ETHER_ADDR_SIZE); /* Kill arp */
+ ETHER_ADDR_LEN); /* Kill arp */
if (bootpreply->bp_file[0]) {
bcopy(bootpreply->bp_file,
kernel_buf, 128);
@@ -573,7 +602,7 @@ await_reply(type, ival, ptr)
(ntohs(udp->dest) == ival)) return(1);
/* RPC */
- rpc = (struct rpc_t *)&packet[ETHER_HDR_SIZE];
+ rpc = (struct rpc_t *)&packet[ETHER_HDR_LEN];
if ((type == AWAIT_RPC) &&
(ntohs(udp->dest) == RPC_SOCKET) &&
(ntohl(rpc->u.reply.id) == ival) &&
@@ -586,6 +615,17 @@ await_reply(type, ival, ptr)
return(0);
}
+void
+bootp_string(char *name, char *bootp_ptr)
+{
+ char tmp_buf[512]; /* oversized, but who cares ! */
+ bzero(tmp_buf, sizeof(tmp_buf));
+ bcopy(bootp_ptr+2, tmp_buf, TAG_LEN(bootp_ptr));
+ sprintf(config_buffer+strlen(config_buffer),
+ "%s %s\n", name, tmp_buf);
+}
+
+
/**************************************************************************
DECODE_RFC1048 - Decodes RFC1048 header
**************************************************************************/
@@ -615,11 +655,27 @@ decode_rfc1048(p)
bcopy(p+2, &nfsdiskless.my_hostnam, TAG_LEN(p));
hostnamelen = (TAG_LEN(p) + 3) & ~3;
break;
+ case RFC1048_ROOT_PATH: /* XXX check len */
+ bootp_string("rootfs", p);
+ break;
+ case RFC1048_SWAP_PATH:
+ bootp_string("swapfs", p);
+ break;
+ case RFC1048_SWAP_LEN: /* T129 */
+ sprintf(config_buffer+strlen(config_buffer),
+ "swapsize %d\n", ntohl(*(long *)(p+2)) );
+ break;
+ case 130: /* root mount options */
+ bootp_string("rootopts", p);
+ break;
+ case 131: /* swap mount options */
+ bootp_string("swapopts", p);
+ break;
default:
printf("Unknown RFC1048-tag ");
for(q=p;q<p+2+TAG_LEN(p);q++)
printf("%x ",*q);
- printf("\n\r");
+ printf("\n");
}
p += TAG_LEN(p) + 2;
}
diff --git a/sys/pc98/boot/netboot/makerom.c b/sys/pc98/boot/netboot/makerom.c
index 715e9b7..b5b1008 100644
--- a/sys/pc98/boot/netboot/makerom.c
+++ b/sys/pc98/boot/netboot/makerom.c
@@ -36,9 +36,9 @@ main(argc,argv)
for (i=0,sum=0; i<ROMSIZE; i++)
sum += rom[i];
rom[5] = -sum;
- for (i=0,sum=0; i<ROMSIZE; i++);
+ for (i=0,sum=0; i<ROMSIZE; i++)
sum += rom[i];
- if (sum)
+ if (sum & 0x00FF)
printf("checksum fails.\n");
if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
perror("unable to seek");
diff --git a/sys/pc98/boot/netboot/misc.c b/sys/pc98/boot/netboot/misc.c
index 8c7be73..a2c863e 100644
--- a/sys/pc98/boot/netboot/misc.c
+++ b/sys/pc98/boot/netboot/misc.c
@@ -3,7 +3,11 @@ MISC Support Routines
**************************************************************************/
#include "netboot.h"
-
+#ifdef PC98
+#include "../../pc98/pc98.h"
+void putchar(int c);
+void putc(int c);
+#endif
#define NO_SWITCH /* saves space */
/**************************************************************************
@@ -288,3 +292,166 @@ gateA20()
#endif IBM_L40
#endif
}
+
+#ifdef PC98
+void
+putchar(int c)
+{
+ if (c == '\n')
+ putc('\r');
+ putc(c);
+}
+
+static unsigned short *Crtat = (unsigned short *)0;
+static int row;
+static int col;
+
+void putc(int c)
+{
+ static unsigned short *crtat;
+ unsigned char sys_type;
+ unsigned short *cp;
+ int i, pos;
+
+ if (Crtat == 0) {
+ sys_type = *(unsigned char *)0x0a1501/*0x11501*/;
+ if (sys_type & 0x08) {
+ Crtat = (unsigned short *)0x0e0000/*0x50000*/;
+ crtat = Crtat;
+ row = 31;
+ col = 80;
+ } else {
+ Crtat = (unsigned short *)0x0a0000/*0x10000*/;
+ crtat = Crtat;
+ row = 25;
+ col = 80;
+ }
+ }
+
+ switch(c) {
+ case '\t':
+ do {
+ putc(' ');
+ } while ((int)crtat % 16);
+ break;
+ case '\b':
+ crtat--;
+ break;
+ case '\r':
+ crtat -= (crtat - Crtat) % col;
+ break;
+ case '\n':
+ crtat += col;
+ break;
+ default:
+ *crtat = (c == 0x5c ? 0xfc : c);
+ *(crtat++ + 0x1000) = 0xe1;
+ break;
+ }
+
+ if (crtat >= Crtat + col * row) {
+ for (i = 1; i < row; i++)
+ bcopy(Crtat+col*i, Crtat+col*(i-1), col*2);
+ for (i = 0, cp = Crtat + col * (row - 1); i < col*2; i++) {
+ *cp++ = ' ';
+ }
+ crtat -= col;
+ }
+ pos = crtat - Crtat;
+ while((inb(0x60) & 0x04) == 0) {}
+ outb(0x62, 0x49);
+ outb(0x60, pos & 0xff);
+ outb(0x60, pos >> 8);
+}
+
+unsigned int bios98getdate();
+
+unsigned int currticks()
+{
+ unsigned int biostime = bios98getdate() >> 8;
+ unsigned int time;
+ static unsigned int oldtime;
+ time = (( (biostime >> 4) & 0x0f)*10
+ + (biostime & 0x0f))*3600 /* hour */
+ + (((biostime >> 12) & 0x0f)*10
+ + ((biostime >> 8) & 0x0f))*60 /* minute */
+ + (((biostime >> 20) & 0x0f)*10
+ + ((biostime >> 16) & 0x0f)); /* second */
+ while(oldtime > time)
+ time += 24*3600;
+ oldtime = time;
+ return time*20;
+}
+
+void machine_check(void)
+{
+ int ret;
+ int i;
+ int data = 0;
+ u_char epson_machine_id = *(unsigned char *)(0x0a1624/*0x11624*/);
+
+ /* PC98_SYSTEM_PARAMETER(0x501) */
+ ret = ((*(unsigned char*)0x0a1501/*0x11501*/) & 0x08) >> 3;
+
+ /* wait V-SYNC */
+ while (inb(0x60) & 0x20) {}
+ while (!(inb(0x60) & 0x20)) {}
+
+ /* ANK 'A' font */
+ outb(0xa1, 0x00);
+ outb(0xa3, 0x41);
+
+ if (ret & M_NORMAL) {
+ /* M_NORMAL, use CG window (all NEC OK) */
+ /* sum */
+ for (i = 0; i < 4; i++) {
+ data += *((unsigned long*)0x0a4000/*0x14000*/ + i);/* 0xa4000 */
+ }
+ if (data == 0x6efc58fc) { /* DA data */
+ ret |= M_NEC_PC98;
+ } else {
+ ret |= M_EPSON_PC98;
+ }
+ ret |= (inb(0x42) & 0x20) ? M_8M : 0;
+ } else {
+ /* M_HIGHRESO, use CG window */
+ /* sum */
+ for (i = 0; i < 12; i++) {
+ data += *((unsigned long*)0x0e4000/*0x54000*/ + i); /* 0xe4000 */
+ }
+ if ( data == 0x50154624) { /* XA data */
+ ret |= M_NEC_PC98;
+ } else {
+ ret |= M_EPSON_PC98;
+ }
+ ret |= (inb(0x63) & 0x01) ? M_8M : 0;
+ }
+
+ /* PC98_SYSTEM_PARAMETER(0x400) */
+ if ((*(unsigned char*)0xa1400/*0x11400*/) & 0x80) {
+ ret |= M_NOTE;
+ }
+ if (ret & M_NEC_PC98) {
+ /* PC98_SYSTEM_PARAMETER(0x458) */
+ if ((*(unsigned char*)0x0a1458/*0x11458*/) & 0x80) {
+ ret |= M_H98;
+ } else {
+ ret |= M_NOT_H98;
+ }
+ } else {
+ ret |= M_NOT_H98;
+ switch (epson_machine_id) {
+ case 0x20: /* note A */
+ case 0x22: /* note W */
+ case 0x27: /* note AE */
+ case 0x2a: /* note WR */
+ /*case 0x2: /* note AR */
+ ret |= M_NOTE;
+ break;
+ default:
+ break;
+ }
+ }
+ (*(unsigned long *)(0x0a1620/*0x11620*/)) = ret;
+}
+#endif
diff --git a/sys/pc98/boot/netboot/netboot.h b/sys/pc98/boot/netboot/netboot.h
index 7f724e6..0e922b7 100644
--- a/sys/pc98/boot/netboot/netboot.h
+++ b/sys/pc98/boot/netboot/netboot.h
@@ -13,9 +13,13 @@ Author: Martin Renters
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/mount.h>
+#include <sys/time.h>
+#include <net/ethernet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <nfs/nfsv2.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfs.h>
#include <nfs/nfsdiskless.h>
#include <machine/bootinfo.h>
#include <machine/cpufunc.h>
@@ -53,11 +57,6 @@ Author: Martin Renters
#define TRUE 1
#define FALSE 0
-#define ETHER_ADDR_SIZE 6 /* Size of Ethernet address */
-#define ETHER_HDR_SIZE 14 /* Size of ethernet header */
-#define ETH_MIN_PACKET 64
-#define ETH_MAX_PACKET 1518
-
#define VENDOR_NONE 0
#define VENDOR_WD 1
#define VENDOR_NOVELL 2
@@ -99,10 +98,20 @@ Author: Martin Renters
#define RFC1048_COOKIE { 99, 130, 83, 99 }
#define RFC1048_PAD 0
#define RFC1048_NETMASK 1
+#define RFC1048_TIME_OFFSET 2
#define RFC1048_GATEWAY 3
+#define RFC1048_TIME_SERVER 4
+#define RFC1048_NAME_SERVER 5
+#define RFC1048_DOMAIN_SERVER 6
#define RFC1048_HOSTNAME 12
+#define RFC1048_BOOT_SIZE 12 /* XXX */
+#define RFC1048_SWAP_SERVER 16
+#define RFC1048_ROOT_PATH 17
+#define RFC1048_SWAP_PATH 128 /* T128 */
+#define RFC1048_SWAP_LEN 129 /* T129 */
+
#define RFC1048_END 255
-#define BOOTP_VENDOR_LEN 64
+#define BOOTP_VENDOR_LEN 256
#define TFTP_RRQ 1
#define TFTP_WRQ 2
@@ -191,7 +200,7 @@ struct bootp_t {
char bp_hwaddr[16];
char bp_sname[64];
char bp_file[128];
- char bp_vend[64];
+ char bp_vend[BOOTP_VENDOR_LEN];
};
struct tftp_t {
diff --git a/sys/pc98/boot/netboot/ns8390.c b/sys/pc98/boot/netboot/ns8390.c
index e0875e2..73f21d8 100644
--- a/sys/pc98/boot/netboot/ns8390.c
+++ b/sys/pc98/boot/netboot/ns8390.c
@@ -19,6 +19,11 @@ SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
**************************************************************************/
+DELAY(int x)
+{ volatile long a, b, l;
+ for (x; x>0; x--) b=a;
+}
+
#include "netboot.h"
#include "ns8390.h"
@@ -38,15 +43,28 @@ unsigned char eth_memsize;
unsigned char *eth_bmem;
unsigned char *eth_rmem;
unsigned char *eth_node_addr;
+#ifdef PC98
+int twiddle_max = 1;
+int twiddle_counter = 0;
+#endif
/**************************************************************************
The following two variables are used externally
**************************************************************************/
char eth_driver[] = "ed0";
-char packet[ETH_MAX_PACKET];
+char packet[ETHER_MAX_LEN];
int packetlen;
-#ifdef INCLUDE_NE
+#ifdef PC98
+#ifdef INCLUDE_LGY
+int type98 = TYPE98_LGY;
+#endif
+#ifdef INCLUDE_EGY
+int type98 = TYPE98_EGY;
+#endif
+#endif
+
+#if defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)
static unsigned short ne_base_list[]= {
#ifdef NE_BASE
NE_BASE,
@@ -91,7 +109,7 @@ eth_probe()
for (brd = wd_boards; brd->name; brd++)
if (brd->id == c) break;
if (!brd->name) {
- printf("\r\nUnknown Ethernet type %x\r\n", c);
+ printf("\nUnknown Ethernet type %x\n", c);
return(0); /* Unknown type */
}
eth_flags = brd->flags;
@@ -115,7 +133,7 @@ eth_probe()
}
}
outb(eth_asic_base + WD_MSR, 0x80); /* Reset */
- printf("\r\n%s base 0x%x, memory 0x%X, addr ",
+ printf("\n%s base 0x%x, memory 0x%X, addr ",
brd->name, eth_asic_base, eth_bmem);
for (i=0; i<6; i++) {
printf("%b",(int)(arptable[ARP_CLIENT].node[i] =
@@ -140,7 +158,11 @@ eth_probe()
if (eth_flags & FLAG_790) {
eth_laar = inb(eth_asic_base + WD_LAAR);
outb(eth_asic_base + WD_LAAR, WD_LAAR_M16EN);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
} else {
outb(eth_asic_base + WD_LAAR, (eth_laar =
WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
@@ -235,7 +257,7 @@ eth_probe()
/* Get our ethernet address */
outb(eth_asic_base + _3COM_CR, _3COM_CR_EALO | _3COM_CR_XSEL);
- printf("\r\n3Com 3c503 base 0x%x, memory 0x%X addr ",
+ printf("\n3Com 3c503 base 0x%x, memory 0x%X addr ",
eth_nic_base, eth_bmem);
for (i=0; i<6; i++) {
printf("%b",(int)(arptable[ARP_CLIENT].node[i] =
@@ -259,7 +281,7 @@ eth_probe()
bzero(eth_bmem, 0x2000);
for(i = 0; i < 0x2000; ++i)
if (*((eth_bmem)+i)) {
- printf ("Failed to clear 3c503 shared mem.\r\n");
+ printf ("Failed to clear 3c503 shared mem.\n");
return (0);
}
/*
@@ -272,7 +294,7 @@ eth_probe()
}
#endif
-#ifdef INCLUDE_NE
+#if defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)
/******************************************************************
Search for NE1000/2000 if no WD/SMC or 3com cards
******************************************************************/
@@ -284,14 +306,27 @@ eth_probe()
ne_again:
eth_asic_base = *tent_base + NE_ASIC_OFFSET;
eth_nic_base = *tent_base;
-
+#ifdef PC98
+ printf("Looking for LGY/EGY at 0x%x\n", eth_nic_base);
+#else
+ printf("Looking for NE1000/NE2000 at 0x%x\n", eth_nic_base);
+#endif
eth_vendor = VENDOR_NOVELL;
eth_flags = FLAG_PIO;
eth_memsize = MEM_16384;
eth_tx_start = 32;
+#ifdef GWETHER
+ outb(eth_asic_base + NE_RESET, 0);
+ DELAY(200);
+#endif
c = inb(eth_asic_base + NE_RESET);
outb(eth_asic_base + NE_RESET, c);
+ DELAY(5000);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
outb(eth_nic_base + D8390_P0_COMMAND, D8390_COMMAND_STP |
D8390_COMMAND_RD2);
outb(eth_nic_base + D8390_P0_RCR, D8390_RCR_MON);
@@ -317,7 +352,17 @@ ne_again:
return (0);
}
eth_pio_read(0, romdata, 16);
- printf("\r\nNE1000/NE2000 base 0x%x, addr ", eth_nic_base);
+#ifdef PC98
+ printf("\n%s base 0x%x, addr ",
+ type98 == TYPE98_LGY ? "Ethernet adapter LGY-98" :
+ (type98 == TYPE98_EGY ? "Ethernet adapter EGY-98" :
+ (type98 == TYPE98_ICM ? "Ethernet adapter ICM" :
+ "Unknown")),
+ eth_nic_base);
+#else
+ printf("\nNE1000/NE2000 (%d bit) base 0x%x, addr ",
+ eth_flags & FLAG_16BIT ? 16:8, eth_nic_base);
+#endif
for (i=0; i<6; i++) {
printf("%b",(int)(arptable[ARP_CLIENT].node[i] = romdata[i
+ ((eth_flags & FLAG_16BIT) ? i : 0)]));
@@ -327,7 +372,7 @@ ne_again:
}
#endif
found_board:
- printf("\r\n");
+ printf("\n");
if (eth_vendor == VENDOR_NONE) return(0);
if (eth_vendor != VENDOR_3COM) eth_rmem = eth_bmem;
@@ -371,7 +416,11 @@ eth_reset()
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS1 |
D8390_COMMAND_RD2 | D8390_COMMAND_STP);
for (i=0; i<6; i++)
+#ifdef INCLUDE_EGY
+ outb(eth_nic_base+D8390_P1_PAR0+i*2, eth_node_addr[i]); /* for EGY-98 XXX HN2 */
+#else
outb(eth_nic_base+D8390_P1_PAR0+i, eth_node_addr[i]);
+#endif
for (i=0; i<6; i++)
outb(eth_nic_base+D8390_P1_MAR0+i, 0xFF);
outb(eth_nic_base+D8390_P1_CURR, eth_tx_start + D8390_TXBUF_SIZE+1);
@@ -413,43 +462,63 @@ eth_transmit(d,t,s,p)
#ifdef INCLUDE_3COM
if (eth_vendor == VENDOR_3COM) {
bcopy(d, eth_bmem, 6); /* dst */
- bcopy(eth_node_addr, eth_bmem+6, ETHER_ADDR_SIZE); /* src */
+ bcopy(eth_node_addr, eth_bmem+6, ETHER_ADDR_LEN); /* src */
*(eth_bmem+12) = t>>8; /* type */
*(eth_bmem+13) = t;
bcopy(p, eth_bmem+14, s);
s += 14;
- while (s < ETH_MIN_PACKET) *(eth_bmem+(s++)) = 0;
+ while (s < ETHER_MIN_LEN) *(eth_bmem+(s++)) = 0;
}
#endif
#ifdef INCLUDE_WD
if (eth_vendor == VENDOR_WD) { /* Memory interface */
if (eth_flags & FLAG_16BIT) {
outb(eth_asic_base + WD_LAAR, eth_laar | WD_LAAR_M16EN);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
if (eth_flags & FLAG_790) {
outb(eth_asic_base + WD_MSR, WD_MSR_MENB);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
bcopy(d, eth_bmem, 6); /* dst */
- bcopy(eth_node_addr, eth_bmem+6, ETHER_ADDR_SIZE); /* src */
+ bcopy(eth_node_addr, eth_bmem+6, ETHER_ADDR_LEN); /* src */
*(eth_bmem+12) = t>>8; /* type */
*(eth_bmem+13) = t;
bcopy(p, eth_bmem+14, s);
s += 14;
- while (s < ETH_MIN_PACKET) *(eth_bmem+(s++)) = 0;
+ while (s < ETHER_MIN_LEN) *(eth_bmem+(s++)) = 0;
if (eth_flags & FLAG_790) {
outb(eth_asic_base + WD_MSR, 0);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
if (eth_flags & FLAG_16BIT) {
outb(eth_asic_base + WD_LAAR, eth_laar & ~WD_LAAR_M16EN);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
}
#endif
-#ifdef INCLUDE_NE
+#if defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)
if (eth_vendor == VENDOR_NOVELL) { /* Programmed I/O */
unsigned short type;
type = (t >> 8) | (t << 8);
@@ -458,10 +527,17 @@ eth_transmit(d,t,s,p)
eth_pio_write(&type, (eth_tx_start<<8)+12, 2);
eth_pio_write(p, (eth_tx_start<<8)+14, s);
s += 14;
- if (s < ETH_MIN_PACKET) s = ETH_MIN_PACKET;
+ if (s < ETHER_MIN_LEN) s = ETHER_MIN_LEN;
}
#endif
+#ifndef PC98
twiddle();
+#else
+ if (twiddle_counter-- <= 0) {
+ twiddle();
+ twiddle_counter = twiddle_max;
+ }
+#endif
if (eth_flags & FLAG_790)
outb(eth_nic_base+D8390_P0_COMMAND, D8390_COMMAND_PS0 |
D8390_COMMAND_STA);
@@ -481,6 +557,12 @@ eth_transmit(d,t,s,p)
return(0);
}
+void
+set_twiddle_max(int max)
+{
+ twiddle_max = max;
+}
+
/**************************************************************************
ETH_POLL - Wait for a frame
**************************************************************************/
@@ -489,7 +571,7 @@ eth_poll()
int ret = 0;
unsigned short type = 0;
unsigned char bound,curr,rstat;
- unsigned short len;
+ unsigned short len, copylen;
unsigned short pktoff;
unsigned char *p;
struct ringbuffer pkthdr;
@@ -509,13 +591,25 @@ eth_poll()
if (eth_vendor == VENDOR_WD) {
if (eth_flags & FLAG_16BIT) {
outb(eth_asic_base + WD_LAAR, eth_laar | WD_LAAR_M16EN);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
if (eth_flags & FLAG_790) {
outb(eth_asic_base + WD_MSR, WD_MSR_MENB);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
pktoff = (bound << 8);
if (eth_flags & FLAG_PIO)
@@ -528,7 +622,7 @@ eth_poll()
bound = pkthdr.bound; /* New bound ptr */
if ( (pkthdr.status & D8390_RSTAT_PRX) && (len > 14) && (len < 1518)) {
p = packet;
- packetlen = len;
+ packetlen = copylen = len;
len = (eth_memsize << 8) - pktoff;
if (packetlen > len) { /* We have a wrap-around */
if (eth_flags & FLAG_PIO)
@@ -537,12 +631,12 @@ eth_poll()
bcopy(eth_rmem + pktoff, p, len);
pktoff = (eth_tx_start + D8390_TXBUF_SIZE) << 8;
p += len;
- packetlen -= len;
+ copylen -= len;
}
if (eth_flags & FLAG_PIO)
- eth_pio_read(pktoff, p, packetlen);
+ eth_pio_read(pktoff, p, copylen);
else
- bcopy(eth_rmem + pktoff, p, packetlen);
+ bcopy(eth_rmem + pktoff, p, copylen);
type = (packet[12]<<8) | packet[13];
ret = 1;
@@ -550,14 +644,26 @@ eth_poll()
if (eth_vendor == VENDOR_WD) {
if (eth_flags & FLAG_790) {
outb(eth_asic_base + WD_MSR, 0);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
if (eth_flags & FLAG_16BIT) {
outb(eth_asic_base + WD_LAAR, eth_laar &
~WD_LAAR_M16EN);
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
+#ifndef PC98
inb(0x84);
+#else
+ (void)outb(0x5f,0);
+#endif
}
if (bound == (eth_tx_start + D8390_TXBUF_SIZE))
bound = eth_memsize;
@@ -565,7 +671,7 @@ eth_poll()
if (ret && (type == ARP)) {
struct arprequest *arpreq;
unsigned long reqip;
- arpreq = (struct arprequest *)&packet[ETHER_HDR_SIZE];
+ arpreq = (struct arprequest *)&packet[ETHER_HDR_LEN];
convert_ipaddr(&reqip, arpreq->tipaddr);
if ((ntohs(arpreq->opcode) == ARP_REQUEST) &&
(reqip == arptable[ARP_CLIENT].ipaddr)) {
@@ -582,7 +688,7 @@ eth_poll()
return(ret);
}
-#ifdef INCLUDE_NE
+#if defined(INCLUDE_NE) || defined(INCLUDE_LGY) || defined(INCLUDE_EGY)
/**************************************************************************
ETH_PIO_READ - Read a frame via Programmed I/O
**************************************************************************/
@@ -644,8 +750,9 @@ eth_pio_write(src, dst, cnt, init)
while (cnt--)
outb(eth_asic_base + NE_DATA, *(src++));
}
+ cnt = 200;
while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
- != D8390_ISR_RDC);
+ != D8390_ISR_RDC && --cnt);
}
#else
/**************************************************************************
diff --git a/sys/pc98/boot/netboot/ns8390.h b/sys/pc98/boot/netboot/ns8390.h
index a6616bc..ea60908 100644
--- a/sys/pc98/boot/netboot/ns8390.h
+++ b/sys/pc98/boot/netboot/ns8390.h
@@ -183,6 +183,7 @@ NE1000/2000 definitions
/**************************************************************************
8390 Register Definitions
**************************************************************************/
+#if !defined(PC98) || defined(INCLUDE_LGY)
#define D8390_P0_COMMAND 0x00
#define D8390_P0_PSTART 0x01
#define D8390_P0_PSTOP 0x02
@@ -210,6 +211,41 @@ NE1000/2000 definitions
#define D8390_P1_PAR5 0x06
#define D8390_P1_CURR 0x07
#define D8390_P1_MAR0 0x08
+#endif
+#ifdef PC98
+#define TYPE98_LGY 0x10
+#define TYPE98_EGY 0x11
+#define TYPE98_ICM 0x12
+#endif
+#ifdef INCLUDE_EGY
+#define D8390_P0_COMMAND 0x00
+#define D8390_P0_PSTART 0x02
+#define D8390_P0_PSTOP 0x04
+#define D8390_P0_BOUND 0x06
+#define D8390_P0_TSR 0x08
+#define D8390_P0_TPSR 0x08
+#define D8390_P0_TBCR0 0x0a
+#define D8390_P0_TBCR1 0x0c
+#define D8390_P0_ISR 0x0e
+#define D8390_P0_RSAR0 0x100
+#define D8390_P0_RSAR1 0x102
+#define D8390_P0_RBCR0 0x104
+#define D8390_P0_RBCR1 0x106
+#define D8390_P0_RSR 0x108
+#define D8390_P0_RCR 0x108
+#define D8390_P0_TCR 0x10a
+#define D8390_P0_DCR 0x10c
+#define D8390_P0_IMR 0x10e
+#define D8390_P1_COMMAND 0x00
+#define D8390_P1_PAR0 0x02
+#define D8390_P1_PAR1 0x04
+#define D8390_P1_PAR2 0x06
+#define D8390_P1_PAR3 0x08
+#define D8390_P1_PAR4 0x0a
+#define D8390_P1_PAR5 0x0c
+#define D8390_P1_CURR 0x0e
+#define D8390_P1_MAR0 0x100
+#endif
#define D8390_COMMAND_PS0 0x0 /* Page 0 select */
#define D8390_COMMAND_PS1 0x40 /* Page 1 select */
diff --git a/sys/pc98/boot/netboot/rpc.c b/sys/pc98/boot/netboot/rpc.c
index f035248..e173013 100644
--- a/sys/pc98/boot/netboot/rpc.c
+++ b/sys/pc98/boot/netboot/rpc.c
@@ -31,7 +31,7 @@ rpclookup(addr, prog, ver)
udp_transmit(arptable[addr].ipaddr, RPC_SOCKET,
SUNRPC, rpcptr - (char *)&buf, &buf);
if (await_reply(AWAIT_RPC, rpc_id, NULL)) {
- rpc = (struct rpc_t *)&packet[ETHER_HDR_SIZE];
+ rpc = (struct rpc_t *)&packet[ETHER_HDR_LEN];
if (rpc->u.reply.rstatus == rpc->u.reply.verifier ==
rpc->u.reply.astatus == 0)
return(ntohl(rpc->u.reply.data[0]));
@@ -66,7 +66,7 @@ nfs_mount(server, port, path, fh)
udp_transmit(arptable[server].ipaddr, RPC_SOCKET,
port, rpcptr - (char *)&buf, &buf);
if (await_reply(AWAIT_RPC, rpc_id, NULL)) {
- rpc = (struct rpc_t *)&packet[ETHER_HDR_SIZE];
+ rpc = (struct rpc_t *)&packet[ETHER_HDR_LEN];
if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
rpc->u.reply.astatus || rpc->u.reply.data[0]) {
rpc_err(rpc);
@@ -86,12 +86,13 @@ nfs_mount(server, port, path, fh)
NFS_LOOKUP: Lookup Pathname
***************************************************************************/
-nfs_lookup(server, port, fh, path, file_fh)
+nfs_lookup(server, port, fh, path, file_fh, sizep)
int server;
int port;
char *fh;
char *path;
char *file_fh;
+ int *sizep;
{
struct rpc_t buf, *rpc;
char *rpcptr;
@@ -104,13 +105,15 @@ nfs_lookup(server, port, fh, path, file_fh)
udp_transmit(arptable[server].ipaddr, RPC_SOCKET,
port, rpcptr - (char *)&buf, &buf);
if (await_reply(AWAIT_RPC, rpc_id, NULL)) {
- rpc = (struct rpc_t *)&packet[ETHER_HDR_SIZE];
+ rpc = (struct rpc_t *)&packet[ETHER_HDR_LEN];
if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
rpc->u.reply.astatus || rpc->u.reply.data[0]) {
rpc_err(rpc);
return(-(ntohl(rpc->u.reply.data[0])));
} else {
bcopy(&rpc->u.reply.data[1],file_fh, 32);
+ if (sizep)
+ *sizep = ntohl(rpc->u.reply.data[14]);
return(0);
}
}
@@ -143,7 +146,7 @@ nfs_read(server, port, fh, offset, len, buffer)
udp_transmit(arptable[server].ipaddr, RPC_SOCKET,
port, rpcptr - (char *)&buf, &buf);
if (await_reply(AWAIT_RPC, rpc_id, NULL)) {
- rpc = (struct rpc_t *)&packet[ETHER_HDR_SIZE];
+ rpc = (struct rpc_t *)&packet[ETHER_HDR_LEN];
if (rpc->u.reply.rstatus || rpc->u.reply.verifier ||
rpc->u.reply.astatus || rpc->u.reply.data[0]) {
rpc_err(rpc);
@@ -151,7 +154,7 @@ nfs_read(server, port, fh, offset, len, buffer)
} else {
rlen = ntohl(rpc->u.reply.data[18]);
if (len < rlen) rlen = len;
- if (len > rlen) printf("short read\r\n");
+ if (len > rlen) printf("short read\n");
bcopy(&rpc->u.reply.data[19], buffer, rlen);
return(rlen);
}
@@ -169,7 +172,7 @@ rpc_err(rpc)
struct rpc_t *rpc;
{
int err = ntohl(rpc->u.reply.data[0]);
- printf("***RPC Error: (%d,%d,%d):\r\n ",
+ printf("***RPC Error: (%d,%d,%d):\n ",
ntohl(rpc->u.reply.rstatus),
ntohl(rpc->u.reply.verifier),
ntohl(rpc->u.reply.astatus));
@@ -183,5 +186,5 @@ nfs_err(err)
else if (err == NFSERR_NOENT) printf("No such file or directory");
else if (err == NFSERR_ACCES) printf("Permission denied");
else printf("Error %d",err);
- printf("\r\n");
+ printf("\n");
}
diff --git a/sys/pc98/boot/netboot/start2.S b/sys/pc98/boot/netboot/start2.S
index 5bbc96c..7530e1d 100644
--- a/sys/pc98/boot/netboot/start2.S
+++ b/sys/pc98/boot/netboot/start2.S
@@ -2,7 +2,8 @@
#define STACKADDR 0xe000 /* Needs to be end of bss + stacksize */
#define KERN_CODE_SEG 0x08
#define KERN_DATA_SEG 0x10
-#define REAL_MODE_SEG 0x18
+#define REAL_MODE_CSEG 0x18
+#define REAL_MODE_DSEG 0x20
#define CR0_PE 1
#define opsize .byte 0x66
@@ -13,6 +14,7 @@
* 32 bit sensitive until things are fixed up.
*/
#ifdef BOOTROM
+#ifndef PC98
.word 0xaa55 /* bios extension signature */
.byte (ROMSIZE>>9) /* no. of 512B blocks */
jmp 1f /* enter from bios here */
@@ -65,6 +67,70 @@
2: pop %ds
pop %eax
lret
+#else /* defined PC98 */
+ .byte 0xcb /* 00 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 03 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 06 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0x55 /* 09 MAGIC */
+ .byte 0xaa
+ .byte 0x00
+ .byte 0xeb /* 0c jmp 1f */
+ .byte 0x22
+ .byte 0x00
+ .byte 0xcb /* 0f retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 12 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 15 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 18 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 1b retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 1e retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 21 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 24 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 27 retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 2a retf */
+ .byte 0x00
+ .byte 0x00
+ .byte 0xcb /* 2d retf */
+ .byte 0x00
+ .byte 0x00
+1:
+ cli
+ pusha
+ opsize
+ mov $0x1fc0, %eax
+ mov %ax, %es
+ mov %esp, %eax
+ addrsize
+ .byte 0x26 /* es: */
+ mov %eax, (0x0000)
+ mov %ss, %ax
+ addrsize
+ .byte 0x26 /* es: */
+ mov %eax, (0x0004)
+#endif
#endif
/**************************************************************************
@@ -93,6 +159,59 @@ _start:
ljmp $(RELOC>>4),$1f-RELOC /* Jmp to RELOC:1f */
1:
nop
+#ifdef PC98
+ opsize
+ mov $0x0a00, %eax /* 80 x 25 mode */
+ int $0x18
+ movb $0x0c, %ah /* text on */
+ int $0x18
+ movb $0x16, %ah /* t-vram clear */
+ opsize
+ mov $0xe100, %edx
+ int $0x18
+
+ /* cursor home and on */
+ xor %edx, %edx
+ movb $0x13, %ah
+ int $0x18
+ movb $0x11, %ah
+ int $0x18
+
+ /* set up %ds */
+ xor %ax, %ax
+ mov %ax, %ds
+
+ opsize
+ mov $0xa000, %eax
+ mov %ax, %es
+
+ /* transfer PC-9801 system common area to 0xa1000 */
+ opsize
+ mov $0x0000, %esi
+ opsize
+ mov $0x1000, %edi
+ opsize
+ mov $0x0630, %ecx
+ cld
+ rep
+ movsb
+
+ /* transfer EPSON machine type to 0xa1200 */
+ push %ds
+ opsize
+ mov $0xfd00, %eax
+ mov %ax, %ds
+ addrsize
+ opsize
+ mov 0x804, %eax
+ opsize
+ and $0x00ffffff, %eax
+ addrsize
+ opsize
+ .byte 0x26
+ mov %eax, %es: (0x1624)
+ pop %ds
+#endif
mov %cs,%ax
mov %ax,%ds
mov %ax,%es
@@ -106,6 +225,7 @@ _start:
.globl _exit
_exit:
call _prot_to_real
+#ifndef PC98
#ifdef BOOTROM
xor %eax,%eax
mov %ax,%ds
@@ -119,7 +239,57 @@ _exit:
#else
int $0x19
#endif
+#else /* defined PC98 */
+#ifdef BOOTROM
+ cli
+ movb $0x0e, %al /* CPU RESET */
+ outb %al, $0x37
+ xor %eax, %eax
+ mov %ax, %es
+ push %cs
+ push $2f
+ addrsize
+ .byte 0x26 /* es: */
+ mov %esp, (0x0404)
+ addrsize
+ .byte 0x26 /* es: */
+ movw %ss, (0x0406)
+ movb $0x00, %al
+ outb %al, $0xf0
+1:
+ jmp 1b
+2:
+ movb $0x0f, %al
+ outb %al, $0x37
+
+ opsize /* restore ss:sp */
+ mov $0x1fc0, %eax
+ mov %ax, %es
+ addrsize
+ .byte 0x26 /* es: */
+ mov (0x0000), %ebx
+ addrsize
+ .byte 0x26 /* es: */
+ mov (0x0004), %eax
+ mov %ax, %ss
+ mov %ebx, %esp
+ sti
+ popa
+ lret
+#else
+ mov $0x8000, %ecx
+ movb $0x00, %al
+1:
+ jmp 1b
+ outb %al, $0x5f
+ loop 1b
+ outb %al, $0xf0
+1:
+ jmp 1b
+#endif
+#endif
+#ifndef PC98
/**************************************************************************
CURRTICKS - Get Time
**************************************************************************/
@@ -127,8 +297,9 @@ CURRTICKS - Get Time
_currticks:
push %ebp
mov %esp,%ebp
- push %ecx
- push %edx
+ push %ebx
+ push %esi
+ push %edi
xor %edx,%edx
call _prot_to_real
xor %eax,%eax
@@ -139,8 +310,9 @@ _currticks:
shl $16,%ecx
mov %edx,%eax
or %ecx,%eax
- pop %edx
- pop %ecx
+ pop %edi
+ pop %esi
+ pop %ebx
pop %ebp
ret
@@ -151,8 +323,9 @@ PUTCHAR - Print a character
_putchar:
push %ebp
mov %esp,%ebp
- push %ecx
push %ebx
+ push %esi
+ push %edi
movb 8(%ebp),%cl
call _prot_to_real
opsize
@@ -162,8 +335,9 @@ _putchar:
int $0x10
opsize
call _real_to_prot
+ pop %edi
+ pop %esi
pop %ebx
- pop %ecx
pop %ebp
ret
@@ -175,6 +349,8 @@ _getchar:
push %ebp
mov %esp,%ebp
push %ebx
+ push %esi
+ push %edi
call _prot_to_real
movb $0x0,%ah
int $0x16
@@ -183,6 +359,8 @@ _getchar:
call _real_to_prot
xor %eax,%eax
movb %bl,%al
+ pop %edi
+ pop %esi
pop %ebx
pop %ebp
ret
@@ -195,6 +373,8 @@ _iskey:
push %ebp
mov %esp,%ebp
push %ebx
+ push %esi
+ push %edi
call _prot_to_real
xor %ebx,%ebx
movb $0x1,%ah
@@ -207,10 +387,120 @@ _iskey:
call _real_to_prot
xor %eax,%eax
movb %bl,%al
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %ebp
+ ret
+#else /* defined PC98 */
+/**************************************************************************
+Get Date & Time
+**************************************************************************/
+ .globl _bios98getdate
+_bios98getdate:
+ push %ebp
+ mov %esp,%ebp
+ push %ebx
+ push %es
+
+ call _prot_to_real
+
+ opsize
+ mov $0x1ff0, %eax
+ mov %ax, %es
+ movb $0x00, %ah
+ opsize
+ mov $0x80, %ebx /* bios uses 1ff0:0080 */
+ int $0x1c
+
+ opsize
+ mov $0x82, %ebx
+ opsize
+ .byte 0x26 /* es: */
+ .byte 0x8b /* mov (%ebx), %ebx */
+ .byte 0x1f
+
+ opsize
+ call _real_to_prot
+
+ mov %ebx, %eax
+ pop %es
+ pop %ebx
+ pop %ebp
+ ret
+
+/*
+ * getc()
+ * BIOS call "INT 18H Function 00H" to read character from keyboard
+ * Call with %ah = 0x0
+ * Return: %ah = keyboard scan code
+ * %al = ASCII character
+ */
+
+ .globl _getchar
+_getchar:
+ push %ebp
+ mov %esp, %ebp
+ push %ebx /* save %ebx */
+
+ call _prot_to_real
+
+ movb $0x0, %ah
+ int $0x18
+
+ movb %al, %bl /* real_to_prot uses %eax */
+
+ opsize
+ call _real_to_prot
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+/*
+ * ischar()
+ * if there is a character pending, return it; otherwise return 0
+ * BIOS call "INT 18H Function 01H" to check whether a character is pending
+ * Call with %ah = 0x1
+ * Return:
+ * If key waiting to be input:
+ * %ah = keyboard scan code
+ * %al = ASCII character
+ * %bh = 1
+ * else
+ * %bh = 0
+ */
+ .globl _iskey
+_iskey:
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ call _prot_to_real /* enter real mode */
+
+ xor %ebx, %ebx
+ movb $0x1, %ah
+ int $0x18
+ andb %bh, %bh
+ opsize
+ jz nochar
+ movb %al, %bl
+
+nochar:
+ opsize
+ call _real_to_prot
+
+ xor %eax, %eax
+ movb %bl, %al
+
pop %ebx
pop %ebp
ret
+#endif
+
/*
* C library -- _setjmp, _longjmp
@@ -298,8 +588,17 @@ _prot_to_real:
sub $RELOC,%eax /* Adjust return address */
push %eax
sub $RELOC,%esp /* Adjust stack pointer */
- ljmp $REAL_MODE_SEG, $1f /* jump to a 16 bit segment */
+
+ /* Prepare %ax while we're still in a mode that gas understands. */
+ movw $REAL_MODE_DSEG, %ax
+
+ ljmp $REAL_MODE_CSEG, $1f-RELOC /* jump to a 16 bit segment */
1:
+ mov %ax, %ds
+ mov %ax, %ss
+ mov %ax, %es
+ mov %ax, %fs
+
/* clear the PE bit of CR0 */
mov %cr0, %eax
opsize
@@ -324,6 +623,76 @@ _prot_to_real:
ret
/**************************************************************************
+GET DISK GEOMETRY INFO
+**************************************************************************/
+#ifdef PC98
+/*
+ *
+ * get_diskinfo(): return a word that represents the
+ * max number of sectors and heads and drives for this device
+ *
+ */
+ .globl _get_diskinfo
+_get_diskinfo:
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+ push %esi
+ push %edi
+
+ movb 0x8(%ebp), %dl /* diskinfo(drive #) */
+ call _prot_to_real /* enter real mode */
+
+ movb %dl, %al /* ask for disk info */
+ andb $0xf0, %al
+ cmpb $0x90, %al
+ jz fdd
+
+ movb %dl, %al
+ movb $0x84, %ah
+
+ int $0x1b
+
+ jnc ok
+ /*
+ * Urk. Call failed. It is not supported for floppies by old BIOS's.
+ * Guess it's a 15-sector floppy.
+ */
+fdd:
+ subb %ah, %ah /* %ax = 0 */
+ movb %al, %al
+ movb %ah, %bh /* %bh = 0 */
+ movb $2, %bl /* %bl bits 0-3 = drive type,
+ bit 2 = 1.2M */
+ movb $79, %ch /* max track */
+ movb $1, %cl /* # floppy drives installed */
+ movb $2, %dh /* max head */
+ movb $15, %dl /* max sector */
+ /* es:di = parameter table */
+ /* carry = 0 */
+ok:
+
+ opsize
+ call _real_to_prot /* back to protected mode */
+
+ /*
+ * form a longword representing all this gunk:
+ * 16 bit cylinder
+ * 8 bit head
+ * 8 bit sector
+ */
+ mov %ecx, %eax
+ sall $16,%eax /* << 16 */
+ movb %dh, %ah /* max head */
+ movb %dl, %al /* max sector (and # sectors) */
+
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %ebp
+ ret
+#endif
+/**************************************************************************
GLOBAL DESCRIPTOR TABLE
**************************************************************************/
.align 4
@@ -339,11 +708,15 @@ gdt:
.word 0xffff, 0
.byte 0, 0x93, 0xcf, 0
- /* 16 bit real mode */
- .word 0xffff, 0
- .byte 0, 0x9b, 0x0f, 0
+ /* 16 bit real mode code segment */
+ .word 0xffff, RELOC & 0xffff
+ .byte (RELOC>>16), 0x9b, 0x00, (RELOC>>24)
+
+ /* 16 bit real mode data segment */
+ .word 0xffff, RELOC & 0xffff
+ .byte (RELOC>>16), 0x93, 0x00, (RELOC>>24)
.align 4
gdtarg:
- .word 0x1f /* limit */
+ .word 0x27 /* limit */
.long gdt /* addr */
OpenPOWER on IntegriCloud