summaryrefslogtreecommitdiff
path: root/sys/boot
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/Makefile7
-rw-r--r--sys/boot/alpha/Makefile.inc8
-rw-r--r--sys/boot/alpha/boot1/Makefile10
-rw-r--r--sys/boot/alpha/boot1/boot1.c4
-rw-r--r--sys/boot/alpha/boot2/Makefile22
-rw-r--r--sys/boot/alpha/boot2/help.alpha0
-rw-r--r--sys/boot/alpha/boot2/newvers.sh1
-rw-r--r--sys/boot/alpha/common/main.c76
-rw-r--r--sys/boot/alpha/libalpha/Makefile4
-rw-r--r--sys/boot/alpha/libalpha/srmdisk.c41
-rw-r--r--sys/boot/alpha/libalpha/start.S15
-rw-r--r--sys/boot/alpha/netboot/Makefile6
-rw-r--r--sys/boot/common/Makefile.inc12
-rw-r--r--sys/boot/common/bcache.c262
-rw-r--r--sys/boot/common/boot.c12
-rw-r--r--sys/boot/common/bootstrap.h134
-rw-r--r--sys/boot/common/commands.c216
-rw-r--r--sys/boot/common/console.c10
-rw-r--r--sys/boot/common/help.common262
-rw-r--r--sys/boot/common/interp.c61
-rw-r--r--sys/boot/common/interp_backslash.c5
-rw-r--r--sys/boot/common/interp_forth.c142
-rw-r--r--sys/boot/common/interp_parse.c8
-rw-r--r--sys/boot/common/isapnp.c236
-rw-r--r--sys/boot/common/isapnp.h8
-rw-r--r--sys/boot/common/load_aout.c48
-rw-r--r--sys/boot/common/load_elf.c113
-rw-r--r--sys/boot/common/ls.c3
-rw-r--r--sys/boot/common/merge_help.awk101
-rw-r--r--sys/boot/common/module.c4
-rw-r--r--sys/boot/common/pnp.c173
-rw-r--r--sys/boot/common/pnpdata183
-rw-r--r--sys/boot/ficl/Makefile30
-rw-r--r--sys/boot/ficl/dict.c779
-rw-r--r--sys/boot/ficl/ficl.c432
-rw-r--r--sys/boot/ficl/ficl.h773
-rw-r--r--sys/boot/ficl/math64.c296
-rw-r--r--sys/boot/ficl/math64.h60
-rw-r--r--sys/boot/ficl/softwords/classes.fr140
-rw-r--r--sys/boot/ficl/softwords/jhlocal.fr77
-rw-r--r--sys/boot/ficl/softwords/marker.fr25
-rw-r--r--sys/boot/ficl/softwords/oo.fr464
-rw-r--r--sys/boot/ficl/softwords/softcore.awk96
-rw-r--r--sys/boot/ficl/softwords/softcore.fr125
-rw-r--r--sys/boot/ficl/stack.c305
-rw-r--r--sys/boot/ficl/sysdep.c126
-rw-r--r--sys/boot/ficl/sysdep.h251
-rw-r--r--sys/boot/ficl/testmain.c275
-rw-r--r--sys/boot/ficl/vm.c565
-rw-r--r--sys/boot/ficl/words.c4544
-rw-r--r--sys/boot/i386/boot0/Makefile10
-rw-r--r--sys/boot/i386/boot0/boot0.m417
-rw-r--r--sys/boot/i386/boot0/boot0.s224
-rw-r--r--sys/boot/i386/boot2/Makefile11
-rw-r--r--sys/boot/i386/boot2/boot1.m44
-rw-r--r--sys/boot/i386/boot2/boot1.s176
-rw-r--r--sys/boot/i386/boot2/boot2.c74
-rw-r--r--sys/boot/i386/boot2/sio.s8
-rw-r--r--sys/boot/i386/btx/btx/btx.s32
-rw-r--r--sys/boot/i386/btx/btxldr/Makefile5
-rw-r--r--sys/boot/i386/btx/btxldr/btxldr.s68
-rw-r--r--sys/boot/i386/btx/lib/btxv86.s7
-rw-r--r--sys/boot/i386/libi386/Makefile27
-rw-r--r--sys/boot/i386/libi386/biosdisk.c130
-rw-r--r--sys/boot/i386/libi386/biospci.c294
-rw-r--r--sys/boot/i386/libi386/biospnp.c289
-rw-r--r--sys/boot/i386/libi386/bootinfo.c6
-rw-r--r--sys/boot/i386/libi386/comconsole.c89
-rw-r--r--sys/boot/i386/libi386/vidconsole.c403
-rw-r--r--sys/boot/i386/loader/Makefile72
-rw-r--r--sys/boot/i386/loader/conf.c10
-rw-r--r--sys/boot/i386/loader/help.i38634
-rw-r--r--sys/boot/i386/loader/main.c46
-rwxr-xr-xsys/boot/i386/loader/newvers.sh1
-rw-r--r--sys/boot/i386/loader/setdef0.c49
-rw-r--r--sys/boot/i386/loader/setdef1.c41
76 files changed, 851 insertions, 12826 deletions
diff --git a/sys/boot/Makefile b/sys/boot/Makefile
index cd271859639f..1de594169211 100644
--- a/sys/boot/Makefile
+++ b/sys/boot/Makefile
@@ -1,7 +1,4 @@
-# Build the add-in FORTH interpreter
-SUBDIR+= ficl
-
-# Pick the machine-dependant subdir based on the target architecture.
-SUBDIR+= ${MACHINE_ARCH}
+# Pick the subdir based on the target architecture.
+SUBDIR= ${MACHINE_ARCH}
.include <bsd.subdir.mk>
diff --git a/sys/boot/alpha/Makefile.inc b/sys/boot/alpha/Makefile.inc
index abb4f65cbc89..bbbea75f1efe 100644
--- a/sys/boot/alpha/Makefile.inc
+++ b/sys/boot/alpha/Makefile.inc
@@ -1,8 +1,10 @@
# Options used when building app-specific libalpha components
-PRIMARY_LOAD_ADDRESS= 0x20000000 # "Region 1 start"
-SECONDARY_LOAD_ADDRESS= 0x2000c000 # "Region 1 start" + 48k
-HEAP_LIMIT= 0x20040000 # "Region 1 start" + 256k
+PRIMARY_LOAD_ADDRESS= 20000000 # "Region 1 start"
+SECONDARY_LOAD_ADDRESS= 2000c000 # "Region 1 start" + 48k
+HEAP_LIMIT= 20040000 # "Region 1 start" + 256k
DPADD+= ${DESTDIR}/${LIBDIR}/libstand.a
LIBSTANDDIR= ${.CURDIR}/../../../../lib/libstand
LIBSTAND= -lstand
LIBALPHA= ${.OBJDIR}/../libalpha/libalpha.a
+
+BINDIR= /usr/mdec
diff --git a/sys/boot/alpha/boot1/Makefile b/sys/boot/alpha/boot1/Makefile
index bfbcb7a88114..e163c03345a4 100644
--- a/sys/boot/alpha/boot1/Makefile
+++ b/sys/boot/alpha/boot1/Makefile
@@ -12,10 +12,9 @@ CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
CFLAGS+= -I${LIBSTANDDIR}
CFLAGS+= -I${.CURDIR}/..
-CFLAGS+= -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS} -DMINIMAL
+CFLAGS+= -DSECONDARY_LOAD_ADDRESS=0x${SECONDARY_LOAD_ADDRESS} -DMINIMAL
NOMAN=1
STRIP=
-BINDIR?= /boot
BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS}
@@ -23,6 +22,10 @@ CLEANFILES+= ${PROG}.sym ${PROG}.nosym ${PROG}.list
all: ${PROG}
+afterinstall:
+ ln -sf boot1 /usr/mdec/daboot
+ ln -sf boot1 /usr/mdec/fdboot
+
${PROG}.nosym: ${PROG}.sym
cp ${PROG}.sym ${PROG}.nosym
strip ${PROG}.nosym
@@ -33,9 +36,10 @@ ${PROG}: ${PROG}.nosym
.include <bsd.prog.mk>
start.o: ${.CURDIR}/../libalpha/start.S
- ${CC} -c ${CFLAGS} $<
+ ${CC} -c -DPRIMARY_BOOTBLOCK $<
${PROG}.sym: ${OBJS} ${LIBKERN}
${LD} -M -Ttext ${BOOT_RELOC} -N -e start -o ${PROG}.sym ${OBJS} \
${LIBSTAND} ${LIBALPHA} ${LIBSTAND} > ${.OBJDIR}/${PROG}.list
size ${PROG}.sym
+
diff --git a/sys/boot/alpha/boot1/boot1.c b/sys/boot/alpha/boot1/boot1.c
index 9eac7ec64c71..a3fbfc2bf397 100644
--- a/sys/boot/alpha/boot1/boot1.c
+++ b/sys/boot/alpha/boot1/boot1.c
@@ -1,5 +1,5 @@
/*
- * $Id: boot1.c,v 1.2 1998/09/26 10:51:36 dfr Exp $
+ * $Id: boot1.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
* From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner Exp $
*/
@@ -181,7 +181,7 @@ main()
init_prom_calls();
- loadfile("/boot/loader", loadaddr);
+ loadfile("/boot/boot2", loadaddr);
entry = (void (*)())loadaddr;
(*entry)();
diff --git a/sys/boot/alpha/boot2/Makefile b/sys/boot/alpha/boot2/Makefile
index 956944d255c8..dfc8e58121eb 100644
--- a/sys/boot/alpha/boot2/Makefile
+++ b/sys/boot/alpha/boot2/Makefile
@@ -1,6 +1,6 @@
# $NetBSD: Makefile,v 1.12 1998/02/19 14:18:36 drochner Exp $
-BASE= loader
+BASE= boot2
PROG= ${BASE}
NOMAN=
NEWVERSWHAT= "SRM disk boot"
@@ -16,9 +16,6 @@ SRCS+= main.c conf.c
CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
CFLAGS+= -I${.CURDIR}/../../.. -I.
-CFLAGS+= -DLOADER
-CFLAGS+= -DPRIMARY_LOAD_ADDRESS=${PRIMARY_LOAD_ADDRESS} \
- -DSECONDARY_LOAD_ADDRESS=${SECONDARY_LOAD_ADDRESS}
CLEANFILES+= vers.c vers.o gensetdefs.o gensetdefs setdef0.o setdef1.o \
setdefs.h start.o
@@ -30,7 +27,6 @@ CFLAGS+= -I${LIBSTANDDIR}
CFLAGS+= -I${.CURDIR}/..
CRT= start.o
STRIP=
-BINDIR?= /boot
all: ${BASE}
@@ -38,7 +34,7 @@ vers.o: ${.CURDIR}/newvers.sh ${.CURDIR}/Makefile
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
${CC} -c vers.c
-${BASE}: ${BASE}.sym ${BASE}.help
+${BASE}: ${BASE}.sym
objcopy -O binary ${BASE}.sym ${BASE}
${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBALPHA} ${CRT} vers.o setdef0.o setdef1.o
@@ -46,21 +42,9 @@ ${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBALPHA} ${CRT} vers.o setdef0.o setdef1.o
${CRT} setdef0.o ${OBJS} setdef1.o \
vers.o ${LIBSTAND} ${LIBALPHA} ${LIBSTAND} >${.OBJDIR}/${BASE}.list
-${BASE}.help: help.common help.alpha
- cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
-
-beforeinstall:
-.if exists(${.OBJDIR}/loader.help)
- ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
- ${.OBJDIR}/${BASE}.help ${DESTDIR}/boot
-.else
- ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
- ${.CURDIR}/${BASE}.help ${DESTDIR}/boot
-.endif
-
# Other fragments still to be brought in from ../Makfile.booters?
start.o: ${.CURDIR}/../libalpha/start.S
- ${CC} -c ${CFLAGS} $<
+ ${CC} -c $<
setdef0.o: setdefs.h
diff --git a/sys/boot/alpha/boot2/help.alpha b/sys/boot/alpha/boot2/help.alpha
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/sys/boot/alpha/boot2/help.alpha
+++ /dev/null
diff --git a/sys/boot/alpha/boot2/newvers.sh b/sys/boot/alpha/boot2/newvers.sh
index 978c16489867..88cc010175bb 100644
--- a/sys/boot/alpha/boot2/newvers.sh
+++ b/sys/boot/alpha/boot2/newvers.sh
@@ -35,7 +35,6 @@
#
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
-LC_TIME=C; export LC_TIME
u=${USER-root} h=`hostname` t=`date`
r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
diff --git a/sys/boot/alpha/common/main.c b/sys/boot/alpha/common/main.c
index 41400240b26e..365e5c4cd98c 100644
--- a/sys/boot/alpha/common/main.c
+++ b/sys/boot/alpha/common/main.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: main.c,v 1.8 1998/10/31 17:12:32 dfr Exp $
+ * $Id: main.c,v 1.4 1998/09/03 02:10:02 msmith Exp $
*/
@@ -63,50 +63,6 @@ memsize()
return total;
}
-static void
-extend_heap()
-{
- struct rpb *hwrpb = (struct rpb *)HWRPB_ADDR;
- struct mddt *mddtp;
- struct mddt_cluster *memc;
- int i;
- unsigned long total = 0;
- unsigned long startpfn;
- vm_offset_t startva;
- vm_offset_t startpte;
-
- /*
- * Find the last usable memory cluster and add some of its pages
- * to our address space. The 256k allowed by the firmware isn't quite
- * adequate for our needs.
- */
- mddtp = (struct mddt *)(((caddr_t)hwrpb) + hwrpb->rpb_memdat_off);
- for (i = mddtp->mddt_cluster_cnt - 1; i >= 0; i--) {
- memc = &mddtp->mddt_clusters[i];
- if (!(memc->mddt_usage & (MDDT_NONVOLATILE | MDDT_PALCODE)))
- break;
- }
-
- /*
- * We want to extend the heap from 256k to 512k. With 8k pages
- * (assumed), we need 32 pages. We take pages from the end of the
- * last usable memory region, taking care to avoid the memory used
- * by the kernel's message buffer. We allow 4 pages for the
- * message buffer.
- */
- startpfn = memc->mddt_pfn + memc->mddt_pg_cnt - 4 - 32;
- startva = 0x20040000;
- startpte = 0x40000000
- + (((startva >> 23) & 0x3ff) << PAGE_SHIFT)
- + (((startva >> 13) & 0x3ff) << 3);
-
- for (i = 0; i < 32; i++) {
- u_int64_t pte;
- pte = ((startpfn + i) << 32) | 0x1101;
- *(u_int64_t *) (startpte + 8 * i) = pte;
- }
-}
-
void
main(void)
{
@@ -114,27 +70,18 @@ main(void)
char bootfile[128];
/*
- * Initialise the heap as early as possible. Once this is done,
- * alloc() is usable. The stack is buried inside us, so this is
- * safe.
+ * Initialise the heap as early as possible. Once this is done, alloc() is usable.
+ * The stack is buried inside us, so this is safe
*/
- extend_heap();
- setheap((void *)end, (void *)0x20080000);
+ setheap((void *)end, (void *)0x20040000);
-#ifdef LOADER
- /*
- * If this is the two stage disk loader, add the memory used by
- * the first stage to the heap.
- */
- free_region((void *)PRIMARY_LOAD_ADDRESS,
- (void *)SECONDARY_LOAD_ADDRESS);
-#endif
/*
- * XXX Chicken-and-egg problem; we want to have console output
- * early, but some console attributes may depend on reading from
- * eg. the boot device, which we can't do yet. We can use
- * printf() etc. once this is done.
+ * XXX Chicken-and-egg problem; we want to have console output early, but some
+ * console attributes may depend on reading from eg. the boot device, which we
+ * can't do yet.
+ *
+ * We can use printf() etc. once this is done.
*/
cons_probe();
@@ -142,11 +89,6 @@ main(void)
OSFpal();
/*
- * Initialise the block cache
- */
- bcache_init(32, 512); /* 16k XXX tune this */
-
- /*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
diff --git a/sys/boot/alpha/libalpha/Makefile b/sys/boot/alpha/libalpha/Makefile
index 4928647b7548..a82febf2e2a3 100644
--- a/sys/boot/alpha/libalpha/Makefile
+++ b/sys/boot/alpha/libalpha/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.5 1998/10/14 09:53:25 peter Exp $
+# $Id: Makefile,v 1.4 1998/09/26 10:51:37 dfr Exp $
LIB= alpha
NOPIC= true
@@ -14,7 +14,7 @@ CFLAGS+= -DDEBUG
CFLAGS+= -I${.CURDIR}/../../common -mno-fp-regs \
-I${.CURDIR}/../../.. -I.
-#CFLAGS+= -DDISK_DEBUG
+CFLAGS+= -DDISK_DEBUG
#CPPFLAGS+= -DNO_DISKLABEL
#CPPFLAGS+= -DSAVE_MEMORY
diff --git a/sys/boot/alpha/libalpha/srmdisk.c b/sys/boot/alpha/libalpha/srmdisk.c
index 6b7d17b8e76d..f7427bdb493f 100644
--- a/sys/boot/alpha/libalpha/srmdisk.c
+++ b/sys/boot/alpha/libalpha/srmdisk.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: srmdisk.c,v 1.3 1998/11/02 23:28:10 msmith Exp $
+ * $Id$
*/
/*
@@ -46,7 +46,6 @@
#include <machine/stdarg.h>
#include <machine/prom.h>
-#include "bootstrap.h"
#include "libalpha.h"
#define SRMDISK_SECSIZE 512
@@ -62,16 +61,18 @@
static int bd_init(void);
static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
-static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
static int bd_open(struct open_file *f, void *vdev);
static int bd_close(struct open_file *f);
-static void bd_print(int verbose);
struct open_disk {
int od_fd;
int od_unit; /* our unit number */
int od_boff; /* block offset from beginning of SRM disk */
int od_flags;
+#define BD_MODEMASK 0x3
+#define BD_MODEINT13 0x0
+#define BD_MODEEDD1 0x1
+#define BD_MODEEDD3 0x2
#define BD_FLOPPY (1<<2)
u_char od_buf[BUFSIZE]; /* transfer buffer (do we want/need this?) */
};
@@ -83,8 +84,7 @@ struct devsw srmdisk = {
bd_strategy,
bd_open,
bd_close,
- noioctl,
- bd_print
+ noioctl
};
/*
@@ -120,23 +120,6 @@ bd_init(void)
}
/*
- * Print information about disks
- */
-static void
-bd_print(int verbose)
-{
- int i;
- char line[80];
-
- for (i = 0; i < nbdinfo; i++) {
- sprintf(line, " disk%d: SRM drive %s", i, bdinfo[i].bd_name);
- pager_output(line);
- /* XXX more detail? */
- pager_output("\n");
- }
-}
-
-/*
* Attempt to open the disk described by (dev) for use by (f).
*
* Note that the philosophy here is "give them exactly what
@@ -324,17 +307,7 @@ bd_close(struct open_file *f)
}
static int
-bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
-{
- struct bcache_devdata bcd;
-
- bcd.dv_strategy = bd_realstrategy;
- bcd.dv_devdata = devdata;
- return(bcache_strategy(&bcd, rw, dblk, size, buf, rsize));
-}
-
-static int
-bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize)
+bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize)
{
prom_return_t ret;
struct open_disk *od = (struct open_disk *)devdata;
diff --git a/sys/boot/alpha/libalpha/start.S b/sys/boot/alpha/libalpha/start.S
index 39c3e48952c6..53063aba11ee 100644
--- a/sys/boot/alpha/libalpha/start.S
+++ b/sys/boot/alpha/libalpha/start.S
@@ -1,5 +1,5 @@
/*
- * $Id: start.S,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
+ * $Id$
* From: $NetBSD: start.S,v 1.4 1998/03/28 00:54:15 cgd Exp $
*/
@@ -51,15 +51,16 @@ NESTED(start, 1, ENTRY_FRAME, ra, 0, 0)
Lstartgp:
LDGP(pv)
+#ifndef PRIMARY_BOOTBLOCK
+ lda sp,start /* start stack below text */
+ lda sp,-ENTRY_FRAME(sp)
+#endif
+
lda a0,_edata
lda a1,_end
subq a1,a0,a1
CALL(bzero)
-#if defined(NETBOOT) || defined(LOADER)
- lda sp,stack + 8192 - ENTRY_FRAME
-#endif
-
CALL(main) /* transfer to C */
XLEAF(_rtt, 0)
@@ -82,7 +83,3 @@ LEAF(cpu_number, 0)
call_pal PAL_VMS_mfpr_whami
RET
END(cpu_number)
-
-#if defined(NETBOOT) || defined(LOADER)
-BSS(stack, 8192)
-#endif
diff --git a/sys/boot/alpha/netboot/Makefile b/sys/boot/alpha/netboot/Makefile
index 927522c4b638..bb4a77ea046d 100644
--- a/sys/boot/alpha/netboot/Makefile
+++ b/sys/boot/alpha/netboot/Makefile
@@ -16,7 +16,8 @@ SRCS+= main.c conf.c dev_net.c
CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
CFLAGS+= -I${.OBJDIR}
-CFLAGS+= -DNETBOOT
+# Verbose ls causes extra heap usage
+CFLAGS+= -DVERBOSE_LS
CLEANFILES+= vers.c vers.o gensetdefs.o gensetdefs setdef0.o setdef1.o \
setdefs.h start.o
@@ -28,7 +29,6 @@ CFLAGS+= -I${LIBSTANDDIR}
CFLAGS+= -I${.CURDIR}/..
CRT= start.o
STRIP=
-BINDIR?= /boot
all: ${BASE}
@@ -49,7 +49,7 @@ ${BASE}.sym: ${OBJS} ${LIBSTAND} ${LIBALPHA} ${CRT} vers.o setdef0.o setdef1.o
vers.o ${LIBSTAND} ${LIBALPHA} ${LIBSTAND} >${.OBJDIR}/${BASE}.list
start.o: ${.CURDIR}/../libalpha/start.S
- ${CC} -c ${CFLAGS} $<
+ ${CC} -c -DPRIMARY_BOOTBLOCK $<
setdef0.o: setdefs.h
diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc
index c29494ba6aef..805b0094eaa2 100644
--- a/sys/boot/common/Makefile.inc
+++ b/sys/boot/common/Makefile.inc
@@ -1,8 +1,7 @@
-# $Id: Makefile.inc,v 1.7 1998/11/02 23:28:10 msmith Exp $
+# $Id: Makefile.inc,v 1.5 1998/09/14 18:27:04 msmith Exp $
-SRCS+= bcache.c boot.c commands.c console.c devopen.c interp.c
-SRCS+= interp_backslash.c interp_parse.c load_aout.c load_elf.c ls.c misc.c
-SRCS+= module.c panic.c
+SRCS+= boot.c commands.c console.c devopen.c interp.c interp_backslash.c
+SRCS+= interp_parse.c load_aout.c load_elf.c ls.c misc.c module.c panic.c
# Machine-independant ISA PnP
.if HAVE_ISABUS
@@ -11,8 +10,3 @@ SRCS+= isapnp.c
.if HAVE_PNP
SRCS+= pnp.c
.endif
-
-# Forth interpreter
-.if BOOT_FORTH
-SRCS+= interp_forth.c
-.endif
diff --git a/sys/boot/common/bcache.c b/sys/boot/common/bcache.c
deleted file mode 100644
index fc12f578f9fa..000000000000
--- a/sys/boot/common/bcache.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*-
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: bcache.c,v 1.3 1998/11/04 00:29:01 msmith Exp $
- */
-
-/*
- * Simple LRU block cache
- */
-
-#include <stand.h>
-#include <string.h>
-#include <bitstring.h>
-
-#include "bootstrap.h"
-
-/* #define BCACHE_DEBUG */
-
-#ifdef BCACHE_DEBUG
-#define BCACHE_TIMEOUT 10
-# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args)
-#else
-#define BCACHE_TIMEOUT 2
-# define DEBUG(fmt, args...)
-#endif
-
-
-struct bcachectl
-{
- daddr_t bc_blkno;
- time_t bc_stamp;
- int bc_count;
-};
-
-static struct bcachectl *bcache_ctl;
-static caddr_t bcache_data;
-static bitstr_t *bcache_miss;
-static int bcache_nblks;
-static int bcache_blksize;
-static int bcache_hits, bcache_misses, bcache_ops, bcache_bypasses;
-static int bcache_bcount;
-
-static void bcache_insert(caddr_t buf, daddr_t blkno);
-static int bcache_lookup(caddr_t buf, daddr_t blkno);
-
-/*
- * Initialise the cache for (nblks) of (bsize).
- */
-int
-bcache_init(int nblks, size_t bsize)
-{
- int i;
-
- /* discard any old contents */
- if (bcache_data != NULL) {
- free(bcache_data);
- bcache_data = NULL;
- free(bcache_ctl);
- }
-
- /* Allocate control structures */
- bcache_nblks = nblks;
- bcache_blksize = bsize;
- bcache_data = malloc(bcache_nblks * bcache_blksize);
- bcache_ctl = (struct bcachectl *)malloc(bcache_nblks * sizeof(struct bcachectl));
- bcache_miss = bit_alloc((bcache_nblks + 1) / 2);
- if ((bcache_data == NULL) || (bcache_ctl == NULL) || (bcache_miss == NULL)) {
- if (bcache_miss)
- free(bcache_miss);
- if (bcache_ctl)
- free(bcache_ctl);
- if (bcache_data)
- free(bcache_data);
- bcache_data = NULL;
- return(ENOMEM);
- }
-
- /* Invalidate the cache */
- for (i = 0; i < bcache_nblks; i++) {
- bcache_ctl[i].bc_count = -1;
- bcache_ctl[i].bc_blkno = -1;
- }
-
- return(0);
-}
-
-/*
- * Handle a transfer request; fill in parts of the request that can
- * be satisfied by the cache, use the supplied strategy routine to do
- * device I/O and then use the I/O results to populate the cache.
- *
- * Requests larger than 1/2 the cache size will be bypassed and go
- * directly to the disk. XXX tune this.
- */
-int
-bcache_strategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf, size_t *rsize)
-{
- struct bcache_devdata *dd = (struct bcache_devdata *)devdata;
- int nblk, p_size;
- daddr_t p_blk;
- caddr_t p_buf;
- int i, j, result;
-
- bcache_ops++;
-
- /* bypass large requests, or when the cache is inactive */
- if ((bcache_data == NULL) || ((size * 2 / bcache_blksize) > bcache_nblks)) {
- DEBUG("bypass %d from %d", size / bcache_blksize, blk);
- bcache_bypasses++;
- return(dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize));
- }
-
- nblk = size / bcache_blksize;
- result = 0;
-
- /* Satisfy any cache hits up front */
- for (i = 0; i < nblk; i++) {
- if (bcache_lookup(buf + (bcache_blksize * i), blk + i)) {
- bit_set(bcache_miss, i); /* cache miss */
- bcache_misses++;
- } else {
- bit_clear(bcache_miss, i); /* cache hit */
- bcache_hits++;
- }
- }
-
- /* Go back and fill in any misses XXX optimise */
- p_blk = -1;
- p_buf = NULL;
- p_size = 0;
- for (i = 0; i < nblk; i++) {
- if (bit_test(bcache_miss, i)) {
- /* miss, add to pending transfer */
- if (p_blk == -1) {
- p_blk = blk + i;
- p_buf = buf + (bcache_blksize * i);
- p_size = 1;
- } else {
- p_size++;
- }
- } else if (p_blk != -1) {
- /* hit, complete pending transfer */
- result = dd->dv_strategy(dd->dv_devdata, rw, p_blk, p_size * bcache_blksize, p_buf, NULL);
- if (result != 0)
- goto done;
- for (j = 0; j < p_size; j++)
- bcache_insert(p_buf + (j * bcache_blksize), p_blk + j);
- p_blk = -1;
- }
- }
- if (p_blk != -1) {
- /* pending transfer left */
- result = dd->dv_strategy(dd->dv_devdata, rw, p_blk, p_size * bcache_blksize, p_buf, NULL);
- if (result != 0)
- goto done;
- for (j = 0; j < p_size; j++)
- bcache_insert(p_buf + (j * bcache_blksize), p_blk + j);
- }
-
- done:
- if ((result == 0) && (rsize != NULL))
- *rsize = size;
- return(result);
-}
-
-
-/*
- * Insert a block into the cache. Retire the oldest block to do so, if required.
- *
- * XXX the LRU algorithm will fail after 2^31 blocks have been transferred.
- */
-static void
-bcache_insert(caddr_t buf, daddr_t blkno)
-{
- time_t now;
- int i, cand, ocount;
-
- time(&now);
- cand = 0; /* assume the first block */
- ocount = bcache_ctl[0].bc_count;
-
- /* find the oldest block */
- for (i = 1; i < bcache_nblks; i++) {
- if (bcache_ctl[i].bc_blkno == blkno) {
- /* reuse old entry */
- cand = i;
- break;
- }
- if (bcache_ctl[i].bc_count < ocount) {
- ocount = bcache_ctl[i].bc_count;
- cand = i;
- }
- }
-
- DEBUG("insert blk %d -> %d @ %d # %d", blkno, cand, now, bcache_bcount);
- bcopy(buf, bcache_data + (bcache_blksize * cand), bcache_blksize);
- bcache_ctl[cand].bc_blkno = blkno;
- bcache_ctl[cand].bc_stamp = now;
- bcache_ctl[cand].bc_count = bcache_bcount++;
-}
-
-/*
- * Look for a block in the cache. Blocks more than BCACHE_TIMEOUT seconds old
- * may be stale (removable media) and thus are discarded. Copy the block out
- * if successful and return zero, or return nonzero on failure.
- */
-static int
-bcache_lookup(caddr_t buf, daddr_t blkno)
-{
- time_t now;
- int i;
-
- time(&now);
-
- for (i = 0; i < bcache_nblks; i++)
- /* cache hit? */
- if ((bcache_ctl[i].bc_blkno == blkno) && ((bcache_ctl[i].bc_stamp + BCACHE_TIMEOUT) >= now)) {
- bcopy(bcache_data + (bcache_blksize * i), buf, bcache_blksize);
- DEBUG("hit blk %d <- %d (now %d then %d)", blkno, i, now, bcache_ctl[i].bc_stamp);
- return(0);
- }
- return(ENOENT);
-}
-
-COMMAND_SET(bcachestat, "bcachestat", "get disk block cache stats", command_bcache);
-
-static int
-command_bcache(int argc, char *argv[])
-{
- int i;
-
- for (i = 0; i < bcache_nblks; i++) {
- printf("%08x %04x %04x|", bcache_ctl[i].bc_blkno, bcache_ctl[i].bc_stamp & 0xffff, bcache_ctl[i].bc_count & 0xffff);
- if (((i + 1) % 4) == 0)
- printf("\n");
- }
- printf("\n%d ops %d bypasses %d hits %d misses\n", bcache_ops, bcache_bypasses, bcache_hits, bcache_misses);
- return(CMD_OK);
-}
-
diff --git a/sys/boot/common/boot.c b/sys/boot/common/boot.c
index 2de8603e881e..608c9d02a921 100644
--- a/sys/boot/common/boot.c
+++ b/sys/boot/common/boot.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: boot.c,v 1.9 1998/10/31 17:12:32 dfr Exp $
+ * $Id: boot.c,v 1.6 1998/10/11 10:10:41 peter Exp $
*/
/*
@@ -38,7 +38,7 @@
static char *getbootfile(int try);
/* List of kernel names to try (may be overwritten by boot.config) XXX should move from here? */
-static char *default_bootfiles = "kernel;kernel.old";
+static char *default_bootfiles = "kernel,kernel.old";
static int autoboot_tried;
@@ -203,13 +203,11 @@ autoboot(int delay, char *prompt)
break;
}
if (ntime != otime) {
- printf("\rBooting [%s] in %d seconds... ", getbootfile(0), (int)(when - ntime));
+ printf("\rBooting [%s] in %d seconds...", getbootfile(0), (int)(when - ntime));
otime = ntime;
cr = 1;
}
}
- if (yes)
- printf("\rBooting [%s]... ", getbootfile(0));
if (cr)
putchar('\n');
if (yes) {
@@ -243,11 +241,11 @@ getbootfile(int try)
spec = default_bootfiles;
while ((try > 0) && (spec != NULL)) {
- spec = strchr(spec, ';');
+ spec = strchr(spec, ',');
try--;
}
if (spec != NULL) {
- if ((ep = strchr(spec, ';')) != NULL) {
+ if ((ep = strchr(spec, ',')) != NULL) {
len = ep - spec;
} else {
len = strlen(spec);
diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index ed450d91602e..84f6d4809764 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -23,11 +23,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bootstrap.h,v 1.17 1999/01/15 00:31:45 abial Exp $
+ * $Id: bootstrap.h,v 1.12 1998/10/09 07:09:22 msmith Exp $
*/
#include <sys/types.h>
-#include <sys/queue.h>
/* XXX debugging */
extern struct console vidconsole;
@@ -56,7 +55,7 @@ extern char command_errbuf[]; /* XXX blah, length */
/* interp.c */
extern void interact(void);
-extern int source(char *filename);
+extern void source(char *filename);
/* interp_parse.c */
extern int parse(int *argc, char ***argv, char *str);
@@ -72,15 +71,6 @@ extern size_t strlenout(vm_offset_t str);
extern char *strdupout(vm_offset_t str);
/*
- * Disk block cache
- */
-struct bcache_devdata
-{
- int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, void *buf, size_t *rsize);
- void *dv_devdata;
-};
-
-/*
* Modular console support.
*/
struct console
@@ -104,44 +94,33 @@ extern void cons_probe(void);
/*
* Plug-and-play enumerator/configurator interface.
*/
-struct pnphandler
+struct pnpident
{
- char *pp_name; /* handler/bus name */
- void (* pp_enumerate)(void); /* enumerate PnP devices, add to chain */
+ char *id_ident; /* ASCII identifier, actual format varies with bus/handler */
+ struct pnpident *id_next; /* the next identifier */
};
-struct pnpident
+struct pnphandler;
+struct pnpinfo
{
- char *id_ident; /* ASCII identifier, actual format varies with bus/handler */
- STAILQ_ENTRY(pnpident) id_link;
+ struct pnpident *pi_ident; /* list of identifiers */
+ int pi_revision; /* optional revision (or -1) if not supported */
+ char *pi_module; /* module/args nominated to handle device */
+ int pi_argc; /* module arguments */
+ char **pi_argv;
+ struct pnphandler *pi_handler; /* handler which detected this device */
+ struct pnpinfo *pi_next;
};
-struct pnpinfo
+struct pnphandler
{
- char *pi_desc; /* ASCII description, optional */
- int pi_revision; /* optional revision (or -1) if not supported */
- char *pi_module; /* module/args nominated to handle device */
- int pi_argc; /* module arguments */
- char **pi_argv;
- struct pnphandler *pi_handler; /* handler which detected this device */
- STAILQ_HEAD(,pnpident) pi_ident; /* list of identifiers */
- STAILQ_ENTRY(pnpinfo) pi_link;
+ char *pp_name; /* handler/bus name */
+ void (* pp_enumerate)(struct pnpinfo **); /* add detected devices to chain */
};
extern struct pnphandler *pnphandlers[]; /* provided by MD code */
extern void pnp_addident(struct pnpinfo *pi, char *ident);
-extern struct pnpinfo *pnp_allocinfo(void);
-extern void pnp_freeinfo(struct pnpinfo *pi);
-extern void pnp_addinfo(struct pnpinfo *pi);
-extern char *pnp_eisaformat(u_int8_t *data);
-
-/*
- * < 0 - No ISA in system
- * == 0 - Maybe ISA, search for read data port
- * > 0 - ISA in system, value is read data port address
- */
-extern int isapnp_readport;
/*
* Module metadata header.
@@ -201,53 +180,58 @@ extern vm_offset_t aout_findsym(char *name, struct loaded_module *mp);
extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
-#ifndef NEW_LINKER_SET
-#include <sys/linker_set.h>
-
-/* XXX just for conversion's sake, until we move to the new linker set code */
-
-#define SET_FOREACH(pvar, set) \
- for (pvar = set.ls_items; \
- pvar < set.ls_items + set.ls_length; \
- pvar++)
-
-#else /* NEW_LINKER_SET */
+#if defined(__ELF__)
/*
- * Private macros, not to be used outside this header file.
+ * Alpha GAS needs an align before the section change. It seems to assume
+ * that after the .previous, it is aligned, so the following .align 3 is
+ * ignored. Since the previous instructions often contain strings, this is
+ * a problem.
*/
-#define __MAKE_SET(set, sym) \
- static void *__CONCAT(__setentry,__LINE__) \
- __attribute__((__section__("set_" #set),__unused__)) = &sym
-#define __SET_BEGIN(set) \
- ({ extern void *__CONCAT(__start_set_,set); \
- &__CONCAT(__start_set_,set); })
-#define __SET_END(set) \
- ({ extern void *__CONCAT(__stop_set_,set); \
- &__CONCAT(__stop_set_,set); })
-/*
- * Public macros.
- */
+#ifdef __alpha__
+#define MAKE_SET(set, sym) \
+ static void const * const __set_##set##_sym_##sym = &sym; \
+ __asm(".align 3"); \
+ __asm(".section .set." #set ",\"aw\""); \
+ __asm(".quad " #sym); \
+ __asm(".previous")
+#else
+#define MAKE_SET(set, sym) \
+ static void const * const __set_##set##_sym_##sym = &sym; \
+ __asm(".section .set." #set ",\"aw\""); \
+ __asm(".long " #sym); \
+ __asm(".previous")
+#endif
+#define TEXT_SET(set, sym) MAKE_SET(set, sym)
+#define DATA_SET(set, sym) MAKE_SET(set, sym)
+#define BSS_SET(set, sym) MAKE_SET(set, sym)
+#define ABS_SET(set, sym) MAKE_SET(set, sym)
-/* Add an entry to a set. */
-#define TEXT_SET(set, sym) __MAKE_SET(set, sym)
-#define DATA_SET(set, sym) __MAKE_SET(set, sym)
-#define BSS_SET(set, sym) __MAKE_SET(set, sym)
-#define ABS_SET(set, sym) __MAKE_SET(set, sym)
+#else
/*
- * Iterate over all the elements of a set.
- *
- * Sets always contain addresses of things, and "pvar" points to words
- * containing those addresses. Thus is must be declared as "type **pvar",
- * and the address of each set item is obtained inside the loop by "*pvar".
+ * Linker set support, directly from <sys/kernel.h>
+ *
+ * NB: the constants defined below must match those defined in
+ * ld/ld.h. Since their calculation requires arithmetic, we
+ * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
*/
-#define SET_FOREACH(pvar, set) \
- for (pvar = (__typeof__(pvar))__SET_BEGIN(set); \
- pvar < (__typeof__(pvar))__SET_END(set); pvar++)
+#define MAKE_SET(set, sym, type) \
+ static void const * const __set_##set##_sym_##sym = &sym; \
+ __asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym)
+#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
+#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
+#define BSS_SET(set, sym) MAKE_SET(set, sym, 27)
+#define ABS_SET(set, sym) MAKE_SET(set, sym, 21)
+
#endif
+struct linker_set {
+ int ls_length;
+ const void *ls_items[1]; /* really ls_length of them, trailing NULL */
+};
+
/*
* Support for commands
*/
diff --git a/sys/boot/common/commands.c b/sys/boot/common/commands.c
index fe0eb54d7707..77cc43ca0e71 100644
--- a/sys/boot/common/commands.c
+++ b/sys/boot/common/commands.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: commands.c,v 1.8 1999/01/09 02:34:48 msmith Exp $
+ * $Id: commands.c,v 1.4 1998/10/07 02:38:26 msmith Exp $
*/
#include <stand.h>
@@ -34,181 +34,35 @@
char *command_errmsg;
char command_errbuf[256]; /* XXX should have procedural interface for setting, size limit? */
-
-
-/*
- * Help is read from a formatted text file.
- *
- * Entries in the file are formatted as
-
-# Ttopic [Ssubtopic] Ddescription
-help
-text
-here
-#
-
- *
- * Note that for code simplicity's sake, the above format must be followed
- * exactly.
- *
- * Subtopic entries must immediately follow the topic (this is used to
- * produce the listing of subtopics).
- *
- * If no argument(s) are supplied by the user, the help for 'help' is displayed.
- */
-COMMAND_SET(help, "help", "detailed help", command_help);
-
-static int
-help_getnext(int fd, char **topic, char **subtopic, char **desc)
-{
- char line[81], *cp, *ep;
-
- for (;;) {
- if (fgetstr(line, 80, fd) < 0)
- return(0);
-
- if ((strlen(line) < 3) || (line[0] != '#') || (line[1] != ' '))
- continue;
-
- *topic = *subtopic = *desc = NULL;
- cp = line + 2;
- while((cp != NULL) && (*cp != 0)) {
- ep = strchr(cp, ' ');
- if ((*cp == 'T') && (*topic == NULL)) {
- if (ep != NULL)
- *ep++ = 0;
- *topic = strdup(cp + 1);
- } else if ((*cp == 'S') && (*subtopic == NULL)) {
- if (ep != NULL)
- *ep++ = 0;
- *subtopic = strdup(cp + 1);
- } else if (*cp == 'D') {
- *desc = strdup(cp + 1);
- ep = NULL;
- }
- cp = ep;
- }
- if (*topic == NULL) {
- if (*subtopic != NULL)
- free(*subtopic);
- if (*desc != NULL)
- free(*desc);
- continue;
- }
- return(1);
- }
-}
-
-static void
-help_emitsummary(char *topic, char *subtopic, char *desc)
-{
- int i;
- pager_output(" ");
- pager_output(topic);
- i = strlen(topic);
- if (subtopic != NULL) {
- pager_output(" ");
- pager_output(subtopic);
- i += strlen(subtopic) + 1;
- }
- if (desc != NULL) {
- do {
- pager_output(" ");
- } while (i++ < 30);
- pager_output(desc);
- }
- pager_output("\n");
-}
+COMMAND_SET(help, "help", "detailed help", command_help);
-
static int
-command_help(int argc, char *argv[])
+command_help(int argc, char *argv[])
{
- char buf[81]; /* XXX buffer size? */
- int hfd, matched, doindex;
- char *topic, *subtopic, *t, *s, *d;
+ char helppath[80]; /* XXX buffer size? */
/* page the help text from our load path */
- sprintf(buf, "%s/boot/loader.help", getenv("loaddev"));
- if ((hfd = open(buf, O_RDONLY)) < 0) {
+ sprintf(helppath, "%s/boot/boot.help", getenv("loaddev"));
+ printf("%s\n", helppath);
+ if (pager_file(helppath) == -1)
printf("Verbose help not available, use '?' to list commands\n");
- return(CMD_OK);
- }
-
- /* pick up request from arguments */
- topic = subtopic = NULL;
- switch(argc) {
- case 3:
- subtopic = strdup(argv[2]);
- case 2:
- topic = strdup(argv[1]);
- break;
- case 1:
- topic = strdup("help");
- break;
- default:
- command_errmsg = "usage is 'help <topic> [<subtopic>]";
- return(CMD_ERROR);
- }
-
- /* magic "index" keyword */
- doindex = !strcmp(topic, "index");
- matched = doindex;
-
- /* Scan the helpfile looking for help matching the request */
- pager_open();
- while(help_getnext(hfd, &t, &s, &d)) {
-
- if (doindex) { /* dink around formatting */
- help_emitsummary(t, s, d);
-
- } else if (strcmp(topic, t)) {
- /* topic mismatch */
- if(matched) /* nothing more on this topic, stop scanning */
- break;
-
- } else {
- /* topic matched */
- matched = 1;
- if (((subtopic == NULL) && (s == NULL)) ||
- ((subtopic != NULL) && (s != NULL) && !strcmp(subtopic, s))) {
- /* exact match, print text */
- while((fgetstr(buf, 80, hfd) >= 0) && (buf[0] != '#')) {
- pager_output(buf);
- pager_output("\n");
- }
- } else if ((subtopic == NULL) && (s != NULL)) {
- /* topic match, list subtopics */
- help_emitsummary(t, s, d);
- }
- }
- free(t);
- free(s);
- free(d);
- }
- pager_close();
- close(hfd);
- if (!matched) {
- sprintf(command_errbuf, "no help available for '%s'", topic);
- return(CMD_ERROR);
- }
return(CMD_OK);
}
-
COMMAND_SET(commandlist, "?", "list commands", command_commandlist);
static int
command_commandlist(int argc, char *argv[])
{
struct bootblk_command **cmdp;
+ int i;
printf("Available commands:\n");
- SET_FOREACH(cmdp, Xcommand_set) {
- if (((*cmdp)->c_name != NULL) && ((*cmdp)->c_desc != NULL))
- printf(" %-15s %s\n", (*cmdp)->c_name, (*cmdp)->c_desc);
- }
+ cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
+ for (i = 0; i < Xcommand_set.ls_length; i++)
+ if ((cmdp[i]->c_name != NULL) && (cmdp[i]->c_desc != NULL))
+ printf(" %-15s %s\n", cmdp[i]->c_name, cmdp[i]->c_desc);
return(CMD_OK);
}
@@ -299,7 +153,6 @@ command_echo(int argc, char *argv[])
nl = 0;
optind = 1;
- optreset = 1;
while ((ch = getopt(argc, argv, "n")) != -1) {
switch(ch) {
case 'n':
@@ -344,7 +197,6 @@ command_read(int argc, char *argv[])
timeout = -1;
prompt = NULL;
optind = 1;
- optreset = 1;
while ((c = getopt(argc, argv, "p:t:")) != -1) {
switch(c) {
@@ -382,47 +234,3 @@ command_read(int argc, char *argv[])
setenv(name, buf, 1);
return(CMD_OK);
}
-
-/*
- * List all disk-like devices
- */
-COMMAND_SET(lsdev, "lsdev", "list all devices", command_lsdev);
-
-static int
-command_lsdev(int argc, char *argv[])
-{
- int verbose, ch, i;
- char line[80];
-
- verbose = 0;
- optind = 1;
- optreset = 1;
- while ((ch = getopt(argc, argv, "v")) != -1) {
- switch(ch) {
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- /* getopt has already reported an error */
- return(CMD_OK);
- }
- }
- argv += (optind);
- argc -= (optind);
-
- pager_open();
- for (i = 0; devsw[i] != NULL; i++) {
- if (devsw[i]->dv_print != NULL){
- sprintf(line, "%s @ %p\n", devsw[i]->dv_name, devsw[i]->dv_print);
- pager_output(line);
- devsw[i]->dv_print(verbose);
- } else {
- sprintf(line, "%s: (unknown)\n", devsw[i]->dv_name);
- pager_output(line);
- }
- }
- pager_close();
- return(CMD_OK);
-}
-
diff --git a/sys/boot/common/console.c b/sys/boot/common/console.c
index 8c4377f2bcd4..b9534d304030 100644
--- a/sys/boot/common/console.c
+++ b/sys/boot/common/console.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: console.c,v 1.3 1998/10/11 10:19:11 peter Exp $
+ * $Id: console.c,v 1.2 1998/09/26 01:29:13 msmith Exp $
*/
#include <stand.h>
@@ -150,12 +150,8 @@ cons_set(struct env_var *ev, int flags, void *value)
{
int cons, active;
- if ((value == NULL) || ((active = cons_find(value)) == -1)) {
- if (value != NULL)
- printf("no such console '%s'\n", (char *)value);
- printf("Available consoles:\n");
- for (cons = 0; consoles[cons] != NULL; cons++)
- printf(" %s\n", consoles[cons]->c_name);
+ if ((active = cons_find(value)) == -1) {
+ printf("no such console '%s'\n", (char *)value);
return(CMD_ERROR);
}
diff --git a/sys/boot/common/help.common b/sys/boot/common/help.common
deleted file mode 100644
index e467b1ca7092..000000000000
--- a/sys/boot/common/help.common
+++ /dev/null
@@ -1,262 +0,0 @@
-################################################################################
-# Thelp DDisplay command help
-
- help [topic [subtopic]]
- ?
-
- The help command displays help on commands and their usage.
-
- In command help, a term enclosed with <...> indicates a value as
- described by the term. A term enclosed with [...] is optional,
- and may not be required by all forms of the command.
-
- Some commands may not be availalble. Use the '?' command to list
- most available commands.
-
-################################################################################
-# Tautoboot DBoot after a delay
-
- autoboot [<delay> [<prompt>]]
-
- Displays <prompt> or a default prompt, and counts down <delay> seconds
- before attempting to boot. If <delay> is not specified, the default
- value is 10.
-
-################################################################################
-# Tboot DBoot immediately
-
- boot [-<arg> ...] [<kernelname>]
-
- Boot the system. If arguments are specified, they are added to the
- arguments for the kernel. If <kernelname> is specified, and a kernel
- has not already been loaded, it will be booted instead of the default
- kernel.
-
-################################################################################
-# Techo DEcho arguments
-
- echo [-n] [<message>]
-
- Emits <message>, with no trailing newline if -n is specified. This is
- most useful in conjunction with scripts and the '@' line prefix.
-
- Variables are substituted by prefixing them with $, eg.
-
- echo Current device is $currdev
-
- will print the current device.
-
-################################################################################
-# Tload DLoad a kernel or module
-
- load [-t <type>] <filename>
-
- Loads the module contained in <filename> into memory. If no other
- modules are loaded, <filename> must be a kernel or the command will
- fail.
-
- If -t is specified, the module is loaded as raw data of <type>, for
- later use by the kernel or other modules. <type> may be any string.
-
-################################################################################
-# Tls DList files
-
- ls [-l] [<path>]
-
- Displays a listing of files in the directory <path>, or the root
- directory of the current device if <path> is not specified.
-
- The -l argument displays file sizes as well; the process of obtaining
- file sizes on some media may be very slow.
-
-################################################################################
-# Tlsdev DList devices
-
- lsdev [-v]
-
- List all of the devices from which it may be possible to load modules.
- If -v is specified, print more details.
-
-################################################################################
-# Tlsmod DList modules
-
- lsmod [-v]
-
- List loaded modules. If [-v] is specified, print more details.
-
-################################################################################
-# Tpnpscan DScan for PnP devices
-
- pnpscan [-v]
-
- Scan for Plug-and-Play devices. This command is normally automatically
- run as part of the boot process, in order to dynamically load modules
- required for system operation.
-
- If the -v argument is specified, details on the devices found will
- be printed.
-
-################################################################################
-# Tset DSet a variable
-
- set <variable name>
- set <variable name>=<value>
-
- The set command is used to set variables.
-
-################################################################################
-# Tset Sautoboot_delay DSet the default autoboot delay
-
- set autoboot_delay=<value>
-
- Sets the default delay for the autoboot command to <value> seconds.
-
-################################################################################
-# Tset Sbootfile DSet the default boot file set
-
- set bootfile=<filename>[,<filename>...]
-
- The default search path for bootable kernels is /kernel,/kernel.old.
- It may be overridden by setting the bootfile variable to a
- semicolon-separated list of paths, which will be searched for in turn.
-
-################################################################################
-# Tset Sboot_askname DPrompt for root device
-
- set boot_askname
-
- Instructs the kernel to prompt the user for the name of the root device
- when the kernel is booted.
-
-################################################################################
-# Tset Sboot_ddb DDrop to the kernel debugger (DDB)
-
- set boot_ddb
-
- Instructs the kernel to start in the DDB debugger, rather than
- proceeding to initialise when booted.
-
-################################################################################
-# Tset Sboot_gdb DSelect gdb-remote mode
-
- set boot_gdb
-
- Selects gdb-remote mode for the kernel debugger by default.
-
-################################################################################
-# Tset Sboot_single DStart system in single-user mode
-
- set boot_single
-
- Prevents the kernel from initiating a multi-user startup, single-user
- mode will be entered when the kernel has finished device probes.
-
-################################################################################
-# Tset Sboot_verbose DVerbose boot messages
-
- set boot_verbose
-
- Setting this variable causes extra debugging information to be printed
- by the kernel during the boot phase.
-
-################################################################################
-# Tset Sconsole DSet the current console
-
- set console[=<value>]
-
- Sets the current console. If <value> is omitted, a list of valid
- consoles will be displayed.
-
-################################################################################
-# Tset Scurrdev DSet the current device
-
- set currdev=<device>
-
- Selects the default device. Syntax for devices is odd.
-
-################################################################################
-# Tset Smodule_path DSet the module search path
-
- set module_path=<path>[,<path>...]
-
- Sets the list of directories which will be searched in for modules
- named in a load command or implicitly required by a dependancy.
-
-################################################################################
-# Tset Sprompt DSet the command prompt
-
- set prompt=<value>
-
- The command prompt is displayed when the loader is waiting for input.
- Variable substitution is performed on the prompt. The default
- prompt can be set with:
-
- set prompt=\$currdev>
-
-################################################################################
-# Tset Srootdev DSet the root filesystem
-
- set rootdev=<path>
-
- By default the value of $currdev is used to set the root filesystem
- when the kernel is booted. This can be overridden by setting
- $rootdev explicitly.
-
-################################################################################
-# Tshow DShow the values of variables
-
- show [<variable>]
-
- Displays the value of <variable>, or all variables if not specified.
- Multiple paths can be separated with a semicolon.
-
- See the set command for a list of some variables.
-
-################################################################################
-# Tsource DRead commands from a script file
-
- source <filename>
-
- The entire contents of <filename> are read into memory before executing
- commands, so it is safe to source a file from removable media.
-
- A number of modifiers may be prefixed to commands within a script file
- to alter their behaviour:
-
- @ Suppresses the printing of the command when executed.
-
- - Prevents the script from terminating if the command returns
- an error.
-
-################################################################################
-# Tread DRead input from the terminal
-
- read [-t <value>] [-p <prompt>] [<variable name>]
-
- The read command reads a line of input from the terminal. If the
- -t argument is specified, it will return nothing if no input has been
- received after <value> seconds. (Any keypress will cancel the
- timeout).
-
- If -p is specified, <prompt> is printed before reading input. No
- newline is emitted after the prompt.
-
- If a variable name is supplied, the variable is set to the value read,
- less any terminating newline.
-
-################################################################################
-# Tunload DRemove all modules from memory
-
- unload
-
- This command removes any kernel and all loaded modules from memory.
-
-################################################################################
-# Tunset DUnset a variable
-
- unset <variable name>
-
- If allowed, the named variable's value is discarded and the variable
- is removed.
-
-################################################################################
diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c
index 22d2199beebc..d24ed6e3182a 100644
--- a/sys/boot/common/interp.c
+++ b/sys/boot/common/interp.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: interp.c,v 1.11 1999/01/13 21:59:58 abial Exp $
+ * $Id: interp.c,v 1.5 1998/10/07 02:38:26 msmith Exp $
*/
/*
* Simple commandline interpreter, toplevel and misc.
@@ -35,15 +35,6 @@
#include <string.h>
#include "bootstrap.h"
-#ifdef BOOT_FORTH
-#include "ficl.h"
-#define RETURN(x) stackPushINT32(bf_vm->pStack,!x); return(x)
-
-extern FICL_VM *bf_vm;
-#else
-#define RETURN(x) return(x)
-#endif
-
#define MAXARGS 20 /* maximum number of arguments allowed */
static void prompt(void);
@@ -51,10 +42,10 @@ static void prompt(void);
/*
* Perform the command
*/
-int
+static int
perform(int argc, char *argv[])
{
- int result;
+ int i, result;
struct bootblk_command **cmdp;
bootblk_cmd_t *cmd;
@@ -67,17 +58,17 @@ perform(int argc, char *argv[])
cmd = NULL;
result = CMD_ERROR;
- /* search the command set for the command */
- SET_FOREACH(cmdp, Xcommand_set) {
- if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name))
- cmd = (*cmdp)->c_fn;
+ cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
+ for (i = 0; i < Xcommand_set.ls_length; i++) {
+ if ((cmdp[i]->c_name != NULL) && !strcmp(argv[0], cmdp[i]->c_name))
+ cmd = cmdp[i]->c_fn;
}
if (cmd != NULL) {
result = (cmd)(argc, argv);
} else {
command_errmsg = "unknown command";
}
- RETURN(result);
+ return(result);
}
/*
@@ -87,20 +78,13 @@ void
interact(void)
{
char input[256]; /* big enough? */
-#ifndef BOOT_FORTH
int argc;
char **argv;
-#endif
-
-#ifdef BOOT_FORTH
- bf_init();
-#endif
/*
* Read our default configuration
*/
- if(source("/boot/loader.rc")!=CMD_OK)
- source("/boot/boot.conf");
+ source("/boot/boot.conf");
printf("\n");
/*
* Before interacting, we might want to autoboot.
@@ -118,9 +102,6 @@ interact(void)
input[0] = '\0';
prompt();
ngets(input, sizeof(input));
-#ifdef BOOT_FORTH
- bf_run(input);
-#else
if (!parse(&argc, &argv, input)) {
if (perform(argc, argv))
printf("%s: %s\n", argv[0], command_errmsg);
@@ -128,7 +109,6 @@ interact(void)
} else {
printf("parse error\n");
}
-#endif
}
}
@@ -147,12 +127,10 @@ static int
command_source(int argc, char *argv[])
{
int i;
- int res;
- res=CMD_OK;
- for (i = 1; (i < argc) && (res == CMD_OK); i++)
- res=source(argv[i]);
- return(res);
+ for (i = 1; i < argc; i++)
+ source(argv[i]);
+ return(CMD_OK);
}
struct sourceline
@@ -165,18 +143,18 @@ struct sourceline
struct sourceline *next;
};
-int
+void
source(char *filename)
{
struct sourceline *script, *se, *sp;
char input[256]; /* big enough? */
- int argc,res;
+ int argc;
char **argv, *cp;
int fd, flags, line;
if (((fd = open(filename, O_RDONLY)) == -1)) {
- sprintf(command_errbuf,"can't open '%s': %s\n", filename, strerror(errno));
- return(CMD_ERROR);
+ printf("can't open '%s': %s\n", filename, strerror(errno));
+ return;
}
/*
@@ -223,7 +201,6 @@ source(char *filename)
* Execute the script
*/
argv = NULL;
- res = CMD_OK;
for (sp = script; sp != NULL; sp = sp->next) {
/* print if not being quiet */
@@ -237,16 +214,13 @@ source(char *filename)
if ((argc > 0) && (perform(argc, argv) != 0)) {
/* normal command */
printf("%s: %s\n", argv[0], command_errmsg);
- if (!(sp->flags & SL_IGNOREERR)) {
- res=CMD_ERROR;
+ if (!(sp->flags & SL_IGNOREERR))
break;
- }
}
free(argv);
argv = NULL;
} else {
printf("%s line %d: parse error\n", filename, sp->line);
- res=CMD_ERROR;
break;
}
}
@@ -257,7 +231,6 @@ source(char *filename)
script = script->next;
free(se);
}
- return(res);
}
/*
diff --git a/sys/boot/common/interp_backslash.c b/sys/boot/common/interp_backslash.c
index 6de118ec63fc..8807fdaa9645 100644
--- a/sys/boot/common/interp_backslash.c
+++ b/sys/boot/common/interp_backslash.c
@@ -11,7 +11,7 @@
* Jordan K. Hubbard
* 29 August 1998
*
- * $Id: interp_backslash.c,v 1.2 1998/09/03 06:14:41 jkh Exp $
+ * $Id: interp_backslash.c,v 1.1 1998/09/01 00:41:24 msmith Exp $
*
* Routine for doing backslash elimination.
*/
@@ -52,10 +52,9 @@ backslash(char *str)
str++;
break;
- /* preserve backslashed quotes, dollar signs */
+ /* preserve backslashed quotes */
case '\'':
case '"':
- case '$':
new_str[i++] = '\\';
new_str[i++] = *str++;
break;
diff --git a/sys/boot/common/interp_forth.c b/sys/boot/common/interp_forth.c
deleted file mode 100644
index 68e09340b0ad..000000000000
--- a/sys/boot/common/interp_forth.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: interp_forth.c,v 1.8 1998/12/22 11:41:51 abial Exp $
- */
-
-#include <string.h>
-#include <stand.h>
-#include "bootstrap.h"
-#include "ficl.h"
-
-/* #define BFORTH_DEBUG */
-
-#ifdef BFORTH_DEBUG
-# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args)
-#else
-# define DEBUG(fmt, args...)
-#endif
-
-/*
- * BootForth Interface to Ficl Forth interpreter.
- */
-
-FICL_VM *bf_vm;
-
-/*
- * Shim for taking commands from BF and passing them out to 'standard'
- * argv/argc command functions.
- */
-static void
-bf_command(FICL_VM *vm)
-{
- char *name, *line, *tail, *cp;
- int len;
- struct bootblk_command **cmdp;
- bootblk_cmd_t *cmd;
- int argc, result;
- char **argv;
-
- /* Get the name of the current word */
- name = vm->runningWord->name;
-
- /* Find our command structure */
- cmd = NULL;
- SET_FOREACH(cmdp, Xcommand_set) {
- if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name))
- cmd = (*cmdp)->c_fn;
- }
- if (cmd == NULL)
- panic("callout for unknown command '%s'", name);
-
- /* Get remainder of invocation */
- tail = vmGetInBuf(vm);
- for (cp = tail, len = 0; *cp != 0 && *cp != '\n'; cp++, len++)
- ;
-
- line = malloc(strlen(name) + len + 2);
- strcpy(line, name);
- if (len > 0) {
- strcat(line, " ");
- strncat(line, tail, len);
- vmUpdateTib(vm, tail + len);
- }
- DEBUG("cmd '%s'", line);
-
- command_errmsg = command_errbuf;
- command_errbuf[0] = 0;
- if (!parse(&argc, &argv, line)) {
- result = (cmd)(argc, argv);
- free(argv);
- if(result != 0) {
- vmTextOut(vm,argv[0],0);
- vmTextOut(vm,": ",0);
- vmTextOut(vm,command_errmsg,1);
- }
- } else {
- vmTextOut(vm, "parse error\n", 1);
- result=1;
- }
- free(line);
- stackPushINT32(vm->pStack,!result);
-}
-
-/*
- * Initialise the Forth interpreter, create all our commands as words.
- */
-void
-bf_init(void)
-{
- struct bootblk_command **cmdp;
- int fd;
-
- ficlInitSystem(4000); /* Default dictionary ~4000 cells */
- bf_vm = ficlNewVM();
-
- /* make all commands appear as Forth words */
- SET_FOREACH(cmdp, Xcommand_set)
- ficlBuild((*cmdp)->c_name, bf_command, FW_DEFAULT);
-
- /* try to load and run init file if present */
- if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) {
- (void)ficlExecFD(bf_vm, fd);
- close(fd);
- }
-}
-
-/*
- * Feed a line of user input to the Forth interpreter
- */
-void
-bf_run(char *line)
-{
- int result;
-
- result = ficlExec(bf_vm, line);
- DEBUG("ficlExec '%s' = %d", line, result);
-
- if (result == VM_USEREXIT)
- panic("interpreter exit");
-}
diff --git a/sys/boot/common/interp_parse.c b/sys/boot/common/interp_parse.c
index 865c8cbc0501..ef235632bd66 100644
--- a/sys/boot/common/interp_parse.c
+++ b/sys/boot/common/interp_parse.c
@@ -11,7 +11,7 @@
* Jordan K. Hubbard
* 29 August 1998
*
- * $Id: interp_parse.c,v 1.5 1999/01/10 05:08:12 msmith Exp $
+ * $Id: interp_parse.c,v 1.3 1998/09/04 02:43:26 msmith Exp $
*
* The meat of the simple parser.
*/
@@ -100,11 +100,7 @@ parse(int *argc, char ***argv, char *str)
while (*p) {
switch (state) {
case STR:
- if ((*p == '\\') && p[1]) {
- p++;
- PARSE_FAIL(i == (PARSE_BUFSIZE - 1));
- buf[i++] = *p++;
- } else if (isquote(*p)) {
+ if (isquote(*p)) {
quote = quote ? 0 : *p;
++p;
}
diff --git a/sys/boot/common/isapnp.c b/sys/boot/common/isapnp.c
index 865e8f683e15..cc28da6c954f 100644
--- a/sys/boot/common/isapnp.c
+++ b/sys/boot/common/isapnp.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: isapnp.c,v 1.3 1998/10/21 20:07:04 msmith Exp $
+ * $Id: isapnp.c,v 1.1 1998/09/18 00:24:25 msmith Exp $
*/
/*
@@ -43,17 +43,17 @@ static void isapnp_write(int d, u_char r);
static u_char isapnp_read(int d);
static void isapnp_send_Initiation_LFSR();
static int isapnp_get_serial(u_int8_t *p);
-static int isapnp_isolation_protocol(void);
-static void isapnp_enumerate(void);
+static int isapnp_isolation_protocol(struct pnpinfo **pnplist);
+static void isapnp_enumerate(struct pnpinfo **pnplist);
/* PnP read data port */
-int isapnp_readport = 0;
+static int pnp_rd_port;
#define _PNP_ID_LEN 9
struct pnphandler isapnphandler =
{
- "ISA bus",
+ "isapnp",
isapnp_enumerate
};
@@ -68,7 +68,7 @@ static u_char
isapnp_read(int d)
{
outb (_PNP_ADDRESS, d);
- return (inb(isapnp_readport));
+ return (inb(3 | (pnp_rd_port <<2)));
}
/*
@@ -104,11 +104,11 @@ isapnp_get_serial(u_int8_t *data)
bzero(data, _PNP_ID_LEN);
outb(_PNP_ADDRESS, SERIAL_ISOLATION);
for (i = 0; i < 72; i++) {
- bit = inb(isapnp_readport) == 0x55;
+ bit = inb((pnp_rd_port << 2) | 0x3) == 0x55;
delay(250); /* Delay 250 usec */
/* Can't Short Circuit the next evaluation, so 'and' is last */
- bit = (inb(isapnp_readport) == 0xaa) && bit;
+ bit = (inb((pnp_rd_port << 2) | 0x3) == 0xaa) && bit;
delay(250); /* Delay 250 usec */
valid = valid || bit;
@@ -126,112 +126,87 @@ isapnp_get_serial(u_int8_t *data)
}
/*
- * Fills the buffer with resource info from the device.
- * Returns nonzero if the device fails to report
+ * Format a pnp id as a string in standard ISA PnP format, AAAIIRR
+ * where 'AAA' is the EISA ID, II is the product ID and RR the revision ID.
*/
-static int
-isapnp_get_resource_info(u_int8_t *buffer, int len)
+static char *
+isapnp_format(u_int8_t *data)
{
- int i, j;
- u_char temp;
-
- for (i = 0; i < len; i++) {
- outb(_PNP_ADDRESS, STATUS);
- for (j = 0; j < 100; j++) {
- if ((inb(isapnp_readport)) & 0x1)
- break;
- delay(1);
- }
- if (j == 100) {
- printf("PnP device failed to report resource data\n");
- return(1);
- }
- outb(_PNP_ADDRESS, RESOURCE_DATA);
- temp = inb(isapnp_readport);
- if (buffer != NULL)
- buffer[i] = temp;
- }
- return(0);
+ static char idbuf[8];
+ const char hextoascii[] = "0123456789abcdef";
+
+ idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
+ idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
+ idbuf[2] = '@' + (data[1] & 0x1f);
+ idbuf[3] = hextoascii[(data[2] >> 4)];
+ idbuf[4] = hextoascii[(data[2] & 0xf)];
+ idbuf[5] = hextoascii[(data[3] >> 4)];
+ idbuf[6] = hextoascii[(data[3] & 0xf)];
+ idbuf[7] = 0;
}
/*
- * Scan Resource Data for useful information.
- *
- * We scan the resource data for compatible device IDs and
- * identifier strings; we only take the first identifier string
- * and assume it's for the card as a whole.
- *
- * Returns 0 if the scan completed OK, nonzero on error.
+ * Try to read a compatible device ID from the current device, return
+ * 1 if we found one.
*/
+#define READ_RSC(c) {while ((isapnp_read(STATUS) & 1) == 0); (c) = isapnp_read(RESOURCE_DATA);}
static int
-isapnp_scan_resdata(struct pnpinfo *pi)
+isapnp_getid(u_int8_t *data)
{
- u_char tag, resinfo[8];
- int large_len, limit;
- char *str;
-
- limit = 1000;
- while ((limit-- > 0) && !isapnp_get_resource_info(&tag, 1)) {
- if (PNP_RES_TYPE(tag) == 0) {
- /* Small resource */
- switch (PNP_SRES_NUM(tag)) {
-
- case COMP_DEVICE_ID:
- /* Got a compatible device id resource */
- if (isapnp_get_resource_info(resinfo, PNP_SRES_LEN(tag)))
- return(1);
- pnp_addident(pi, pnp_eisaformat(resinfo));
-
- case END_TAG:
- return(0);
- break;
-
- default:
- /* Skip this resource */
- if (isapnp_get_resource_info(NULL, PNP_SRES_LEN(tag)))
- return(1);
- break;
- }
- } else {
- /* Large resource */
- if (isapnp_get_resource_info(resinfo, 2))
+ int discard, pos, len;
+ u_int8_t c, t;
+
+ discard = 0;
+ len = 0;
+ pos = 0;
+
+ for (;;) {
+ READ_RSC(c);
+ /* skipping junk? */
+ if (discard > 0) {
+ discard--;
+ continue;
+ }
+ /* copying data? */
+ if (len > 0) {
+ data[pos++] = c;
+ /* got all data? */
+ if (pos >= len)
return(1);
-
- large_len = resinfo[1];
- large_len = (large_len << 8) + resinfo[0];
-
- switch(PNP_LRES_NUM(tag)) {
-
- case ID_STRING_ANSI:
- str = malloc(large_len + 1);
- if (isapnp_get_resource_info(str, large_len)) {
- free(str);
- return(1);
- }
- str[large_len] = 0;
- if (pi->pi_desc == NULL) {
- pi->pi_desc = str;
- } else {
- free(str);
- }
- break;
-
- default:
- /* Large resource, skip it */
- if (isapnp_get_resource_info(NULL, large_len))
- return(1);
- }
}
+ /* resource type */
+ if (c & 0x80) { /* large resource, throw it away */
+ if (c == 0xff)
+ return(0); /* end of resources */
+ READ_RSC(c);
+ discard = c;
+ READ_RSC(c);
+ discard += ((int)c << 8);
+ continue;
+ }
+ /* small resource */
+ t = (c >> 3) & 0xf;
+ if (t == 0xf)
+ return(0); /* end of resources */
+ if ((t == LOG_DEVICE_ID) || (t == COMP_DEVICE_ID)) {
+ len = c & 7;
+ pos = 0;
+ continue;
+ }
+ discard = c & 7; /* unwanted small resource */
}
- return(1);
+
}
+
/*
- * Run the isolation protocol. Upon exiting, all cards are aware that
- * they should use isapnp_readport as the READ_DATA port.
+ * Run the isolation protocol. Use pnp_rd_port as the READ_DATA port
+ * value (caller should try multiple READ_DATA locations before giving
+ * up). Upon exiting, all cards are aware that they should use
+ * pnp_rd_port as the READ_DATA port.
*/
static int
-isapnp_isolation_protocol(void)
+isapnp_isolation_protocol(struct pnpinfo **pilist)
{
int csn;
struct pnpinfo *pi;
@@ -246,32 +221,30 @@ isapnp_isolation_protocol(void)
for (csn = 1; ; csn++) {
/* Wake up cards without a CSN (ie. all of them) */
isapnp_write(WAKE, 0);
- isapnp_write(SET_RD_DATA, (isapnp_readport >> 2));
+ isapnp_write(SET_RD_DATA, pnp_rd_port);
outb(_PNP_ADDRESS, SERIAL_ISOLATION);
delay(1000); /* Delay 1 msec */
if (isapnp_get_serial(cardid)) {
isapnp_write(SET_CSN, csn);
- pi = pnp_allocinfo();
+ pi = malloc(sizeof(struct pnpinfo));
+ pi->pi_next = *pilist;
+ *pilist = pi;
ndevs++;
- pnp_addident(pi, pnp_eisaformat(cardid));
/* scan the card obtaining all the identifiers it holds */
- if (isapnp_scan_resdata(pi)) {
- pnp_freeinfo(pi); /* error getting data, ignore */
- } else {
- pnp_addinfo(pi);
+ while (isapnp_getid(cardid)) {
+ printf(" %s\n", isapnp_format(cardid));
+ pnp_addident(pi, isapnp_format(cardid));
}
- } else {
+ } else
break;
- }
}
/* Move all cards to wait-for-key state */
- while (--csn > 0) {
+ while (csn >= 0) {
isapnp_send_Initiation_LFSR();
isapnp_write(WAKE, csn);
isapnp_write(CONFIG_CONTROL, 0x02);
delay(1000); /* XXX is it really necessary ? */
- csn--;
}
return(ndevs);
}
@@ -280,40 +253,17 @@ isapnp_isolation_protocol(void)
* Locate ISA-PnP devices and populate the supplied list.
*/
static void
-isapnp_enumerate(void)
+isapnp_enumerate(struct pnpinfo **pnplist)
{
- int pnp_rd_port;
-
- /* Check for I/O port access */
- if ((archsw.arch_isainb == NULL) || (archsw.arch_isaoutb == NULL))
- return;
-
- /*
- * Validate a possibly-suggested read port value. If the autoscan failed
- * last time, this will return us to autoscan mode again.
- */
- if ((isapnp_readport > 0) &&
- (((isapnp_readport < 0x203) ||
- (isapnp_readport > 0x3ff) ||
- (isapnp_readport & 0x3) != 0x3)))
- /* invalid, go look for ourselves */
- isapnp_readport = 0;
-
- if (isapnp_readport < 0) {
- /* someone is telling us there is no ISA in the system */
- return;
-
- } else if (isapnp_readport > 0) {
- /* Someone has told us where the port is/should be, or we found one last time */
- isapnp_isolation_protocol();
-
- } else {
- /* No clues, look for it ourselves */
- for (pnp_rd_port = 0x80; pnp_rd_port < 0xff; pnp_rd_port += 0x10) {
- /* Look for something, quit when we find it */
- isapnp_readport = (pnp_rd_port << 2) | 0x3;
- if (isapnp_isolation_protocol() > 0)
- break;
- }
+ int devs;
+
+ for (pnp_rd_port = 0x80; pnp_rd_port < 0xff; pnp_rd_port += 0x10) {
+
+ /* Look for something, quit when we find it */
+ if ((devs = isapnp_isolation_protocol(pnplist)) > 0)
+ break;
}
+ printf("Found %d ISA PnP devices\n", devs);
}
+
+
diff --git a/sys/boot/common/isapnp.h b/sys/boot/common/isapnp.h
index 0b3b9ec88527..6c072824867e 100644
--- a/sys/boot/common/isapnp.h
+++ b/sys/boot/common/isapnp.h
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: isapnp.h,v 1.1 1998/09/18 00:24:25 msmith Exp $
+ * $Id: pnp.h,v 1.6 1998/01/10 07:41:43 kato Exp $
*/
#ifndef _I386_ISA_PNP_H_
@@ -210,12 +210,6 @@
/*** 32-bit memory accesses are at 0x76 ***/
-/* Macros to parse Resource IDs */
-#define PNP_RES_TYPE(a) (a >> 7)
-#define PNP_SRES_NUM(a) (a >> 3)
-#define PNP_SRES_LEN(a) (a & 0x07)
-#define PNP_LRES_NUM(a) (a & 0x7f)
-
/* Small Resource Item names */
#define PNP_VERSION 0x1
#define LOG_DEVICE_ID 0x2
diff --git a/sys/boot/common/load_aout.c b/sys/boot/common/load_aout.c
index 6d33ad49f367..3a5d34d15a6b 100644
--- a/sys/boot/common/load_aout.c
+++ b/sys/boot/common/load_aout.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: load_aout.c,v 1.10 1998/10/12 09:05:12 peter Exp $
+ * $Id: load_aout.c,v 1.9 1998/10/09 23:15:39 peter Exp $
*/
#include <sys/param.h>
@@ -223,34 +223,30 @@ aout_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, struct ex
/* symbol table size */
ssym = addr;
- if(ehdr->a_syms!=NULL) {
- archsw.arch_copyin(&ehdr->a_syms, addr, sizeof(ehdr->a_syms));
- addr += sizeof(ehdr->a_syms);
+ archsw.arch_copyin(&ehdr->a_syms, addr, sizeof(ehdr->a_syms));
+ addr += sizeof(ehdr->a_syms);
- /* symbol table */
- printf("symbols=[0x%x+0x%lx", sizeof(ehdr->a_syms), ehdr->a_syms);
- if (archsw.arch_readin(fd, addr, ehdr->a_syms) != ehdr->a_syms)
- return(0);
- addr += ehdr->a_syms;
-
- /* string table */
- read(fd, &ss, sizeof(ss));
- archsw.arch_copyin(&ss, addr, sizeof(ss));
- addr += sizeof(ss);
- ss -= sizeof(ss);
- printf("+0x%x+0x%x]", sizeof(ss), ss);
- if (archsw.arch_readin(fd, addr, ss) != ss)
- return(0);
- addr += ss;
-
- mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
- mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym);
- } else {
- printf("symbols=[none]");
- }
- printf("\n");
+ /* symbol table */
+ printf("symbols=[0x%x+0x%lx", sizeof(ehdr->a_syms), ehdr->a_syms);
+ if (archsw.arch_readin(fd, addr, ehdr->a_syms) != ehdr->a_syms)
+ return(0);
+ addr += ehdr->a_syms;
+
+ /* string table */
+ read(fd, &ss, sizeof(ss));
+ archsw.arch_copyin(&ss, addr, sizeof(ss));
+ addr += sizeof(ss);
+ ss -= sizeof(ss);
+ printf("+0x%x+0x%x]", sizeof(ss), ss);
+ if (archsw.arch_readin(fd, addr, ss) != ss)
+ return(0);
+ printf(" \n");
+ addr += ss;
esym = addr;
+ mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
+ mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym);
+
return(addr - loadaddr);
}
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index ff1f50638ac8..b2b38c7800b6 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: load_elf.c,v 1.9 1998/10/17 03:06:38 peter Exp $
+ * $Id: load_elf.c,v 1.7 1998/10/15 21:56:47 dfr Exp $
*/
#include <sys/param.h>
@@ -40,7 +40,7 @@
#include "bootstrap.h"
-static int elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, Elf_Ehdr *ehdr, int kernel, caddr_t firstpage, int firstlen);
+static int elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t loadaddr, Elf_Ehdr *ehdr, Elf_Phdr *phdr, int kernel);
char *elf_kerneltype = "elf kernel";
char *elf_moduletype = "elf module";
@@ -54,15 +54,15 @@ int
elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
{
struct loaded_module *mp, *kmp;
- Elf_Ehdr *ehdr;
+ Elf_Ehdr ehdr;
+ Elf_Phdr *phdr;
int fd;
int err, kernel;
u_int pad;
char *s;
- caddr_t firstpage;
- int firstlen;
mp = NULL;
+ phdr = NULL;
/*
* Open the image, read and validate the ELF header
@@ -71,26 +71,21 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
return(EFTYPE);
if ((fd = open(filename, O_RDONLY)) == -1)
return(errno);
- firstpage = malloc(PAGE_SIZE);
- if (firstpage == NULL)
- return(ENOMEM);
- firstlen = read(fd, firstpage, PAGE_SIZE);
- if (firstlen <= sizeof(ehdr)) {
+ if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
err = EFTYPE; /* could be EIO, but may be small file */
goto oerr;
}
- ehdr = (Elf_Ehdr *)firstpage;
/* Is it ELF? */
- if (!IS_ELF(*ehdr)) {
+ if (!IS_ELF(ehdr)) {
err = EFTYPE;
goto oerr;
}
- if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */
- ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
- ehdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */
- ehdr->e_version != EV_CURRENT ||
- ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */
+ if (ehdr.e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */
+ ehdr.e_ident[EI_DATA] != ELF_TARG_DATA ||
+ ehdr.e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */
+ ehdr.e_version != EV_CURRENT ||
+ ehdr.e_machine != ELF_TARG_MACH) { /* Machine ? */
err = EFTYPE;
goto oerr;
}
@@ -100,7 +95,7 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
* Check to see what sort of module we are.
*/
kmp = mod_findmodule(NULL, NULL);
- if (ehdr->e_type == ET_DYN) {
+ if (ehdr.e_type == ET_DYN) {
/* Looks like a kld module */
if (kmp == NULL) {
printf("elf_loadmodule: can't load module before kernel\n");
@@ -121,7 +116,7 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
pad = PAGE_SIZE - pad;
dest += pad;
}
- } else if (ehdr->e_type == ET_EXEC) {
+ } else if (ehdr.e_type == ET_EXEC) {
/* Looks like a kernel */
if (kmp != NULL) {
printf("elf_loadmodule: kernel already loaded\n");
@@ -131,7 +126,7 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
/*
* Calculate destination address based on kernel entrypoint
*/
- dest = (vm_offset_t) ehdr->e_entry;
+ dest = (vm_offset_t) ehdr.e_entry;
if (dest == 0) {
printf("elf_loadmodule: not a kernel (maybe static binary?)\n");
err = EPERM;
@@ -169,12 +164,36 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
printf("%s ", filename);
#endif
- mp->m_size = elf_loadimage(mp, fd, dest, ehdr, kernel, firstpage, firstlen);
+ phdr = malloc(ehdr.e_phnum * sizeof(*phdr));
+ if (phdr == NULL) {
+ err = ENOMEM;
+ goto out;
+ }
+
+ if (lseek(fd, ehdr.e_phoff, SEEK_SET) == -1) {
+ printf("elf_loadexec: lseek for phdr failed\n");
+ goto ioerr;
+ }
+ if (read(fd, phdr, ehdr.e_phnum * sizeof(*phdr)) !=
+ ehdr.e_phnum * sizeof(*phdr)) {
+ printf("elf_loadmodule: cannot read program header\n");
+ goto ioerr;
+ }
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ close(fd);
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ printf("elf_loadmodule: cannot reset file position\n");
+ mod_discard(mp);
+ return errno;
+ }
+ }
+
+ mp->m_size = elf_loadimage(mp, fd, dest, &ehdr, phdr, kernel);
if (mp->m_size == 0 || mp->m_addr == 0)
goto ioerr;
/* save exec header as metadata */
- mod_addmetadata(mp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr);
+ mod_addmetadata(mp, MODINFOMD_ELFHDR, sizeof(ehdr), &ehdr);
/* Load OK, return module pointer */
*result = (struct loaded_module *)mp;
@@ -186,8 +205,8 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
oerr:
mod_discard(mp);
out:
- if (firstpage)
- free(firstpage);
+ if (phdr)
+ free(phdr);
close(fd);
return(err);
}
@@ -198,10 +217,9 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
*/
static int
elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
- Elf_Ehdr *ehdr, int kernel, caddr_t firstpage, int firstlen)
+ Elf_Ehdr *ehdr, Elf_Phdr *phdr, int kernel)
{
int i, j;
- Elf_Phdr *phdr;
Elf_Shdr *shdr;
int ret;
vm_offset_t firstaddr;
@@ -221,7 +239,6 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
int symstrindex;
int symtabindex;
long size;
- int fpcopy;
dp = NULL;
shdr = NULL;
@@ -235,12 +252,6 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
#endif
}
- if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > firstlen) {
- printf("elf_loadimage: program header not within first page\n");
- goto out;
- }
- phdr = (Elf_Phdr *)(firstpage + ehdr->e_phoff);
-
for (i = 0; i < ehdr->e_phnum; i++) {
/* We want to load PT_LOAD segments only.. */
if (phdr[i].p_type != PT_LOAD)
@@ -261,22 +272,15 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
printf(" ");
}
#endif
- fpcopy = 0;
- if (firstlen > phdr[i].p_offset) {
- fpcopy = firstlen - phdr[i].p_offset;
- archsw.arch_copyin(firstpage + phdr[i].p_offset,
- phdr[i].p_vaddr + off, fpcopy);
+
+ if (lseek(fd, phdr[i].p_offset, SEEK_SET) == -1) {
+ printf("\nelf_loadexec: cannot seek\n");
+ goto out;
}
- if (phdr[i].p_filesz > fpcopy) {
- if (lseek(fd, phdr[i].p_offset + fpcopy, SEEK_SET) == -1) {
- printf("\nelf_loadexec: cannot seek\n");
- goto out;
- }
- if (archsw.arch_readin(fd, phdr[i].p_vaddr + off + fpcopy,
- phdr[i].p_filesz - fpcopy) != phdr[i].p_filesz - fpcopy) {
- printf("\nelf_loadexec: archsw.readin failed\n");
- goto out;
- }
+ if (archsw.arch_readin(fd, phdr[i].p_vaddr + off, phdr[i].p_filesz) !=
+ phdr[i].p_filesz) {
+ printf("\nelf_loadexec: archsw.readin failed\n");
+ goto out;
}
/* clear space from oversized segments; eg: bss */
if (phdr[i].p_filesz < phdr[i].p_memsz) {
@@ -323,11 +327,11 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
if (shdr == NULL)
goto nosyms;
if (lseek(fd, ehdr->e_shoff, SEEK_SET) == -1) {
- printf("\nelf_loadimage: cannot lseek() to section headers");
+ printf("\nelf_loadimage: cannot lseek() to section headers\n");
goto nosyms;
}
if (read(fd, shdr, chunk) != chunk) {
- printf("\nelf_loadimage: read section headers failed");
+ printf("\nelf_loadimage: read section headers failed\n");
goto nosyms;
}
symtabindex = -1;
@@ -382,7 +386,7 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
lastaddr += sizeof(long);
#ifdef ELF_VERBOSE
- printf("\n%s: 0x%lx@0x%lx -> 0x%lx-0x%lx", secname,
+ printf("%s: 0x%lx@0x%lx -> 0x%lx-0x%lx\n", secname,
shdr[i].sh_size, shdr[i].sh_offset,
lastaddr, lastaddr + shdr[i].sh_size);
#else
@@ -392,14 +396,14 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
#endif
if (lseek(fd, shdr[i].sh_offset, SEEK_SET) == -1) {
- printf("\nelf_loadimage: could not seek for symbols - skipped!");
+ printf("\nelf_loadimage: could not seek for symbols - skipped!\n");
lastaddr = ssym;
ssym = 0;
goto nosyms;
}
if (archsw.arch_readin(fd, lastaddr, shdr[i].sh_size) !=
shdr[i].sh_size) {
- printf("\nelf_loadimage: could not read symbols - skipped!");
+ printf("\nelf_loadimage: could not read symbols - skipped!\n");
lastaddr = ssym;
ssym = 0;
goto nosyms;
@@ -414,14 +418,13 @@ elf_loadimage(struct loaded_module *mp, int fd, vm_offset_t off,
}
esym = lastaddr;
#ifndef ELF_VERBOSE
- printf("]");
+ printf("]\n");
#endif
mod_addmetadata(mp, MODINFOMD_SSYM, sizeof(ssym), &ssym);
mod_addmetadata(mp, MODINFOMD_ESYM, sizeof(esym), &esym);
nosyms:
- printf("\n");
ret = lastaddr - firstaddr;
mp->m_addr = firstaddr;
diff --git a/sys/boot/common/ls.c b/sys/boot/common/ls.c
index 73f805700bf8..493482a7b300 100644
--- a/sys/boot/common/ls.c
+++ b/sys/boot/common/ls.c
@@ -1,5 +1,5 @@
/*
- * $Id: ls.c,v 1.6 1998/10/11 10:28:51 peter Exp $
+ * $Id: ls.c,v 1.5 1998/10/09 07:09:22 msmith Exp $
* From: $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $
*/
@@ -70,7 +70,6 @@ command_ls(int argc, char *argv[])
fd = -1;
verbose = 0;
optind = 1;
- optreset = 1;
while ((ch = getopt(argc, argv, "l")) != -1) {
switch(ch) {
case 'l':
diff --git a/sys/boot/common/merge_help.awk b/sys/boot/common/merge_help.awk
deleted file mode 100644
index 1376c53aee3c..000000000000
--- a/sys/boot/common/merge_help.awk
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/awk -f
-#
-# $Id: mergehelp.awk,v 1.3 1999/01/13 20:06:52 jabley Exp $
-#
-# Merge two boot loader help files for FreeBSD 3.0
-# Joe Abley <jabley@patho.gen.nz>
-
-BEGIN \
-{
- state = 0;
- first = 0;
- ind = 0;
-}
-
-# beginning of first command
-/^###/ && (state == 0) \
-{
- state = 1;
- next;
-}
-
-# entry header
-/^# T[[:graph:]]+ (S[[:graph:]]+ )*D[[:graph:]][[:print:]]*$/ && (state == 1) \
-{
- match($0, " T[[:graph:]]+");
- T = substr($0, RSTART + 2, RLENGTH - 2);
- match($0, " S[[:graph:]]+");
- S = (RLENGTH == -1) ? "" : substr($0, RSTART + 2, RLENGTH - 2);
- match($0, " D[[:graph:]][[:print:]]*$");
- D = substr($0, RSTART + 2);
-
- # find a suitable place to store this one...
- ind++;
- if (ind == 1)
- {
- first = ind;
- help[ind, "T"] = T;
- help[ind, "S"] = S;
- help[ind, "link"] = -1;
- } else {
- i = first; j = -1;
- while (help[i, "T"] help[i, "S"] < T S)
- {
- j = i;
- i = help[i, "link"];
- if (i == -1) break;
- }
-
- if (i == -1)
- {
- help[j, "link"] = ind;
- help[ind, "link"] = -1;
- } else {
- help[ind, "link"] = i;
- if (j == -1)
- first = ind;
- else
- help[j, "link"] = ind;
- }
- }
- help[ind, "T"] = T;
- help[ind, "S"] = S;
- help[ind, "D"] = D;
-
- # set our state
- state = 2;
- help[ind, "text"] = 0;
- next;
-}
-
-# end of last command, beginning of next one
-/^###/ && (state == 2) \
-{
- state = 1;
-}
-
-(state == 2) \
-{
- sub("[[:blank:]]+$", "");
- if (help[ind, "text"] == 0 && $0 ~ /^[[:blank:]]*$/) next;
- help[ind, "text", help[ind, "text"]] = $0;
- help[ind, "text"]++;
- next;
-}
-
-# show them what we have (it's already sorted in help[])
-END \
-{
- node = first;
- while (node != -1)
- {
- printf "################################################################################\n";
- printf "# T%s ", help[node, "T"];
- if (help[node, "S"] != "") printf "S%s ", help[node, "S"];
- printf "D%s\n\n", help[node, "D"];
- for (i = 0; i < help[node, "text"]; i++)
- printf "%s\n", help[node, "text", i];
- node = help[node, "link"];
- }
- printf "################################################################################\n";
-}
diff --git a/sys/boot/common/module.c b/sys/boot/common/module.c
index 141a8ed32f66..5b0d547af069 100644
--- a/sys/boot/common/module.c
+++ b/sys/boot/common/module.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: module.c,v 1.6 1998/10/09 23:12:34 peter Exp $
+ * $Id: module.c,v 1.5 1998/09/26 10:51:38 dfr Exp $
*/
/*
@@ -72,7 +72,6 @@ command_load(int argc, char *argv[])
dofile = 0;
optind = 1;
- optreset = 1;
typestr = NULL;
while ((ch = getopt(argc, argv, "t:")) != -1) {
switch(ch) {
@@ -134,7 +133,6 @@ command_lsmod(int argc, char *argv[])
verbose = 0;
optind = 1;
- optreset = 1;
while ((ch = getopt(argc, argv, "v")) != -1) {
switch(ch) {
case 'v':
diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c
index 74853154ffe7..4a8ee48d5bd4 100644
--- a/sys/boot/common/pnp.c
+++ b/sys/boot/common/pnp.c
@@ -13,10 +13,9 @@
#include <string.h>
#include <bootstrap.h>
-STAILQ_HEAD(,pnpinfo) pnp_devices;
-static int pnp_devices_initted = 0;
+static struct pnpinfo *pnp_devices = NULL;
-static void pnp_discard(void);
+static void pnp_discard(struct pnpinfo **list);
static int pnp_readconf(char *path);
static int pnp_scankernel(void);
@@ -29,56 +28,15 @@ COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan);
int
pnp_scan(int argc, char *argv[])
{
- struct pnpinfo *pi;
int hdlr;
- int verbose;
- int ch;
-
- if (pnp_devices_initted == 0) {
- STAILQ_INIT(&pnp_devices);
- pnp_devices_initted = 1;
- }
-
- verbose = 0;
- optind = 1;
- optreset = 1;
- while ((ch = getopt(argc, argv, "v")) != -1) {
- switch(ch) {
- case 'v':
- verbose = 1;
- break;
- case '?':
- default:
- /* getopt has already reported an error */
- return(CMD_OK);
- }
- }
/* forget anything we think we knew */
- pnp_discard();
-
- if (verbose)
- pager_open();
+ pnp_discard(&pnp_devices);
/* iterate over all of the handlers */
for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) {
- if (verbose) {
- pager_output("Probing ");
- pager_output(pnphandlers[hdlr]->pp_name);
- pager_output("...\n");
- }
- pnphandlers[hdlr]->pp_enumerate();
- }
- if (verbose) {
- for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) {
- pager_output(pi->pi_ident.stqh_first->id_ident); /* first ident should be canonical */
- if (pi->pi_desc != NULL) {
- pager_output(" : ");
- pager_output(pi->pi_desc);
- }
- pager_output("\n");
- }
- pager_close();
+ printf("Probing bus '%s'...\n", pnphandlers[hdlr]->pp_name);
+ pnphandlers[hdlr]->pp_enumerate(&pnp_devices);
}
return(CMD_OK);
}
@@ -93,7 +51,7 @@ pnp_reload(char *fname)
char *modfname;
/* find anything? */
- if (pnp_devices.stqh_first != NULL) {
+ if (pnp_devices != NULL) {
/* check for kernel, assign modules handled by static drivers there */
if (pnp_scankernel()) {
@@ -112,13 +70,13 @@ pnp_reload(char *fname)
}
/* try to load any modules that have been nominated */
- for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) {
+ for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) {
/* Already loaded? */
if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) {
- modfname = malloc(strlen(pi->pi_module) + 4);
+ modfname = malloc(strlen(pi->pi_module + 3));
sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */
if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv))
- printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident.stqh_first->id_ident);
+ printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident->id_ident);
free(modfname);
}
}
@@ -130,14 +88,24 @@ pnp_reload(char *fname)
* Throw away anything we think we know about PnP devices on (list)
*/
static void
-pnp_discard(void)
+pnp_discard(struct pnpinfo **list)
{
struct pnpinfo *pi;
-
- while (pnp_devices.stqh_first != NULL) {
- pi = pnp_devices.stqh_first;
- STAILQ_REMOVE_HEAD(&pnp_devices, pi_link);
- pnp_freeinfo(pi);
+ struct pnpident *id;
+
+ while (*list != NULL) {
+ pi = *list;
+ *list = (*list)->pi_next;
+ while (pi->pi_ident) {
+ id = pi->pi_ident;
+ pi->pi_ident = pi->pi_ident->id_next;
+ free(id);
+ }
+ if (pi->pi_module)
+ free(pi->pi_module);
+ if (pi->pi_argv)
+ free(pi->pi_argv);
+ free(pi);
}
}
@@ -258,14 +226,14 @@ pnp_readconf(char *path)
* assigned.
* XXX no revision parse/test here yet.
*/
- for (pi = pnp_devices.stqh_first; pi != NULL; pi = pi->pi_link.stqe_next) {
+ for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) {
/* no driver assigned, bus matches OK */
if ((pi->pi_module == NULL) &&
!strcmp(pi->pi_handler->pp_name, currbus)) {
/* scan idents, take first match */
- for (id = pi->pi_ident.stqh_first; id != NULL; id = id->id_link.stqe_next)
+ for (id = pi->pi_ident; id != NULL; id = id->id_next)
if (!strcmp(id->id_ident, ident))
break;
@@ -299,82 +267,19 @@ pnp_scankernel(void)
void
pnp_addident(struct pnpinfo *pi, char *ident)
{
- struct pnpident *id;
-
- for (id = pi->pi_ident.stqh_first; id != NULL; id = id->id_link.stqe_next)
- if (!strcmp(id->id_ident, ident))
- return; /* already have this one */
-
- id = malloc(sizeof(struct pnpident));
- id->id_ident = strdup(ident);
- STAILQ_INSERT_TAIL(&pi->pi_ident, id, id_link);
-}
-
-/*
- * Allocate a new pnpinfo struct
- */
-struct pnpinfo *
-pnp_allocinfo(void)
-{
- struct pnpinfo *pi;
+ struct pnpident *id, **idp;
- pi = malloc(sizeof(struct pnpinfo));
- bzero(pi, sizeof(struct pnpinfo));
- STAILQ_INIT(&pi->pi_ident);
- return(pi);
-}
-
-/*
- * Release storage held by a pnpinfo struct
- */
-void
-pnp_freeinfo(struct pnpinfo *pi)
-{
- struct pnpident *id;
-
- while (pi->pi_ident.stqh_first != NULL) {
- id = pi->pi_ident.stqh_first;
- STAILQ_REMOVE_HEAD(&pi->pi_ident, id_link);
- free(id->id_ident);
- free(id);
+ if (pi->pi_ident == NULL) {
+ idp = &(pi->pi_ident);
+ } else {
+ for (id = pi->pi_ident; id->id_next != NULL; id = id->id_next)
+ if (!strcmp(id->id_ident, ident))
+ return; /* already have this one */
+ ;
+ idp = &(id->id_next);
}
- if (pi->pi_desc)
- free(pi->pi_desc);
- if (pi->pi_module)
- free(pi->pi_module);
- if (pi->pi_argv)
- free(pi->pi_argv);
- free(pi);
-}
-
-/*
- * Add a new pnpinfo struct to the list.
- */
-void
-pnp_addinfo(struct pnpinfo *pi)
-{
- STAILQ_INSERT_TAIL(&pnp_devices, pi, pi_link);
-}
-
-
-/*
- * Format an EISA id as a string in standard ISA PnP format, AAAIIRR
- * where 'AAA' is the EISA vendor ID, II is the product ID and RR the revision ID.
- */
-char *
-pnp_eisaformat(u_int8_t *data)
-{
- static char idbuf[8];
- const char hextoascii[] = "0123456789abcdef";
-
- idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
- idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
- idbuf[2] = '@' + (data[1] & 0x1f);
- idbuf[3] = hextoascii[(data[2] >> 4)];
- idbuf[4] = hextoascii[(data[2] & 0xf)];
- idbuf[5] = hextoascii[(data[3] >> 4)];
- idbuf[6] = hextoascii[(data[3] & 0xf)];
- idbuf[7] = 0;
- return(idbuf);
+ *idp = malloc(sizeof(struct pnpident));
+ (*idp)->id_next = NULL;
+ (*idp)->id_ident = strdup(ident);
}
diff --git a/sys/boot/common/pnpdata b/sys/boot/common/pnpdata
deleted file mode 100644
index 62d35a819386..000000000000
--- a/sys/boot/common/pnpdata
+++ /dev/null
@@ -1,183 +0,0 @@
-#
-# $Id$
-#
-# This file contains the system default Plug-and-Play data. It is
-# derived from a number of sources, including:
-#
-# - The Microsoft "Windows Generic Device IDs" document
-#
-
-[pci]
-######################################################################
-# PCI devices.
-#
-# Required attributes:
-#
-# ident= PCI identifier in the form 0xDDDDVVVV where
-# 'VVVV' is the 4-digit hex form of the vendor ID and
-# 'DDDD' is the 4-digit hex form of the device ID.
-# or
-#
-# vendor= 0xVVVV where 'VVVV' is above
-# name= Vendor name
-
-vendor=0x8086 name=Intel
-
-
-[isa]
-######################################################################
-# ISA PnP devices
-#
-# Required attributes:
-#
-# ident= ISA PnP identifier in the form AAAIIRR where
-# 'AAA' is the EISA vendor ID, 'II' is the device ID
-# and 'RR' is the revision ID.
-# or
-#
-# vendor= AAA to register just a vendor name.
-# name= Vendor name
-#
-# Optional attributes:
-#
-# module= Support module identifier.
-#
-# args= Arguments to pass to the support module.
-#
-
-vendor=CSC name=Crystal Semiconductor
-vendor=CTL name=Creative Labs
-vendor=PNP name=Generic
-
-# From "Windows Generic Device IDs"
-#
-# --Parallel Devices--
-ident=PNP0400 module=lpt # Standard LPT printer port
-ident=PNP0401 module=lpt # ECP printer port
-
-# --Serial Devices--
-ident=PNP0500 module=sio # Standard PC COM port
-ident=PNP0501 module=sio # 16550A-compatible COM port
-ident=PNP0502 module=sio # Multiport serial device (non-intelligent 16550)
-
-# --Disk Controllers--
-ident=PNP0600 module=wd # Generic ESDI/IDE/ATA compatible hard disk controller
-ident=PNP0603 module=wd # Generic IDE supporting Microsoft Device Bay Specification
-ident=PNP0700 module=fd # PC standard floppy disk controller
-ident=PNP0701 module=fd # Standard floppy controller supporting MS Device Bay Spec
-
-# --Peripheral Buses--
-ident=PNP0A00 module=isa # ISA Bus
-ident=PNP0A01 module=eisa # EISA Bus
-ident=PNP0A03 module=pci # PCI Bus
-ident=PNP0A04 module=isa # VESA/VL Bus
-
-# -- Real Time Clock, BIOS, System board devices--
-ident=PNP0C04 module=npx # Math Coprocessor
-ident=PNP0C05 module=apm # APM BIOS (Version independent)
-
-# --PCMCIA Controller Chipsets--
-ident=PNP0E00 module=pcic # Intel 82365-Compatible PCMCIA Controller
-ident=PNP0E01 module=pcic # Cirrus Logic CL-PD6720 PCMCIA Controller
-ident=PNP0E02 module=pcic # VLSI VL82C146 PCMCIA Controller
-ident=PNP0E03 module=pcic # Intel 82365-compatible CardBus controller
-
-# --Network Adapters--
-ident=PNP8001 module=ed # Novell/Anthem NE3200
-ident=PNP8004 # Compaq NE3200
-ident=PNP80d3 module=ed # Novell/Anthem NE1000
-ident=PNP80d4 module=ed # Novell/Anthem NE2000
-ident=PNP80d5 module=ed # NE1000 Compatible
-ident=PNP80d6 module=ed # NE2000 Compatible
-ident=PNP80d8 module=lnc # Novell/Anthem NE2100
-ident=PNP80e9 module=le # DEC (DE200) EtherWorks Turbo
-ident=PNP80eb module=le # DEC (DE201) EtherWorks Turbo/TP
-ident=PNP80ec module=le # DEC (DE202) EtherWorks Turbo/TP_BNC
-ident=PNP80f1 module=eg # 3Com EtherLink Plus
-ident=PNP80f3 module=ed # 3Com EtherLink II or IITP (8 or 16-bit)
-ident=PNP80f6 module=ed # 3Com EtherLink 16
-ident=PNP80f7 module=ep # 3Com EtherLink III
-ident=PNP80f8 module=ep # 3Com Generic Etherlink Plug and Play Device
-ident=PNP8123 module=ed # SMC StarCard PLUS (WD/8003S)
-ident=PNP8124 module=ed # SMC StarCard PLUS With On Board Hub (WD/8003SH)
-ident=PNP8125 module=ed # SMC EtherCard PLUS (WD/8003E)
-ident=PNP8126 module=ed # SMC EtherCard PLUS With Boot ROM Socket (WD/8003EBT)
-ident=PNP8127 module=ed # SMC EtherCard PLUS With Boot ROM Socket (WD/8003EB)
-ident=PNP8128 module=ed # SMC EtherCard PLUS TP (WD/8003WT)
-ident=PNP812a module=ed # SMC EtherCard PLUS 16 With Boot ROM Socket (WD/8013EBT)
-ident=PNP812d module=ie # Intel EtherExpress 16 or 16TP
-ident=PNP8137 module=ed # Artisoft AE-1
-ident=PNP8138 module=ed # Artisoft AE-2 or AE-3
-ident=PNP8158 module=ed # HP PC LAN Adapter/16 TP Plus (HP27247B)
-ident=PNP8159 module=ed # HP PC LAN Adapter/16 TL Plus (HP27252)
-ident=PNP81c3 module=ed # SMC EtherCard PLUS Elite (WD/8003EP)
-ident=PNP81c4 module=ed # SMC EtherCard PLUS 10T (WD/8003W)
-ident=PNP81c5 module=ed # SMC EtherCard PLUS Elite 16 (WD/8013EP)
-ident=PNP81c6 module=ed # SMC EtherCard PLUS Elite 16T (WD/8013W)
-ident=PNP81c7 module=ed # SMC EtherCard PLUS Elite 16 Combo (WD/8013EW or 8013EWC)
-ident=PNP81c8 module=ed # SMC EtherElite Ultra 16
-ident=PNP820a module=ed # Zenith Data Systems NE2000-Compatible
-ident=PNP8231 module=lnc # Advanced Micro Devices AM2100/AM1500T
-ident=PNP828C module=lnc # AMD PCNet Family cards
-ident=PNP828D module=lnc # AMD PCNet32 (VL version)
-ident=PNP8323 module=ed # SMC EtherCard (All Types except 8013/A)
-ident=PNP8390 module=ed # Generic network adapter
-
-# --SCSI, Proprietary CD Adapters--
-ident=PNPA003 module=matcd # Panasonic proprietary CD-ROM adapter (SBPro/SB16)
-ident=PNPA02B module=scd # Sony proprietary CD-ROM controller
-ident=PNPA030 module=mcd # Mitsumi LU-005 Single Speed CD-ROM controller + drive
-ident=PNPA031 module=mcd # Mitsumi FX-001 Single Speed CD-ROM controller + drive
-ident=PNPA032 module=mcd # Mitsumi FX-001 Double Speed CD-ROM controller + drive
-
-# --Sound/Video-capture, multimedia--
-ident=PNPB000 module=pcm # Sound Blaster 1.5 sound device
-ident=PNPB001 module=pcm # Sound Blaster 2.0 sound device
-ident=PNPB002 module=pcm # Sound Blaster Pro sound device
-ident=PNPB003 module=pcm # Sound Blaster 16 sound device
-ident=PNPB007 module=pcm # Microsoft Windows Sound System-compatible sound device
-ident=PNPB009 module=pcm # Plug and Play Microsoft Windows Sound System Device
-ident=PNPB020 module=pcm # Yamaha OPL3-compatible FM synthesizer device
-ident=PNPB02F module=joy # Joystick/Game port
-
-# --Compatibility with early device ID list--
-ident=PNP0802 module=pcm # Microsoft Sound System compatible device (obsolete, use PNPB0xx instead)
-
-# --Modems--
-ident=PNPC000 module=sio # Compaq 14400 Modem (TBD)
-ident=PNPC001 module=sio # Compaq 2400/9600 Modem (TBD)
-
-# Vendor supplied IDs.
-
-# --Parallel Devices--
-
-# --Serial Devices--
-
-# --Disk Controllers--
-
-# --Peripheral Buses--
-
-# --Real Time Clock, BIOS, System board devices--
-
-# --PCMCIA Controller Chipsets--
-
-# --Network Adapters--
-ident=CSC6040 module=cs # Crystal Semiconductor CS8920
-
-# --SCSI, Proprietary CD Adapters--
-
-# --Sound/Video-capture, multimedia--
-
-# --Modems--
-
-
-
-[com]
-######################################################################
-# COM PnP devices
-#
-
-[lpt]
-######################################################################
-# LPT PnP devices
-#
diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile
deleted file mode 100644
index 260254e316a1..000000000000
--- a/sys/boot/ficl/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-# $Id: Makefile,v 1.6 1998/11/05 08:39:42 jkh Exp $
-#
-LIB= ficl
-NOPROFILE= yes
-INTERNALLIB= yes
-INTERNALSTATICLIB= yes
-BASE_SRCS= dict.c ficl.c math64.c stack.c sysdep.c vm.c words.c
-SRCS= ${BASE_SRCS} softcore.c
-CLEANFILES= softcore.c testmain
-
-# Standard softwords
-SOFTWORDS= softcore.fr jhlocal.fr marker.fr
-# Optional OO extension softwords
-#SOFTWORDS+= oo.fr classes.fr
-
-.PATH: ${.CURDIR}/softwords
-CFLAGS+= -I${.CURDIR}
-
-softcore.c: ${SOFTWORDS} softcore.awk
- (cd ${.CURDIR}/softwords; cat ${SOFTWORDS} | awk -f softcore.awk) > ${.TARGET}
-
-.include <bsd.lib.mk>
-
-testmain: ${.CURDIR}/testmain.c ${SRCS}
- @for i in ${BASE_SRCS}; do echo $${i}... ; \
- ${CC} -c ${CFLAGS} -DTESTMAIN ${.CURDIR}/$${i}; done
- @echo softdep.c...
- @${CC} -c ${CFLAGS} -D_TESTMAIN softcore.c
- cc -o ${.TARGET} ${.CURDIR}/testmain.c ${OBJS}
-
diff --git a/sys/boot/ficl/dict.c b/sys/boot/ficl/dict.c
deleted file mode 100644
index 640a2fddc1ad..000000000000
--- a/sys/boot/ficl/dict.c
+++ /dev/null
@@ -1,779 +0,0 @@
-/*******************************************************************
-** d i c t . c
-** Forth Inspired Command Language - dictionary methods
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 19 July 1997
-**
-*******************************************************************/
-/*
-** This file implements the dictionary -- FICL's model of
-** memory management. All FICL words are stored in the
-** dictionary. A word is a named chunk of data with its
-** associated code. FICL treats all words the same, even
-** precompiled ones, so your words become first-class
-** extensions of the language. You can even define new
-** control structures.
-**
-** 29 jun 1998 (sadler) added variable sized hash table support
-*/
-
-#ifdef TESTMAIN
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#else
-#include <stand.h>
-#endif
-#include <string.h>
-#include "ficl.h"
-
-static char *dictCopyName(FICL_DICT *pDict, STRINGINFO si);
-
-/**************************************************************************
- d i c t A b o r t D e f i n i t i o n
-** Abort a definition in process: reclaim its memory and unlink it
-** from the dictionary list. Assumes that there is a smudged
-** definition in process...otherwise does nothing.
-** NOTE: this function is not smart enough to unlink a word that
-** has been successfully defined (ie linked into a hash). It
-** only works for defs in process. If the def has been unsmudged,
-** nothing happens.
-**************************************************************************/
-void dictAbortDefinition(FICL_DICT *pDict)
-{
- FICL_WORD *pFW;
- ficlLockDictionary(TRUE);
- pFW = pDict->smudge;
-
- if (pFW->flags & FW_SMUDGE)
- pDict->here = (CELL *)pFW->name;
-
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- a l i g n P t r
-** Aligns the given pointer to FICL_ALIGN address units.
-** Returns the aligned pointer value.
-**************************************************************************/
-void *alignPtr(void *ptr)
-{
-#if FICL_ALIGN > 0
- char *cp;
- CELL c;
- cp = (char *)ptr + FICL_ALIGN_ADD;
- c.p = (void *)cp;
- c.u = c.u & (~FICL_ALIGN_ADD);
- ptr = (CELL *)c.p;
-#endif
- return ptr;
-}
-
-
-/**************************************************************************
- d i c t A l i g n
-** Align the dictionary's free space pointer
-**************************************************************************/
-void dictAlign(FICL_DICT *pDict)
-{
- pDict->here = alignPtr(pDict->here);
-}
-
-
-/**************************************************************************
- d i c t A l l o t
-** Allocate or remove n chars of dictionary space, with
-** checks for underrun and overrun
-**************************************************************************/
-int dictAllot(FICL_DICT *pDict, int n)
-{
- char *cp = (char *)pDict->here;
-#if FICL_ROBUST
- if (n > 0)
- {
- if ((unsigned)n <= dictCellsAvail(pDict) * sizeof (CELL))
- cp += n;
- else
- return 1; /* dict is full */
- }
- else
- {
- n = -n;
- if ((unsigned)n <= dictCellsUsed(pDict) * sizeof (CELL))
- cp -= n;
- else /* prevent underflow */
- cp -= dictCellsUsed(pDict) * sizeof (CELL);
- }
-#else
- cp += n;
-#endif
- pDict->here = PTRtoCELL cp;
- return 0;
-}
-
-
-/**************************************************************************
- d i c t A l l o t C e l l s
-** Reserve space for the requested number of cells in the
-** dictionary. If nCells < 0 , removes space from the dictionary.
-**************************************************************************/
-int dictAllotCells(FICL_DICT *pDict, int nCells)
-{
-#if FICL_ROBUST
- if (nCells > 0)
- {
- if (nCells <= dictCellsAvail(pDict))
- pDict->here += nCells;
- else
- return 1; /* dict is full */
- }
- else
- {
- nCells = -nCells;
- if (nCells <= dictCellsUsed(pDict))
- pDict->here -= nCells;
- else /* prevent underflow */
- pDict->here -= dictCellsUsed(pDict);
- }
-#else
- pDict->here += nCells;
-#endif
- return 0;
-}
-
-
-/**************************************************************************
- d i c t A p p e n d C e l l
-** Append the specified cell to the dictionary
-**************************************************************************/
-void dictAppendCell(FICL_DICT *pDict, CELL c)
-{
- *pDict->here++ = c;
- return;
-}
-
-
-/**************************************************************************
- d i c t A p p e n d C h a r
-** Append the specified char to the dictionary
-**************************************************************************/
-void dictAppendChar(FICL_DICT *pDict, char c)
-{
- char *cp = (char *)pDict->here;
- *cp++ = c;
- pDict->here = PTRtoCELL cp;
- return;
-}
-
-
-/**************************************************************************
- d i c t A p p e n d W o r d
-** Create a new word in the dictionary with the specified
-** name, code, and flags. Name must be NULL-terminated.
-**************************************************************************/
-FICL_WORD *dictAppendWord(FICL_DICT *pDict,
- char *name,
- FICL_CODE pCode,
- UNS8 flags)
-{
- STRINGINFO si;
- SI_SETLEN(si, strlen(name));
- SI_SETPTR(si, name);
- return dictAppendWord2(pDict, si, pCode, flags);
-}
-
-
-/**************************************************************************
- d i c t A p p e n d W o r d 2
-** Create a new word in the dictionary with the specified
-** STRINGINFO, code, and flags. Does not require a NULL-terminated
-** name.
-**************************************************************************/
-FICL_WORD *dictAppendWord2(FICL_DICT *pDict,
- STRINGINFO si,
- FICL_CODE pCode,
- UNS8 flags)
-{
- FICL_COUNT len = (FICL_COUNT)SI_COUNT(si);
- char *name = SI_PTR(si);
- char *pName;
- FICL_WORD *pFW;
-
- ficlLockDictionary(TRUE);
-
- /*
- ** NOTE: dictCopyName advances "here" as a side-effect.
- ** It must execute before pFW is initialized.
- */
- pName = dictCopyName(pDict, si);
- pFW = (FICL_WORD *)pDict->here;
- pDict->smudge = pFW;
- pFW->hash = hashHashCode(si);
- pFW->code = pCode;
- pFW->flags = (UNS8)(flags | FW_SMUDGE);
- pFW->nName = (char)len;
- pFW->name = pName;
- /*
- ** Point "here" to first cell of new word's param area...
- */
- pDict->here = pFW->param;
-
- if (!(flags & FW_SMUDGE))
- dictUnsmudge(pDict);
-
- ficlLockDictionary(FALSE);
- return pFW;
-}
-
-
-/**************************************************************************
- d i c t A p p e n d U N S 3 2
-** Append the specified UNS32 to the dictionary
-**************************************************************************/
-void dictAppendUNS32(FICL_DICT *pDict, UNS32 u)
-{
- *pDict->here++ = LVALUEtoCELL(u);
- return;
-}
-
-
-/**************************************************************************
- d i c t C e l l s A v a i l
-** Returns the number of empty cells left in the dictionary
-**************************************************************************/
-int dictCellsAvail(FICL_DICT *pDict)
-{
- return pDict->size - dictCellsUsed(pDict);
-}
-
-
-/**************************************************************************
- d i c t C e l l s U s e d
-** Returns the number of cells consumed in the dicionary
-**************************************************************************/
-int dictCellsUsed(FICL_DICT *pDict)
-{
- return pDict->here - pDict->dict;
-}
-
-
-/**************************************************************************
- d i c t C h e c k
-** Checks the dictionary for corruption and throws appropriate
-** errors
-**************************************************************************/
-void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int nCells)
-{
- if ((nCells >= 0) && (dictCellsAvail(pDict) < nCells))
- {
- vmThrowErr(pVM, "Error: dictionary full");
- }
-
- if ((nCells <= 0) && (dictCellsUsed(pDict) < -nCells))
- {
- vmThrowErr(pVM, "Error: dictionary underflow");
- }
-
- if (pDict->nLists > FICL_DEFAULT_VOCS)
- {
- dictResetSearchOrder(pDict);
- vmThrowErr(pVM, "Error: search order overflow");
- }
- else if (pDict->nLists < 0)
- {
- dictResetSearchOrder(pDict);
- vmThrowErr(pVM, "Error: search order underflow");
- }
-
- return;
-}
-
-
-/**************************************************************************
- d i c t C o p y N a m e
-** Copy up to nFICLNAME characters of the name specified by si into
-** the dictionary starting at "here", then NULL-terminate the name,
-** point "here" to the next available byte, and return the address of
-** the beginning of the name. Used by dictAppendWord.
-** N O T E S :
-** 1. "here" is guaranteed to be aligned after this operation.
-** 2. If the string has zero length, align and return "here"
-**************************************************************************/
-static char *dictCopyName(FICL_DICT *pDict, STRINGINFO si)
-{
- char *oldCP = (char *)pDict->here;
- char *cp = oldCP;
- char *name = SI_PTR(si);
- int i = SI_COUNT(si);
-
- if (i == 0)
- {
- dictAlign(pDict);
- return (char *)pDict->here;
- }
-
- if (i > nFICLNAME)
- i = nFICLNAME;
-
- for (; i > 0; --i)
- {
- *cp++ = *name++;
- }
-
- *cp++ = '\0';
-
- pDict->here = PTRtoCELL cp;
- dictAlign(pDict);
- return oldCP;
-}
-
-
-/**************************************************************************
- d i c t C r e a t e
-** Create and initialize a dictionary with the specified number
-** of cells capacity, and no hashing (hash size == 1).
-**************************************************************************/
-FICL_DICT *dictCreate(unsigned nCells)
-{
- return dictCreateHashed(nCells, 1);
-}
-
-
-FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash)
-{
- FICL_DICT *pDict;
- size_t nAlloc;
-
- nAlloc = sizeof (FICL_DICT) + nCells * sizeof (CELL)
- + sizeof (FICL_HASH) + (nHash - 1) * sizeof (FICL_WORD *);
-
- pDict = ficlMalloc(nAlloc);
- assert(pDict);
- pDict->size = nCells;
- dictEmpty(pDict, nHash);
- return pDict;
-}
-
-
-/**************************************************************************
- d i c t D e l e t e
-** Free all memory allocated for the given dictionary
-**************************************************************************/
-void dictDelete(FICL_DICT *pDict)
-{
- assert(pDict);
- ficlFree(pDict);
- return;
-}
-
-
-/**************************************************************************
- d i c t E m p t y
-** Empty the dictionary, reset its hash table, and reset its search order.
-** Clears and (re-)creates the main hash table (pForthWords) with the
-** size specified by nHash.
-**************************************************************************/
-void dictEmpty(FICL_DICT *pDict, unsigned nHash)
-{
- FICL_HASH *pHash;
-
- pDict->here = pDict->dict;
-
- dictAlign(pDict);
- pHash = (FICL_HASH *)pDict->here;
- dictAllot(pDict,
- sizeof (FICL_HASH) + (nHash - 1) * sizeof (FICL_WORD *));
-
- pHash->size = nHash;
- hashReset(pHash);
-
- pDict->pForthWords = pHash;
- pDict->smudge = NULL;
- dictResetSearchOrder(pDict);
- return;
-}
-
-
-/**************************************************************************
- d i c t H a s h S u m m a r y
-** Calculate a figure of merit for the dictionary hash table based
-** on the average search depth for all the words in the dictionary,
-** assuming uniform distribution of target keys. The figure of merit
-** is the ratio of the total search depth for all keys in the table
-** versus a theoretical optimum that would be achieved if the keys
-** were distributed into the table as evenly as possible.
-** The figure would be worse if the hash table used an open
-** addressing scheme (i.e. collisions resolved by searching the
-** table for an empty slot) for a given size table.
-**************************************************************************/
-void dictHashSummary(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- FICL_HASH *pFHash;
- FICL_WORD **pHash;
- unsigned size;
- FICL_WORD *pFW;
- unsigned i;
- int nMax = 0;
- int nWords = 0;
- int nFilled;
- double avg = 0.0;
- double best;
- int nAvg, nRem, nDepth;
-
- dictCheck(dp, pVM, 0);
-
- pFHash = dp->pSearch[dp->nLists - 1];
- pHash = pFHash->table;
- size = pFHash->size;
- nFilled = size;
-
- for (i = 0; i < size; i++)
- {
- int n = 0;
- pFW = pHash[i];
-
- while (pFW)
- {
- ++n;
- ++nWords;
- pFW = pFW->link;
- }
-
- avg += (double)(n * (n+1)) / 2.0;
-
- if (n > nMax)
- nMax = n;
- if (n == 0)
- --nFilled;
- }
-
- /* Calc actual avg search depth for this hash */
- avg = avg / nWords;
-
- /* Calc best possible performance with this size hash */
- nAvg = nWords / size;
- nRem = nWords % size;
- nDepth = size * (nAvg * (nAvg+1))/2 + (nAvg+1)*nRem;
- best = (double)nDepth/nWords;
-
- sprintf(pVM->pad,
- "%d bins, %2.0f%% filled, Depth: Max=%d, Avg=%2.1f, Best=%2.1f, Score: %2.0f%%",
- size,
- (double)nFilled * 100.0 / size, nMax,
- avg,
- best,
- 100.0 * best / avg);
-
- ficlTextOut(pVM, pVM->pad, 1);
-
- return;
-}
-
-
-/**************************************************************************
- d i c t I n c l u d e s
-** Returns TRUE iff the given pointer is within the address range of
-** the dictionary.
-**************************************************************************/
-int dictIncludes(FICL_DICT *pDict, void *p)
-{
- return ((p >= (void *) &pDict->dict)
- && (p < (void *)(&pDict->dict + pDict->size))
- );
-}
-
-
-/**************************************************************************
- d i c t L o o k u p
-** Find the FICL_WORD that matches the given name and length.
-** If found, returns the word's address. Otherwise returns NULL.
-** Uses the search order list to search multiple wordlists.
-**************************************************************************/
-FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si)
-{
- FICL_WORD *pFW = NULL;
- FICL_HASH *pHash;
- int i;
- UNS16 hashCode = hashHashCode(si);
-
- assert(pDict);
-
- ficlLockDictionary(1);
-
- for (i = (int)pDict->nLists - 1; (i >= 0) && (!pFW); --i)
- {
- pHash = pDict->pSearch[i];
- pFW = hashLookup(pHash, si, hashCode);
- }
-
- ficlLockDictionary(0);
- return pFW;
-}
-
-
-/**************************************************************************
- d i c t L o o k u p L o c
-** Same as dictLookup, but looks in system locals dictionary first...
-** Assumes locals dictionary has only one wordlist...
-**************************************************************************/
-#if FICL_WANT_LOCALS
-FICL_WORD *dictLookupLoc(FICL_DICT *pDict, STRINGINFO si)
-{
- FICL_WORD *pFW = NULL;
- FICL_HASH *pHash = ficlGetLoc()->pForthWords;
- int i;
- UNS16 hashCode = hashHashCode(si);
-
- assert(pHash);
- assert(pDict);
-
- ficlLockDictionary(1);
- /*
- ** check the locals dict first...
- */
- pFW = hashLookup(pHash, si, hashCode);
-
- /*
- ** If no joy, (!pFW) --------------------------v
- ** iterate over the search list in the main dict
- */
- for (i = (int)pDict->nLists - 1; (i >= 0) && (!pFW); --i)
- {
- pHash = pDict->pSearch[i];
- pFW = hashLookup(pHash, si, hashCode);
- }
-
- ficlLockDictionary(0);
- return pFW;
-}
-#endif
-
-
-/**************************************************************************
- d i c t R e s e t S e a r c h O r d e r
-** Initialize the dictionary search order list to sane state
-**************************************************************************/
-void dictResetSearchOrder(FICL_DICT *pDict)
-{
- assert(pDict);
- pDict->pCompile = pDict->pForthWords;
- pDict->nLists = 1;
- pDict->pSearch[0] = pDict->pForthWords;
- return;
-}
-
-
-/**************************************************************************
- d i c t S e t F l a g s
-** Changes the flags field of the most recently defined word:
-** Set all bits that are ones in the set parameter, clear all bits
-** that are ones in the clr parameter. Clear wins in case the same bit
-** is set in both parameters.
-**************************************************************************/
-void dictSetFlags(FICL_DICT *pDict, UNS8 set, UNS8 clr)
-{
- assert(pDict->smudge);
- pDict->smudge->flags |= set;
- pDict->smudge->flags &= ~clr;
- return;
-}
-
-
-/**************************************************************************
- d i c t S e t I m m e d i a t e
-** Set the most recently defined word as IMMEDIATE
-**************************************************************************/
-void dictSetImmediate(FICL_DICT *pDict)
-{
- assert(pDict->smudge);
- pDict->smudge->flags |= FW_IMMEDIATE;
- return;
-}
-
-
-/**************************************************************************
- d i c t U n s m u d g e
-** Completes the definition of a word by linking it
-** into the main list
-**************************************************************************/
-void dictUnsmudge(FICL_DICT *pDict)
-{
- FICL_WORD *pFW = pDict->smudge;
- FICL_HASH *pHash = pDict->pCompile;
-
- assert(pHash);
- assert(pFW);
- /*
- ** :noname words never get linked into the list...
- */
- if (pFW->nName > 0)
- hashInsertWord(pHash, pFW);
- pFW->flags &= ~(FW_SMUDGE);
- return;
-}
-
-
-/**************************************************************************
- d i c t W h e r e
-** Returns the value of the HERE pointer -- the address
-** of the next free cell in the dictionary
-**************************************************************************/
-CELL *dictWhere(FICL_DICT *pDict)
-{
- return pDict->here;
-}
-
-
-/**************************************************************************
- h a s h F o r g e t
-** Unlink all words in the hash that have addresses greater than or
-** equal to the address supplied. Implementation factor for FORGET
-** and MARKER.
-**************************************************************************/
-void hashForget(FICL_HASH *pHash, void *where)
-{
- FICL_WORD *pWord;
- unsigned i;
-
- assert(pHash);
- assert(where);
-
- for (i = 0; i < pHash->size; i++)
- {
- pWord = pHash->table[i];
-
- while ((void *)pWord >= where)
- {
- pWord = pWord->link;
- }
-
- pHash->table[i] = pWord;
- }
-
- return;
-}
-
-
-/**************************************************************************
- h a s h H a s h C o d e
-**
-** Generate a 16 bit hashcode from a character string using a rolling
-** shift and add stolen from PJ Weinberger of Bell Labs fame. Case folds
-** the name before hashing it...
-** N O T E : If string has zero length, returns zero.
-**************************************************************************/
-UNS16 hashHashCode(STRINGINFO si)
-{
- /* hashPJW */
- UNS8 *cp;
- UNS16 code = (UNS16)si.count;
- UNS16 shift = 0;
-
- if (si.count == 0)
- return 0;
-
- for (cp = (UNS8 *)si.cp; *cp && si.count; cp++, si.count--)
- {
- code = (UNS16)((code << 4) + tolower(*cp));
- shift = (UNS16)(code & 0xf000);
- if (shift)
- {
- code ^= (UNS16)(shift >> 8);
- code ^= (UNS16)shift;
- }
- }
-
- return (UNS16)code;
-}
-
-
-/**************************************************************************
- h a s h I n s e r t W o r d
-** Put a word into the hash table using the word's hashcode as
-** an index (modulo the table size).
-**************************************************************************/
-void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW)
-{
- FICL_WORD **pList;
-
- assert(pHash);
- assert(pFW);
-
- if (pHash->size == 1)
- {
- pList = pHash->table;
- }
- else
- {
- pList = pHash->table + (pFW->hash % pHash->size);
- }
-
- pFW->link = *pList;
- *pList = pFW;
- return;
-}
-
-
-/**************************************************************************
- h a s h L o o k u p
-** Find a name in the hash table given the hashcode and text of the name.
-** Returns the address of the corresponding FICL_WORD if found,
-** otherwise NULL.
-** Note: outer loop on link field supports inheritance in wordlists.
-** It's not part of ANS Forth - ficl only. hashReset creates wordlists
-** with NULL link fields.
-**************************************************************************/
-FICL_WORD *hashLookup(FICL_HASH *pHash, STRINGINFO si, UNS16 hashCode)
-{
- FICL_COUNT nCmp = (FICL_COUNT)si.count;
- FICL_WORD *pFW;
- UNS16 hashIdx;
-
- if (nCmp > nFICLNAME)
- nCmp = nFICLNAME;
-
- for (; pHash != NULL; pHash = pHash->link)
- {
- if (pHash->size > 1)
- hashIdx = (UNS16)(hashCode % pHash->size);
- else /* avoid the modulo op for single threaded lists */
- hashIdx = 0;
-
- for (pFW = pHash->table[hashIdx]; pFW; pFW = pFW->link)
- {
- if ( (pFW->nName == si.count)
- && (!strincmp(si.cp, pFW->name, nCmp)) )
- return pFW;
-#if FICL_ROBUST
- assert(pFW != pFW->link);
-#endif
- }
- }
-
- return NULL;
-}
-
-
-/**************************************************************************
- h a s h R e s e t
-** Initialize a FICL_HASH to empty state.
-**************************************************************************/
-void hashReset(FICL_HASH *pHash)
-{
- unsigned i;
-
- assert(pHash);
-
- for (i = 0; i < pHash->size; i++)
- {
- pHash->table[i] = NULL;
- }
-
- pHash->link = NULL;
- return;
-}
-
-
diff --git a/sys/boot/ficl/ficl.c b/sys/boot/ficl/ficl.c
deleted file mode 100644
index 3b5885f06e2b..000000000000
--- a/sys/boot/ficl/ficl.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*******************************************************************
-** f i c l . c
-** Forth Inspired Command Language - external interface
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 19 July 1997
-**
-*******************************************************************/
-/*
-** This is an ANS Forth interpreter written in C.
-** Ficl uses Forth syntax for its commands, but turns the Forth
-** model on its head in other respects.
-** Ficl provides facilities for interoperating
-** with programs written in C: C functions can be exported to Ficl,
-** and Ficl commands can be executed via a C calling interface. The
-** interpreter is re-entrant, so it can be used in multiple instances
-** in a multitasking system. Unlike Forth, Ficl's outer interpreter
-** expects a text block as input, and returns to the caller after each
-** text block, so the data pump is somewhere in external code. This
-** is more like TCL than Forth.
-**
-** Code is written in ANSI C for portability.
-*/
-
-#ifdef TESTMAIN
-#include <stdlib.h>
-#else
-#include <stand.h>
-#endif
-#include <string.h>
-#include "ficl.h"
-
-
-/*
-** Local prototypes
-*/
-
-
-/*
-** System statics
-** The system builds a global dictionary during its start
-** sequence. This is shared by all interpreter instances.
-** Therefore only one instance can update the dictionary
-** at a time. The system imports a locking function that
-** you can override in order to control update access to
-** the dictionary. The function is stubbed out by default,
-** but you can insert one: #define FICL_MULTITHREAD 1
-** and supply your own version of ficlLockDictionary.
-*/
-static FICL_DICT *dp = NULL;
-static FICL_DICT *envp = NULL;
-#if FICL_WANT_LOCALS
-static FICL_DICT *localp = NULL;
-#endif
-static FICL_VM *vmList = NULL;
-
-static int defaultStack = FICL_DEFAULT_STACK;
-static int defaultDict = FICL_DEFAULT_DICT;
-
-
-/**************************************************************************
- f i c l I n i t S y s t e m
-** Binds a global dictionary to the interpreter system.
-** You specify the address and size of the allocated area.
-** After that, ficl manages it.
-** First step is to set up the static pointers to the area.
-** Then write the "precompiled" portion of the dictionary in.
-** The dictionary needs to be at least large enough to hold the
-** precompiled part. Try 1K cells minimum. Use "words" to find
-** out how much of the dictionary is used at any time.
-**************************************************************************/
-void ficlInitSystem(int nDictCells)
-{
- if (dp)
- dictDelete(dp);
-
- if (envp)
- dictDelete(envp);
-
-#if FICL_WANT_LOCALS
- if (localp)
- dictDelete(localp);
-#endif
-
- if (nDictCells <= 0)
- nDictCells = defaultDict;
-
- dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE);
- envp = dictCreate( (unsigned)FICL_DEFAULT_ENV);
-#if FICL_WANT_LOCALS
- /*
- ** The locals dictionary is only searched while compiling,
- ** but this is where speed is most important. On the other
- ** hand, the dictionary gets emptied after each use of locals
- ** The need to balance search speed with the cost of the empty
- ** operation led me to select a single-threaded list...
- */
- localp = dictCreate( (unsigned)FICL_MAX_LOCALS * CELLS_PER_WORD);
-#endif
-
- ficlCompileCore(dp);
-
- return;
-}
-
-
-/**************************************************************************
- f i c l N e w V M
-** Create a new virtual machine and link it into the system list
-** of VMs for later cleanup by ficlTermSystem. If this is the first
-** VM to be created, use it to compile the words in softcore.c
-**************************************************************************/
-FICL_VM *ficlNewVM(void)
-{
- FICL_VM *pVM = vmCreate(NULL, defaultStack, defaultStack);
- pVM->link = vmList;
-
- /*
- ** Borrow the first vm to build the soft words in softcore.c
- */
- if (vmList == NULL)
- ficlCompileSoftCore(pVM);
-
- vmList = pVM;
- return pVM;
-}
-
-
-/**************************************************************************
- f i c l B u i l d
-** Builds a word into the dictionary.
-** Preconditions: system must be initialized, and there must
-** be enough space for the new word's header! Operation is
-** controlled by ficlLockDictionary, so any initialization
-** required by your version of the function (if you overrode
-** it) must be complete at this point.
-** Parameters:
-** name -- duh, the name of the word
-** code -- code to execute when the word is invoked - must take a single param
-** pointer to a FICL_VM
-** flags -- 0 or more of F_IMMEDIATE, F_COMPILE, use bitwise OR!
-**
-**************************************************************************/
-int ficlBuild(char *name, FICL_CODE code, char flags)
-{
- int err = ficlLockDictionary(TRUE);
- if (err) return err;
-
- dictAppendWord(dp, name, code, flags);
-
- ficlLockDictionary(FALSE);
- return 0;
-}
-
-
-/**************************************************************************
- f i c l E x e c
-** Evaluates a block of input text in the context of the
-** specified interpreter. Emits any requested output to the
-** interpreter's output function.
-**
-** Contains the "inner interpreter" code in a tight loop
-**
-** Returns one of the VM_XXXX codes defined in ficl.h:
-** VM_OUTOFTEXT is the normal exit condition
-** VM_ERREXIT means that the interp encountered a syntax error
-** and the vm has been reset to recover (some or all
-** of the text block got ignored
-** VM_USEREXIT means that the user executed the "bye" command
-** to shut down the interpreter. This would be a good
-** time to delete the vm, etc -- or you can ignore this
-** signal.
-**************************************************************************/
-int ficlExec(FICL_VM *pVM, char *pText)
-{
- int except;
- FICL_WORD *tempFW;
- jmp_buf vmState;
- jmp_buf *oldState;
- TIB saveTib;
-
- assert(pVM);
-
- vmPushTib(pVM, pText, &saveTib);
-
- /*
- ** Save and restore VM's jmp_buf to enable nested calls to ficlExec
- */
- oldState = pVM->pState;
- pVM->pState = &vmState; /* This has to come before the setjmp! */
- except = setjmp(vmState);
-
- switch (except)
- {
- case 0:
- if (pVM->fRestart)
- {
- pVM->fRestart = 0;
- pVM->runningWord->code(pVM);
- }
-
- /*
- ** the mysterious inner interpreter...
- ** vmThrow gets you out of this loop with a longjmp()
- */
- for (;;)
- {
- tempFW = *pVM->ip++;
- /*
- ** inline code for
- ** vmExecute(pVM, tempFW);
- */
- pVM->runningWord = tempFW;
- tempFW->code(pVM);
- }
-
- break;
-
- case VM_RESTART:
- pVM->fRestart = 1;
- except = VM_OUTOFTEXT;
- break;
-
- case VM_OUTOFTEXT:
-#ifdef TESTMAIN
- if ((pVM->state != COMPILE) && (pVM->sourceID.i == 0))
- ficlTextOut(pVM, FICL_PROMPT, 0);
-#endif
- break;
-
- case VM_USEREXIT:
- break;
-
- case VM_QUIT:
- if (pVM->state == COMPILE)
- dictAbortDefinition(dp);
- vmQuit(pVM);
- break;
-
- case VM_ERREXIT:
- default: /* user defined exit code?? */
- if (pVM->state == COMPILE)
- {
- dictAbortDefinition(dp);
-#if FICL_WANT_LOCALS
- dictEmpty(localp, localp->pForthWords->size);
-#endif
- }
- dictResetSearchOrder(dp);
- vmReset(pVM);
- break;
- }
-
- pVM->pState = oldState;
- vmPopTib(pVM, &saveTib);
- return (except);
-}
-
-/**************************************************************************
- f i c l E x e c F D
-** reads in text from file fd and passes it to ficlExec()
- * returns VM_OUTOFTEXT on success or the ficlExec() error code on
- * failure.
- */
-#define nLINEBUF 256
-int ficlExecFD(FICL_VM *pVM, int fd)
-{
- char cp[nLINEBUF];
- int i, nLine = 0, rval = VM_OUTOFTEXT;
- char ch;
- CELL id;
-
- id = pVM->sourceID;
- pVM->sourceID.i = fd;
-
- /* feed each line to ficlExec */
- while (1) {
- int status, i;
-
- i = 0;
- while ((status = read(fd, &ch, 1)) > 0 && ch != '\n')
- cp[i++] = ch;
- nLine++;
- if (!i) {
- if (status < 1)
- break;
- continue;
- }
- cp[i] = '\0';
- if ((rval = ficlExec(pVM, cp)) >= VM_ERREXIT)
- {
- pVM->sourceID = id;
- vmThrowErr(pVM, "ficlExecFD: Error at line %d", nLine);
- break;
- }
- }
- /*
- ** Pass an empty line with SOURCE-ID == 0 to flush
- ** any pending REFILLs (as required by FILE wordset)
- */
- pVM->sourceID.i = -1;
- ficlExec(pVM, "");
-
- pVM->sourceID = id;
- return rval;
-}
-
-/**************************************************************************
- f i c l L o o k u p
-** Look in the system dictionary for a match to the given name. If
-** found, return the address of the corresponding FICL_WORD. Otherwise
-** return NULL.
-**************************************************************************/
-FICL_WORD *ficlLookup(char *name)
-{
- STRINGINFO si;
- SI_PSZ(si, name);
- return dictLookup(dp, si);
-}
-
-
-/**************************************************************************
- f i c l G e t D i c t
-** Returns the address of the system dictionary
-**************************************************************************/
-FICL_DICT *ficlGetDict(void)
-{
- return dp;
-}
-
-
-/**************************************************************************
- f i c l G e t E n v
-** Returns the address of the system environment space
-**************************************************************************/
-FICL_DICT *ficlGetEnv(void)
-{
- return envp;
-}
-
-
-/**************************************************************************
- f i c l S e t E n v
-** Create an environment variable with a one-CELL payload. ficlSetEnvD
-** makes one with a two-CELL payload.
-**************************************************************************/
-void ficlSetEnv(char *name, UNS32 value)
-{
- STRINGINFO si;
- FICL_WORD *pFW;
-
- SI_PSZ(si, name);
- pFW = dictLookup(envp, si);
-
- if (pFW == NULL)
- {
- dictAppendWord(envp, name, constantParen, FW_DEFAULT);
- dictAppendCell(envp, LVALUEtoCELL(value));
- }
- else
- {
- pFW->param[0] = LVALUEtoCELL(value);
- }
-
- return;
-}
-
-void ficlSetEnvD(char *name, UNS32 hi, UNS32 lo)
-{
- FICL_WORD *pFW;
- STRINGINFO si;
- SI_PSZ(si, name);
- pFW = dictLookup(envp, si);
-
- if (pFW == NULL)
- {
- dictAppendWord(envp, name, twoConstParen, FW_DEFAULT);
- dictAppendCell(envp, LVALUEtoCELL(lo));
- dictAppendCell(envp, LVALUEtoCELL(hi));
- }
- else
- {
- pFW->param[0] = LVALUEtoCELL(lo);
- pFW->param[1] = LVALUEtoCELL(hi);
- }
-
- return;
-}
-
-
-/**************************************************************************
- f i c l G e t L o c
-** Returns the address of the system locals dictionary. This dict is
-** only used during compilation, and is shared by all VMs.
-**************************************************************************/
-#if FICL_WANT_LOCALS
-FICL_DICT *ficlGetLoc(void)
-{
- return localp;
-}
-#endif
-
-
-/**************************************************************************
- f i c l T e r m S y s t e m
-** Tear the system down by deleting the dictionaries and all VMs.
-** This saves you from having to keep track of all that stuff.
-**************************************************************************/
-void ficlTermSystem(void)
-{
- if (dp)
- dictDelete(dp);
- dp = NULL;
-
- if (envp)
- dictDelete(envp);
- envp = NULL;
-
-#if FICL_WANT_LOCALS
- if (localp)
- dictDelete(localp);
- localp = NULL;
-#endif
-
- while (vmList != NULL)
- {
- FICL_VM *pVM = vmList;
- vmList = vmList->link;
- vmDelete(pVM);
- }
-
- return;
-}
diff --git a/sys/boot/ficl/ficl.h b/sys/boot/ficl/ficl.h
deleted file mode 100644
index 3fcb32efbb81..000000000000
--- a/sys/boot/ficl/ficl.h
+++ /dev/null
@@ -1,773 +0,0 @@
-/*******************************************************************
-** f i c l . h
-** Forth Inspired Command Language
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 19 July 1997
-**
-*******************************************************************/
-/*
-** N O T I C E -- DISCLAIMER OF WARRANTY
-**
-** Ficl is freeware. Use it in any way that you like, with
-** the understanding that the code is supported on a "best effort"
-** basis only.
-**
-** Any third party may reproduce, distribute, or modify the ficl
-** software code or any derivative works thereof without any
-** compensation or license, provided that the author information
-** and this disclaimer text are retained in the source code files.
-** The ficl software code is provided on an "as is" basis without
-** warranty of any kind, including, without limitation, the implied
-** warranties of merchantability and fitness for a particular purpose
-** and their equivalents under the laws of any jurisdiction.
-**
-** I am interested in hearing from anyone who uses ficl. If you have
-** a problem, a success story, a defect, an enhancement request, or
-** if you would like to contribute to the ficl release (yay!), please
-** send me email at the address above.
-*/
-
-#if !defined (__FICL_H__)
-#define __FICL_H__
-/*
-** Ficl (Forth-inspired command language) is an ANS Forth
-** interpreter written in C. Unlike traditional Forths, this
-** interpreter is designed to be embedded into other systems
-** as a command/macro/development prototype language.
-**
-** Where Forths usually view themselves as the center of the system
-** and expect the rest of the system to be coded in Forth, Ficl
-** acts as a component of the system. It is easy to export
-** code written in C or ASM to Ficl in the style of TCL, or to invoke
-** Ficl code from a compiled module. This allows you to do incremental
-** development in a way that combines the best features of threaded
-** languages (rapid development, quick code/test/debug cycle,
-** reasonably fast) with the best features of C (everyone knows it,
-** easier to support large blocks of code, efficient, type checking).
-**
-** Ficl provides facilities for interoperating
-** with programs written in C: C functions can be exported to Ficl,
-** and Ficl commands can be executed via a C calling interface. The
-** interpreter is re-entrant, so it can be used in multiple instances
-** in a multitasking system. Unlike Forth, Ficl's outer interpreter
-** expects a text block as input, and returns to the caller after each
-** text block, so the "data pump" is somewhere in external code. This
-** is more like TCL than Forth, which usually expcets to be at the center
-** of the system, requesting input at its convenience. Each Ficl virtual
-** machine can be bound to a different I/O channel, and is independent
-** of all others in in the same address space except that all virtual
-** machines share a common dictionary (a sort or open symbol table that
-** defines all of the elements of the language).
-**
-** Code is written in ANSI C for portability.
-**
-** Summary of Ficl features and constraints:
-** - Standard: Implements the ANSI Forth CORE word set and part
-** of the CORE EXT word-set, SEARCH and SEARCH EXT, TOOLS and
-** TOOLS EXT, LOCAL and LOCAL ext and various extras.
-** - Extensible: you can export code written in Forth, C,
-** or asm in a straightforward way. Ficl provides open
-** facilities for extending the language in an application
-** specific way. You can even add new control structures!
-** - Ficl and C can interact in two ways: Ficl can encapsulate
-** C code, or C code can invoke Ficl code.
-** - Thread-safe, re-entrant: The shared system dictionary
-** uses a locking mechanism that you can either supply
-** or stub out to provide exclusive access. Each Ficl
-** virtual machine has an otherwise complete state, and
-** each can be bound to a separate I/O channel (or none at all).
-** - Simple encapsulation into existing systems: a basic implementation
-** requires three function calls (see the example program in testmain.c).
-** - ROMable: Ficl is designed to work in RAM-based and ROM code / RAM data
-** environments. It does require somewhat more memory than a pure
-** ROM implementation because it builds its system dictionary in
-** RAM at startup time.
-** - Written an ANSI C to be as simple as I can make it to understand,
-** support, debug, and port. Compiles without complaint at /Az /W4
-** (require ANSI C, max warnings) under Microsoft VC++ 5.
-** - Does full 32 bit math (but you need to implement
-** two mixed precision math primitives (see sysdep.c))
-** - Indirect threaded interpreter is not the fastest kind of
-** Forth there is (see pForth 68K for a really fast subroutine
-** threaded interpreter), but it's the cleanest match to a
-** pure C implementation.
-**
-** P O R T I N G F i c l
-**
-** To install Ficl on your target system, you need an ANSI C compiler
-** and its runtime library. Inspect the system dependent macros and
-** functions in sysdep.h and sysdep.c and edit them to suit your
-** system. For example, INT16 is a short on some compilers and an
-** int on others. Check the default CELL alignment controlled by
-** FICL_ALIGN. If necessary, add new definitions of ficlMalloc, ficlFree,
-** ficlLockDictionary, and ficlTextOut to work with your operating system.
-** Finally, use testmain.c as a guide to installing the Ficl system and
-** one or more virtual machines into your code. You do not need to include
-** testmain.c in your build.
-**
-** T o D o L i s t
-**
-** 1. Unimplemented system dependent CORE word: key
-** 2. Kludged CORE word: ACCEPT
-** 3. Dictionary locking is full of holes - only one vm at a time
-** can alter the dict.
-** 4. Ficl uses the pad in CORE words - this violates the standard,
-** but it's cleaner for a multithreaded system. I'll have to make a
-** second pad for reference by the word PAD to fix this.
-**
-** F o r M o r e I n f o r m a t i o n
-**
-** Web home of ficl
-** http://www.taygeta.com/forth/compilers
-** Check this website for Forth literature (including the ANSI standard)
-** http://www.taygeta.com/forthlit.html
-** and here for software and more links
-** http://www.taygeta.com/forth.html
-**
-** Obvious Performance enhancement opportunities
-** Compile speed
-** - work on interpret speed
-** - turn off locals (FICL_WANT_LOCALS)
-** Interpret speed
-** - Change inner interpreter (and everything else)
-** so that a definition is a list of pointers to functions
-** and inline data rather than pointers to words. This gets
-** rid of vm->runningWord and a level of indirection in the
-** inner loop. I'll look at it for ficl 3.0
-** - Make the main hash table a bigger prime (HASHSIZE)
-** - FORGET about twiddling the hash function - my experience is
-** that that is a waste of time.
-** - eliminate the need to pass the pVM parameter on the stack
-** by dedicating a register to it. Most words need access to the
-** vm, but the parameter passing overhead can be reduced. One way
-** requires that the host OS have a task switch callout. Create
-** a global variable for the running VM and refer to it in words
-** that need VM access. Alternative: use thread local storage.
-** For single threaded implementations, you can just use a global.
-** The first two solutions create portability problems, so I
-** haven't considered doing them. Another possibility is to
-** declare the pVm parameter to be "register", and hope the compiler
-** pays attention.
-**
-*/
-
-/*
-** Revision History:
-** 27 Aug 1998 (sadler) testing and corrections for LOCALS, LOCALS EXT,
-** SEARCH / SEARCH EXT, TOOLS / TOOLS EXT.
-** Added .X to display in hex, PARSE and PARSE-WORD to supplement WORD,
-** EMPTY to clear stack.
-**
-** 29 jun 1998 (sadler) added variable sized hash table support
-** and ANS Forth optional SEARCH & SEARCH EXT word set.
-** 26 May 1998 (sadler)
-** FICL_PROMPT macro
-** 14 April 1998 (sadler) V1.04
-** Ficlwin: Windows version, Skip Carter's Linux port
-** 5 March 1998 (sadler) V1.03
-** Bug fixes -- passes John Ryan's ANS test suite "core.fr"
-**
-** 24 February 1998 (sadler) V1.02
-** -Fixed bugs in <# # #>
-** -Changed FICL_WORD so that storage for the name characters
-** can be allocated from the dictionary as needed rather than
-** reserving 32 bytes in each word whether needed or not -
-** this saved 50% of the dictionary storage requirement.
-** -Added words in testmain for Win32 functions system,chdir,cwd,
-** also added a word that loads and evaluates a file.
-**
-** December 1997 (sadler)
-** -Added VM_RESTART exception handling in ficlExec -- this lets words
-** that require additional text to succeed (like :, create, variable...)
-** recover gracefully from an empty input buffer rather than emitting
-** an error message. Definitions can span multiple input blocks with
-** no restrictions.
-** -Changed #include order so that <assert.h> is included in sysdep.h,
-** and sysdep is included in all other files. This lets you define
-** NDEBUG in sysdep.h to disable assertions if you want to.
-** -Make PC specific system dependent code conditional on _M_IX86
-** defined so that ports can coexist in sysdep.h/sysdep.c
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "sysdep.h"
-#include <limits.h> /* UCHAR_MAX */
-
-/*
-** Forward declarations... read on.
-*/
-struct ficl_word;
-struct vm;
-struct ficl_dict;
-
-/*
-** the Good Stuff starts here...
-*/
-#define FICL_VER "2.02"
-#ifndef FICL_PROMPT
-# define FICL_PROMPT "ok> "
-#endif
-
-/*
-** ANS Forth requires false to be zero, and true to be the ones
-** complement of false... that unifies logical and bitwise operations
-** nicely.
-*/
-#define FICL_TRUE (0xffffffffL)
-#define FICL_FALSE (0)
-#define FICL_BOOL(x) ((x) ? FICL_TRUE : FICL_FALSE)
-
-
-/*
-** A CELL is the main storage type. It must be large enough
-** to contain a pointer or a scalar. Let's be picky and make
-** a 32 bit cell explicitly...
-*/
-typedef union _cell
-{
- INT32 i;
- UNS32 u;
- void *p;
-} CELL;
-
-/*
-** LVALUEtoCELL does a little pointer trickery to cast any 32 bit
-** lvalue (informal definition: an expression whose result has an
-** address) to CELL. Remember that constants and casts are NOT
-** themselves lvalues!
-*/
-#define LVALUEtoCELL(v) (*(CELL *)&v)
-
-/*
-** PTRtoCELL is a cast through void * intended to satisfy the
-** most outrageously pedantic compiler... (I won't mention
-** its name)
-*/
-#define PTRtoCELL (CELL *)(void *)
-#define PTRtoSTRING (FICL_STRING *)(void *)
-
-/*
-** Strings in FICL are stored in Pascal style - with a count
-** preceding the text. We'll also NULL-terminate them so that
-** they work with the usual C lib string functions. (Belt &
-** suspenders? You decide.)
-** STRINGINFO hides the implementation with a couple of
-** macros for use in internal routines.
-*/
-
-typedef unsigned char FICL_COUNT;
-#define FICL_STRING_MAX UCHAR_MAX
-typedef struct _ficl_string
-{
- FICL_COUNT count;
- char text[1];
-} FICL_STRING;
-
-typedef struct
-{
- UNS32 count;
- char *cp;
-} STRINGINFO;
-
-#define SI_COUNT(si) (si.count)
-#define SI_PTR(si) (si.cp)
-#define SI_SETLEN(si, len) (si.count = (UNS32)(len))
-#define SI_SETPTR(si, ptr) (si.cp = (char *)(ptr))
-/*
-** Init a STRINGINFO from a pointer to NULL-terminated string
-*/
-#define SI_PSZ(si, psz) \
- {si.cp = psz; si.count = (FICL_COUNT)strlen(psz);}
-/*
-** Init a STRINGINFO from a pointer to FICL_STRING
-*/
-#define SI_PFS(si, pfs) \
- {si.cp = pfs->text; si.count = pfs->count;}
-
-/*
-** Ficl uses a this little structure to hold the address of
-** the block of text it's working on and an index to the next
-** unconsumed character in the string. Traditionally, this is
-** done by a Text Input Buffer, so I've called this struct TIB.
-*/
-typedef struct
-{
- INT32 index;
- char *cp;
-} TIB;
-
-
-/*
-** Stacks get heavy use in Ficl and Forth...
-** Each virtual machine implements two of them:
-** one holds parameters (data), and the other holds return
-** addresses and control flow information for the virtual
-** machine. (Note: C's automatic stack is implicitly used,
-** but not modeled because it doesn't need to be...)
-** Here's an abstract type for a stack
-*/
-typedef struct _ficlStack
-{
- UNS32 nCells; /* size of the stack */
- CELL *pFrame; /* link reg for stack frame */
- CELL *sp; /* stack pointer */
- CELL base[1]; /* Bottom of the stack */
-} FICL_STACK;
-
-/*
-** Stack methods... many map closely to required Forth words.
-*/
-FICL_STACK *stackCreate(unsigned nCells);
-void stackDelete(FICL_STACK *pStack);
-int stackDepth (FICL_STACK *pStack);
-void stackDrop (FICL_STACK *pStack, int n);
-CELL stackFetch (FICL_STACK *pStack, int n);
-CELL stackGetTop(FICL_STACK *pStack);
-void stackLink (FICL_STACK *pStack, int nCells);
-void stackPick (FICL_STACK *pStack, int n);
-CELL stackPop (FICL_STACK *pStack);
-void *stackPopPtr (FICL_STACK *pStack);
-UNS32 stackPopUNS32 (FICL_STACK *pStack);
-INT32 stackPopINT32 (FICL_STACK *pStack);
-void stackPush (FICL_STACK *pStack, CELL c);
-void stackPushPtr (FICL_STACK *pStack, void *ptr);
-void stackPushUNS32(FICL_STACK *pStack, UNS32 u);
-void stackPushINT32(FICL_STACK *pStack, INT32 i);
-void stackReset (FICL_STACK *pStack);
-void stackRoll (FICL_STACK *pStack, int n);
-void stackSetTop(FICL_STACK *pStack, CELL c);
-void stackStore (FICL_STACK *pStack, int n, CELL c);
-void stackUnlink(FICL_STACK *pStack);
-
-/*
-** The virtual machine (VM) contains the state for one interpreter.
-** Defined operations include:
-** Create & initialize
-** Delete
-** Execute a block of text
-** Parse a word out of the input stream
-** Call return, and branch
-** Text output
-** Throw an exception
-*/
-
-typedef struct ficl_word ** IPTYPE; /* the VM's instruction pointer */
-
-/*
-** Each VM has a placeholder for an output function -
-** this makes it possible to have each VM do I/O
-** through a different device. If you specify no
-** OUTFUNC, it defaults to ficlTextOut.
-*/
-typedef void (*OUTFUNC)(struct vm *pVM, char *text, int fNewline);
-
-/*
-** Each VM operates in one of two non-error states: interpreting
-** or compiling. When interpreting, words are simply executed.
-** When compiling, most words in the input stream have their
-** addresses inserted into the word under construction. Some words
-** (known as IMMEDIATE) are executed in the compile state, too.
-*/
-/* values of STATE */
-#define INTERPRET 0
-#define COMPILE 1
-
-/*
-** The pad is a small scratch area for text manipulation. ANS Forth
-** requires it to hold at least 84 characters.
-*/
-#if !defined nPAD
-#define nPAD 256
-#endif
-
-/*
-** ANS Forth requires that a word's name contain {1..31} characters.
-*/
-#if !defined nFICLNAME
-#define nFICLNAME 31
-#endif
-
-/*
-** OK - now we can really define the VM...
-*/
-typedef struct vm
-{
- struct vm *link; /* Ficl keeps a VM list for simple teardown */
- jmp_buf *pState; /* crude exception mechanism... */
- OUTFUNC textOut; /* Output callback - see sysdep.c */
- void * pExtend; /* vm extension pointer */
- short fRestart; /* Set TRUE to restart runningWord */
- IPTYPE ip; /* instruction pointer */
- struct ficl_word
- *runningWord;/* address of currently running word (often just *(ip-1) ) */
- UNS32 state; /* compiling or interpreting */
- UNS32 base; /* number conversion base */
- FICL_STACK *pStack; /* param stack */
- FICL_STACK *rStack; /* return stack */
- CELL sourceID; /* -1 if string, 0 if normal input */
- TIB tib; /* address of incoming text string */
-#if FICL_WANT_USER
- CELL user[FICL_USER_CELLS];
-#endif
- char pad[nPAD]; /* the scratch area (see above) */
-} FICL_VM;
-
-/*
-** A FICL_CODE points to a function that gets called to help execute
-** a word in the dictionary. It always gets passed a pointer to the
-** running virtual machine, and from there it can get the address
-** of the parameter area of the word it's supposed to operate on.
-** For precompiled words, the code is all there is. For user defined
-** words, the code assumes that the word's parameter area is a list
-** of pointers to the code fields of other words to execute, and
-** may also contain inline data. The first parameter is always
-** a pointer to a code field.
-*/
-typedef void (*FICL_CODE)(FICL_VM *pVm);
-
-/*
-** Ficl models memory as a contiguous space divided into
-** words in a linked list called the dictionary.
-** A FICL_WORD starts each entry in the list.
-** Version 1.02: space for the name characters is allotted from
-** the dictionary ahead of the word struct - this saves about half
-** the storage on average with very little runtime cost.
-*/
-typedef struct ficl_word
-{
- struct ficl_word *link; /* Previous word in the dictionary */
- UNS16 hash;
- UNS8 flags; /* Immediate, Smudge, Compile-only */
- FICL_COUNT nName; /* Number of chars in word name */
- char *name; /* First nFICLNAME chars of word name */
- FICL_CODE code; /* Native code to execute the word */
- CELL param[1]; /* First data cell of the word */
-} FICL_WORD;
-
-/*
-** Worst-case size of a word header: nFICLNAME chars in name
-*/
-#define CELLS_PER_WORD \
- ( (sizeof (FICL_WORD) + nFICLNAME + sizeof (CELL)) \
- / (sizeof (CELL)) )
-
-int wordIsImmediate(FICL_WORD *pFW);
-int wordIsCompileOnly(FICL_WORD *pFW);
-
-/* flag values for word header */
-#define FW_IMMEDIATE 1 /* execute me even if compiling */
-#define FW_COMPILE 2 /* error if executed when not compiling */
-#define FW_SMUDGE 4 /* definition in progress - hide me */
-#define FW_CLASS 8 /* Word defines a class */
-
-#define FW_COMPIMMED (FW_IMMEDIATE | FW_COMPILE)
-#define FW_DEFAULT 0
-
-
-/*
-** Exit codes for vmThrow
-*/
-#define VM_OUTOFTEXT 1 /* hungry - normal exit */
-#define VM_RESTART 2 /* word needs more text to suxcceed - re-run it */
-#define VM_USEREXIT 3 /* user wants to quit */
-#define VM_ERREXIT 4 /* interp found an error */
-#define VM_QUIT 5 /* like errexit, but leave pStack & base alone */
-
-
-void vmBranchRelative(FICL_VM *pVM, int offset);
-FICL_VM * vmCreate (FICL_VM *pVM, unsigned nPStack, unsigned nRStack);
-void vmDelete (FICL_VM *pVM);
-void vmExecute(FICL_VM *pVM, FICL_WORD *pWord);
-char * vmGetString(FICL_VM *pVM, FICL_STRING *spDest, char delimiter);
-STRINGINFO vmGetWord(FICL_VM *pVM);
-STRINGINFO vmGetWord0(FICL_VM *pVM);
-int vmGetWordToPad(FICL_VM *pVM);
-STRINGINFO vmParseString(FICL_VM *pVM, char delimiter);
-void vmPopIP (FICL_VM *pVM);
-void vmPushIP (FICL_VM *pVM, IPTYPE newIP);
-void vmQuit (FICL_VM *pVM);
-void vmReset (FICL_VM *pVM);
-void vmSetTextOut(FICL_VM *pVM, OUTFUNC textOut);
-void vmTextOut(FICL_VM *pVM, char *text, int fNewline);
-void vmThrow (FICL_VM *pVM, int except);
-void vmThrowErr(FICL_VM *pVM, char *fmt, ...);
-
-/*
-** vmCheckStack needs a vm pointer because it might have to say
-** something if it finds a problem. Parms popCells and pushCells
-** correspond to the number of parameters on the left and right of
-** a word's stack effect comment.
-*/
-void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells);
-
-/*
-** TIB access routines...
-** ANS forth seems to require the input buffer to be represented
-** as a pointer to the start of the buffer, and an index to the
-** next character to read.
-** PushTib points the VM to a new input string and optionally
-** returns a copy of the current state
-** PopTib restores the TIB state given a saved TIB from PushTib
-** GetInBuf returns a pointer to the next unused char of the TIB
-*/
-void vmPushTib(FICL_VM *pVM, char *text, TIB *pSaveTib);
-void vmPopTib(FICL_VM *pVM, TIB *pTib);
-#define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index)
-#define vmSetTibIndex(pVM, i) (pVM)->tib.index = i
-#define vmUpdateTib(pVM, str) (pVM)->tib.index = (str) - (pVM)->tib.cp
-
-/*
-** Generally useful string manipulators omitted by ANSI C...
-** ltoa complements strtol
-*/
-#if defined(_WIN32) && !FICL_MAIN
-/* #SHEESH
-** Why do Microsoft Meatballs insist on contaminating
-** my namespace with their string functions???
-*/
-#pragma warning(disable: 4273)
-#endif
-
-char *ltoa( INT32 value, char *string, int radix );
-char *ultoa(UNS32 value, char *string, int radix );
-char digit_to_char(int value);
-char *strrev( char *string );
-char *skipSpace(char *cp);
-char *caseFold(char *cp);
-int strincmp(char *cp1, char *cp2, FICL_COUNT count);
-
-#if defined(_WIN32) && !FICL_MAIN
-#pragma warning(default: 4273)
-#endif
-
-/*
-** Ficl hash table - variable size.
-** assert(size > 0)
-** If size is 1, the table degenerates into a linked list.
-** A WORDLIST (see the search order word set in DPANS) is
-** just a pointer to a FICL_HASH in this implementation.
-*/
-#if !defined HASHSIZE /* Default size of hash table. For best */
-#define HASHSIZE 127 /* performance, use a prime number! */
-#endif
-
-typedef struct ficl_hash
-{
- struct ficl_hash *link; /* eventual inheritance support */
- unsigned size;
- FICL_WORD *table[1];
-} FICL_HASH;
-
-void hashForget(FICL_HASH *pHash, void *where);
-UNS16 hashHashCode(STRINGINFO si);
-void hashInsertWord(FICL_HASH *pHash, FICL_WORD *pFW);
-FICL_WORD *hashLookup(struct ficl_hash *pHash,
- STRINGINFO si,
- UNS16 hashCode);
-void hashReset(FICL_HASH *pHash);
-
-/*
-** A Dictionary is a linked list of FICL_WORDs. It is also Ficl's
-** memory model. Description of fields:
-**
-** here -- points to the next free byte in the dictionary. This
-** pointer is forced to be CELL-aligned before a definition is added.
-** Do not assume any specific alignment otherwise - Use dictAlign().
-**
-** smudge -- pointer to word currently being defined (or last defined word)
-** If the definition completes successfully, the word will be
-** linked into the hash table. If unsuccessful, dictUnsmudge
-** uses this pointer to restore the previous state of the dictionary.
-** Smudge prevents unintentional recursion as a side-effect: the
-** dictionary search algo examines only completed definitions, so a
-** word cannot invoke itself by name. See the ficl word "recurse".
-** NOTE: smudge always points to the last word defined. IMMEDIATE
-** makes use of this fact. Smudge is initially NULL.
-**
-** pForthWords -- pointer to the default wordlist (FICL_HASH).
-** This is the initial compilation list, and contains all
-** ficl's precompiled words.
-**
-** pCompile -- compilation wordlist - initially equal to pForthWords
-** pSearch -- array of pointers to wordlists. Managed as a stack.
-** Highest index is the first list in the search order.
-** nLists -- number of lists in pSearch. nLists-1 is the highest
-** filled slot in pSearch, and points to the first wordlist
-** in the search order
-** size -- number of cells in the dictionary (total)
-** dict -- start of data area. Must be at the end of the struct.
-*/
-typedef struct ficl_dict
-{
- CELL *here;
- FICL_WORD *smudge;
- FICL_HASH *pForthWords;
- FICL_HASH *pCompile;
- FICL_HASH *pSearch[FICL_DEFAULT_VOCS];
- int nLists;
- unsigned size; /* Number of cells in dict (total)*/
- CELL dict[1]; /* Base of dictionary memory */
-} FICL_DICT;
-
-void *alignPtr(void *ptr);
-void dictAbortDefinition(FICL_DICT *pDict);
-void dictAlign(FICL_DICT *pDict);
-int dictAllot(FICL_DICT *pDict, int n);
-int dictAllotCells(FICL_DICT *pDict, int nCells);
-void dictAppendCell(FICL_DICT *pDict, CELL c);
-void dictAppendChar(FICL_DICT *pDict, char c);
-FICL_WORD *dictAppendWord(FICL_DICT *pDict,
- char *name,
- FICL_CODE pCode,
- UNS8 flags);
-FICL_WORD *dictAppendWord2(FICL_DICT *pDict,
- STRINGINFO si,
- FICL_CODE pCode,
- UNS8 flags);
-void dictAppendUNS32(FICL_DICT *pDict, UNS32 u);
-int dictCellsAvail(FICL_DICT *pDict);
-int dictCellsUsed (FICL_DICT *pDict);
-void dictCheck(FICL_DICT *pDict, FICL_VM *pVM, int nCells);
-FICL_DICT *dictCreate(unsigned nCELLS);
-FICL_DICT *dictCreateHashed(unsigned nCells, unsigned nHash);
-void dictDelete(FICL_DICT *pDict);
-void dictEmpty(FICL_DICT *pDict, unsigned nHash);
-void dictHashSummary(FICL_VM *pVM);
-int dictIncludes(FICL_DICT *pDict, void *p);
-FICL_WORD *dictLookup(FICL_DICT *pDict, STRINGINFO si);
-#if FICL_WANT_LOCALS
-FICL_WORD *dictLookupLoc(FICL_DICT *pDict, STRINGINFO si);
-#endif
-void dictResetSearchOrder(FICL_DICT *pDict);
-void dictSetFlags(FICL_DICT *pDict, UNS8 set, UNS8 clr);
-void dictSetImmediate(FICL_DICT *pDict);
-void dictUnsmudge(FICL_DICT *pDict);
-CELL *dictWhere(FICL_DICT *pDict);
-
-
-/*
-** External interface to FICL...
-*/
-/*
-** f i c l I n i t S y s t e m
-** Binds a global dictionary to the interpreter system and initializes
-** the dict to contain the ANSI CORE wordset.
-** You specify the address and size of the allocated area.
-** After that, ficl manages it.
-** First step is to set up the static pointers to the area.
-** Then write the "precompiled" portion of the dictionary in.
-** The dictionary needs to be at least large enough to hold the
-** precompiled part. Try 1K cells minimum. Use "words" to find
-** out how much of the dictionary is used at any time.
-*/
-void ficlInitSystem(int nDictCells);
-
-/*
-** f i c l T e r m S y s t e m
-** Deletes the system dictionary and all virtual machines that
-** were created with ficlNewVM (see below). Call this function to
-** reclaim all memory used by the dictionary and VMs.
-*/
-void ficlTermSystem(void);
-
-/*
-** f i c l E x e c
-** Evaluates a block of input text in the context of the
-** specified interpreter. Emits any requested output to the
-** interpreter's output function
-** Execution returns when the text block has been executed,
-** or an error occurs.
-** Returns one of the VM_XXXX codes defined in ficl.h:
-** VM_OUTOFTEXT is the normal exit condition
-** VM_ERREXIT means that the interp encountered a syntax error
-** and the vm has been reset to recover (some or all
-** of the text block got ignored
-** VM_USEREXIT means that the user executed the "bye" command
-** to shut down the interpreter. This would be a good
-** time to delete the vm, etc -- or you can ignore this
-** signal.
-** Preconditions: successful execution of ficlInitSystem,
-** Successful creation and init of the VM by ficlNewVM (or equiv)
-*/
-int ficlExec(FICL_VM *pVM, char *pText);
-
-/*
-** ficlExecFD(FICL_VM *pVM, int fd);
- * Evaluates text from file passed in via fd.
- * Execution returns when all of file has been executed or an
- * error occurs.
- */
-int ficlExecFD(FICL_VM *pVM, int fd);
-
-/*
-** Create a new VM from the heap, and link it into the system VM list.
-** Initializes the VM and binds default sized stacks to it. Returns the
-** address of the VM, or NULL if an error occurs.
-** Precondition: successful execution of ficlInitSystem
-*/
-FICL_VM *ficlNewVM(void);
-
-/*
-** Returns the address of the most recently defined word in the system
-** dictionary with the given name, or NULL if no match.
-** Precondition: successful execution of ficlInitSystem
-*/
-FICL_WORD *ficlLookup(char *name);
-
-/*
-** f i c l G e t D i c t
-** Utility function - returns the address of the system dictionary.
-** Precondition: successful execution of ficlInitSystem
-*/
-FICL_DICT *ficlGetDict(void);
-FICL_DICT *ficlGetEnv(void);
-void ficlSetEnv(char *name, UNS32 value);
-void ficlSetEnvD(char *name, UNS32 hi, UNS32 lo);
-#if FICL_WANT_LOCALS
-FICL_DICT *ficlGetLoc(void);
-#endif
-/*
-** f i c l B u i l d
-** Builds a word into the system default dictionary in a thread-safe way.
-** Preconditions: system must be initialized, and there must
-** be enough space for the new word's header! Operation is
-** controlled by ficlLockDictionary, so any initialization
-** required by your version of the function (if you "overrode"
-** it) must be complete at this point.
-** Parameters:
-** name -- the name of the word to be built
-** code -- code to execute when the word is invoked - must take a single param
-** pointer to a FICL_VM
-** flags -- 0 or more of FW_IMMEDIATE, FW_COMPILE, use bitwise OR!
-** Most words can use FW_DEFAULT.
-** nAllot - number of extra cells to allocate in the parameter area (usually zero)
-*/
-int ficlBuild(char *name, FICL_CODE code, char flags);
-
-/*
-** f i c l C o m p i l e C o r e
-** Builds the ANS CORE wordset into the dictionary - called by
-** ficlInitSystem - no need to waste dict space by doing it again.
-*/
-void ficlCompileCore(FICL_DICT *dp);
-void ficlCompileSoftCore(FICL_VM *pVM);
-
-/*
-** from words.c...
-*/
-void constantParen(FICL_VM *pVM);
-void twoConstParen(FICL_VM *pVM);
-
-#if defined(__i386__) && !defined(TESTMAIN)
-extern void ficlOutb(FICL_VM *pVM);
-extern void ficlInb(FICL_VM *pVM);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __FICL_H__ */
diff --git a/sys/boot/ficl/math64.c b/sys/boot/ficl/math64.c
deleted file mode 100644
index e83000a8b4a2..000000000000
--- a/sys/boot/ficl/math64.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*******************************************************************
-** m a t h 6 4 . c
-** Forth Inspired Command Language - 64 bit math support routines
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 25 January 1998
-**
-*******************************************************************/
-
-#include "ficl.h"
-#include "math64.h"
-
-
-/**************************************************************************
- m 6 4 A b s
-** Returns the absolute value of an INT64
-**************************************************************************/
-INT64 m64Abs(INT64 x)
-{
- if (m64IsNegative(x))
- x = m64Negate(x);
-
- return x;
-}
-
-
-/**************************************************************************
- m 6 4 F l o o r e d D i v I
-**
-** FROM THE FORTH ANS...
-** Floored division is integer division in which the remainder carries
-** the sign of the divisor or is zero, and the quotient is rounded to
-** its arithmetic floor. Symmetric division is integer division in which
-** the remainder carries the sign of the dividend or is zero and the
-** quotient is the mathematical quotient rounded towards zero or
-** truncated. Examples of each are shown in tables 3.3 and 3.4.
-**
-** Table 3.3 - Floored Division Example
-** Dividend Divisor Remainder Quotient
-** -------- ------- --------- --------
-** 10 7 3 1
-** -10 7 4 -2
-** 10 -7 -4 -2
-** -10 -7 -3 1
-**
-**
-** Table 3.4 - Symmetric Division Example
-** Dividend Divisor Remainder Quotient
-** -------- ------- --------- --------
-** 10 7 3 1
-** -10 7 -3 -1
-** 10 -7 3 -1
-** -10 -7 -3 1
-**************************************************************************/
-INTQR m64FlooredDivI(INT64 num, INT32 den)
-{
- INTQR qr;
- UNSQR uqr;
- int signRem = 1;
- int signQuot = 1;
-
- if (m64IsNegative(num))
- {
- num = m64Negate(num);
- signQuot = -signQuot;
- }
-
- if (den < 0)
- {
- den = -den;
- signRem = -signRem;
- signQuot = -signQuot;
- }
-
- uqr = ficlLongDiv(m64CastIU(num), (UNS32)den);
- qr = m64CastQRUI(uqr);
- if (signQuot < 0)
- {
- qr.quot = -qr.quot;
- if (qr.rem != 0)
- {
- qr.quot--;
- qr.rem = den - qr.rem;
- }
- }
-
- if (signRem < 0)
- qr.rem = -qr.rem;
-
- return qr;
-}
-
-
-/**************************************************************************
- m 6 4 I s N e g a t i v e
-** Returns TRUE if the specified INT64 has its sign bit set.
-**************************************************************************/
-int m64IsNegative(INT64 x)
-{
- return (x.hi < 0);
-}
-
-
-/**************************************************************************
- m 6 4 M a c
-** Mixed precision multiply and accumulate primitive for number building.
-** Multiplies UNS64 u by UNS32 mul and adds UNS32 add. Mul is typically
-** the numeric base, and add represents a digit to be appended to the
-** growing number.
-** Returns the result of the operation
-**************************************************************************/
-UNS64 m64Mac(UNS64 u, UNS32 mul, UNS32 add)
-{
- UNS64 resultLo = ficlLongMul(u.lo, mul);
- UNS64 resultHi = ficlLongMul(u.hi, mul);
- resultLo.hi += resultHi.lo;
- resultHi.lo = resultLo.lo + add;
-
- if (resultHi.lo < resultLo.lo)
- resultLo.hi++;
-
- resultLo.lo = resultHi.lo;
-
- return resultLo;
-}
-
-
-/**************************************************************************
- m 6 4 M u l I
-** Multiplies a pair of INT32s and returns an INT64 result.
-**************************************************************************/
-INT64 m64MulI(INT32 x, INT32 y)
-{
- UNS64 prod;
- int sign = 1;
-
- if (x < 0)
- {
- sign = -sign;
- x = -x;
- }
-
- if (y < 0)
- {
- sign = -sign;
- y = -y;
- }
-
- prod = ficlLongMul(x, y);
- if (sign > 0)
- return m64CastUI(prod);
- else
- return m64Negate(m64CastUI(prod));
-}
-
-
-/**************************************************************************
- m 6 4 N e g a t e
-** Negates an INT64 by complementing and incrementing.
-**************************************************************************/
-INT64 m64Negate(INT64 x)
-{
- x.hi = ~x.hi;
- x.lo = ~x.lo;
- x.lo ++;
- if (x.lo == 0)
- x.hi++;
-
- return x;
-}
-
-
-/**************************************************************************
- m 6 4 P u s h
-** Push an INT64 onto the specified stack in the order required
-** by ANS Forth (most significant cell on top)
-** These should probably be macros...
-**************************************************************************/
-void i64Push(FICL_STACK *pStack, INT64 i64)
-{
- stackPushINT32(pStack, i64.lo);
- stackPushINT32(pStack, i64.hi);
- return;
-}
-
-void u64Push(FICL_STACK *pStack, UNS64 u64)
-{
- stackPushINT32(pStack, u64.lo);
- stackPushINT32(pStack, u64.hi);
- return;
-}
-
-
-/**************************************************************************
- m 6 4 P o p
-** Pops an INT64 off the stack in the order required by ANS Forth
-** (most significant cell on top)
-** These should probably be macros...
-**************************************************************************/
-INT64 i64Pop(FICL_STACK *pStack)
-{
- INT64 ret;
- ret.hi = stackPopINT32(pStack);
- ret.lo = stackPopINT32(pStack);
- return ret;
-}
-
-UNS64 u64Pop(FICL_STACK *pStack)
-{
- UNS64 ret;
- ret.hi = stackPopINT32(pStack);
- ret.lo = stackPopINT32(pStack);
- return ret;
-}
-
-
-/**************************************************************************
- m 6 4 S y m m e t r i c D i v
-** Divide an INT64 by an INT32 and return an INT32 quotient and an INT32
-** remainder. The absolute values of quotient and remainder are not
-** affected by the signs of the numerator and denominator (the operation
-** is symmetric on the number line)
-**************************************************************************/
-INTQR m64SymmetricDivI(INT64 num, INT32 den)
-{
- INTQR qr;
- UNSQR uqr;
- int signRem = 1;
- int signQuot = 1;
-
- if (m64IsNegative(num))
- {
- num = m64Negate(num);
- signRem = -signRem;
- signQuot = -signQuot;
- }
-
- if (den < 0)
- {
- den = -den;
- signQuot = -signQuot;
- }
-
- uqr = ficlLongDiv(m64CastIU(num), (UNS32)den);
- qr = m64CastQRUI(uqr);
- if (signRem < 0)
- qr.rem = -qr.rem;
-
- if (signQuot < 0)
- qr.quot = -qr.quot;
-
- return qr;
-}
-
-
-/**************************************************************************
- m 6 4 U M o d
-** Divides an UNS64 by base (an UNS16) and returns an UNS16 remainder.
-** Writes the quotient back to the original UNS64 as a side effect.
-** This operation is typically used to convert an UNS64 to a text string
-** in any base. See words.c:numberSignS, for example.
-** Mechanics: performs 4 ficlLongDivs, each of which produces 16 bits
-** of the quotient. C does not provide a way to divide an UNS32 by an
-** UNS16 and get an UNS32 quotient (ldiv is closest, but it's signed,
-** unfortunately), so I've used ficlLongDiv.
-**************************************************************************/
-UNS16 m64UMod(UNS64 *pUD, UNS16 base)
-{
- UNS64 ud;
- UNSQR qr;
- UNS64 result;
-
- result.hi = result.lo = 0;
-
- ud.hi = 0;
- ud.lo = pUD->hi >> 16;
- qr = ficlLongDiv(ud, (UNS32)base);
- result.hi = qr.quot << 16;
-
- ud.lo = (qr.rem << 16) | (pUD->hi & 0x0000ffff);
- qr = ficlLongDiv(ud, (UNS32)base);
- result.hi |= qr.quot & 0x0000ffff;
-
- ud.lo = (qr.rem << 16) | (pUD->lo >> 16);
- qr = ficlLongDiv(ud, (UNS32)base);
- result.lo = qr.quot << 16;
-
- ud.lo = (qr.rem << 16) | (pUD->lo & 0x0000ffff);
- qr = ficlLongDiv(ud, (UNS32)base);
- result.lo |= qr.quot & 0x0000ffff;
-
- *pUD = result;
-
- return (UNS16)(qr.rem);
-}
-
-
diff --git a/sys/boot/ficl/math64.h b/sys/boot/ficl/math64.h
deleted file mode 100644
index 2b7df37006bd..000000000000
--- a/sys/boot/ficl/math64.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*******************************************************************
-** m a t h 6 4 . h
-** Forth Inspired Command Language - 64 bit math support routines
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 25 January 1998
-**
-*******************************************************************/
-/*
-** N O T I C E -- DISCLAIMER OF WARRANTY
-**
-** Ficl is freeware. Use it in any way that you like, with
-** the understanding that the code is not supported.
-**
-** Any third party may reproduce, distribute, or modify the ficl
-** software code or any derivative works thereof without any
-** compensation or license, provided that the author information
-** and this disclaimer text are retained in the source code files.
-** The ficl software code is provided on an "as is" basis without
-** warranty of any kind, including, without limitation, the implied
-** warranties of merchantability and fitness for a particular purpose
-** and their equivalents under the laws of any jurisdiction.
-**
-** I am interested in hearing from anyone who uses ficl. If you have
-** a problem, a success story, a defect, an enhancement request, or
-** if you would like to contribute to the ficl release (yay!), please
-** send me email at the address above.
-*/
-
-#if !defined (__MATH64_H__)
-#define __MATH64_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-INT64 m64Abs(INT64 x);
-int m64IsNegative(INT64 x);
-UNS64 m64Mac(UNS64 u, UNS32 mul, UNS32 add);
-INT64 m64MulI(INT32 x, INT32 y);
-INT64 m64Negate(INT64 x);
-INTQR m64FlooredDivI(INT64 num, INT32 den);
-void i64Push(FICL_STACK *pStack, INT64 i64);
-INT64 i64Pop(FICL_STACK *pStack);
-void u64Push(FICL_STACK *pStack, UNS64 u64);
-UNS64 u64Pop(FICL_STACK *pStack);
-INTQR m64SymmetricDivI(INT64 num, INT32 den);
-UNS16 m64UMod(UNS64 *pUD, UNS16 base);
-
-#define i64Extend(i64) (i64).hi = ((i64).lo < 0) ? -1L : 0
-#define m64CastIU(i64) (*(UNS64 *)(&(i64)))
-#define m64CastUI(u64) (*(INT64 *)(&(u64)))
-#define m64CastQRIU(iqr) (*(UNSQR *)(&(iqr)))
-#define m64CastQRUI(uqr) (*(INTQR *)(&(uqr)))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/sys/boot/ficl/softwords/classes.fr b/sys/boot/ficl/softwords/classes.fr
deleted file mode 100644
index 75dc35ae0da2..000000000000
--- a/sys/boot/ficl/softwords/classes.fr
+++ /dev/null
@@ -1,140 +0,0 @@
-\ ** ficl/softwords/classes.fr
-\ ** F I C L 2 . 0 C L A S S E S
-\ john sadler 1 sep 98
-\ Needs oop.fr
-
-.( loading ficl utility classes ) cr
-also oop definitions
-
-\ REF subclass holds a pointer to an object. It's
-\ mainly for aggregation to help in making data structures.
-\
-object subclass c-ref
- cell: .class
- cell: .instance
-
- : get ( inst class -- refinst refclass )
- drop 2@ ;
- : set ( refinst refclass inst class -- )
- drop 2! ;
-end-class
-
-object subclass c-byte
- char: .payload
-
- : get drop c@ ;
- : set drop c! ;
-end-class
-
-object subclass c-2byte
- 2 chars: .payload
-
- : get drop w@ ;
- : set drop w! ;
-end-class
-
-object subclass c-4byte
- cell: .payload
-
- : get drop @ ;
- : set drop ! ;
-end-class
-
-
-\ ** C - P T R
-\ Base class for pointers to scalars (not objects).
-\ Note: use c-ref to make references to objects. C-ptr
-\ subclasses refer to untyped quantities of various sizes.
-
-\ Derived classes must specify the size of the thing
-\ they point to, and supply get and set methods.
-
-\ All derived classes must define the @size method:
-\ @size ( inst class -- addr-units )
-\ Returns the size in address units of the thing the pointer
-\ refers to.
-object subclass c-ptr
- c-4byte obj: .addr
-
- \ get the value of the pointer
- : get-ptr ( inst class -- addr )
- c-ptr => .addr
- c-4byte => get
- ;
-
- \ set the pointer to address supplied
- : set-ptr ( addr inst class -- )
- c-ptr => .addr
- c-4byte => set
- ;
-
- \ increment the pointer in place
- : inc-ptr ( inst class -- )
- 2dup 2dup ( i c i c i c )
- c-ptr => get-ptr -rot ( i c addr i c )
- --> @size + -rot ( addr' i c )
- c-ptr => set-ptr
- ;
-
- \ decrement the pointer in place
- : dec-ptr ( inst class -- )
- 2dup 2dup ( i c i c i c )
- c-ptr => get-ptr -rot ( i c addr i c )
- --> @size - -rot ( addr' i c )
- c-ptr => set-ptr
- ;
-
- \ index the pointer in place
- : index-ptr ( index inst class -- )
- locals| class inst index |
- inst class c-ptr => get-ptr ( addr )
- inst class --> @size index * + ( addr' )
- inst class c-ptr => set-ptr
- ;
-
-end-class
-
-
-\ ** C - C E L L P T R
-\ Models a pointer to cell (a 32 bit scalar).
-c-ptr subclass c-cellPtr
- : @size 2drop 4 ;
- \ fetch and store through the pointer
- : get ( inst class -- cell )
- c-ptr => get-ptr @
- ;
- : set ( value inst class -- )
- c-ptr => get-ptr !
- ;
-end-class
-
-
-\ ** C - 2 B Y T E P T R
-\ Models a pointer to a 16 bit scalar
-c-ptr subclass c-2bytePtr
- : @size 2drop 2 ;
- \ fetch and store through the pointer
- : get ( inst class -- value )
- c-ptr => get-ptr w@
- ;
- : set ( value inst class -- )
- c-ptr => get-ptr w!
- ;
-end-class
-
-
-\ ** C - B Y T E P T R
-\ Models a pointer to an 8 bit scalar
-c-ptr subclass c-bytePtr
- : @size 2drop 1 ;
- \ fetch and store through the pointer
- : get ( inst class -- value )
- c-ptr => get-ptr c@
- ;
- : set ( value inst class -- )
- c-ptr => get-ptr c!
- ;
-end-class
-
-
-previous definitions
diff --git a/sys/boot/ficl/softwords/jhlocal.fr b/sys/boot/ficl/softwords/jhlocal.fr
deleted file mode 100644
index 034ada519711..000000000000
--- a/sys/boot/ficl/softwords/jhlocal.fr
+++ /dev/null
@@ -1,77 +0,0 @@
-\ #if FICL_WANT_LOCALS
-\ ** ficl/softwords/jhlocal.fr
-\ ** stack comment style local syntax...
-\ { a b c | cleared -- d e }
-\ variables before the "|" are initialized in reverse order
-\ from the stack. Those after the "|" are zero initialized.
-\ Anything between "--" and "}" is treated as comment
-\ Uses locals...
-\ locstate: 0 = looking for | or -- or }}
-\ 1 = found |
-\ 2 = found --
-hide
-0 constant zero
-
-: ?-- ( c-addr u -- c-addr u flag )
- 2dup s" --" compare 0= ;
-: ?} ( c-addr u -- c-addr u flag )
- 2dup s" }" compare 0= ;
-: ?| ( c-addr u -- c-addr u flag )
- 2dup s" |" compare 0= ;
-
-: ?delim ( c-addr u -- state | c-addr u 0 )
- ?| if
- 2drop 1
- else
- ?-- if
- 2drop 2
- else
- ?} if 2drop 3 else 0 endif
- endif
- endif
-;
-
-set-current
-
-: {
- 0 dup locals| locstate |
-
- \ stack locals until we hit a delimiter
- begin
- parse-word \ ( nLocals c-addr u )
- ?delim dup to locstate
- 0= while
- rot 1+ \ ( c-addr u ... c-addr u nLocals )
- repeat
-
- \ now unstack the locals
- 0 do (local) loop \ ( )
-
- \ zero locals until -- or }
- locstate 1 = if
- begin
- parse-word
- ?delim dup to locstate
- 0= while
- postpone zero (local)
- repeat
- endif
-
- 0 0 (local)
-
- \ toss words until }
- locstate 2 = if
- begin
- parse-word
- ?delim dup to locstate
- 0= while
- 2drop
- repeat
- endif
-
- locstate 3 <> abort" syntax error in { } local line"
-; immediate compile-only
-
-previous
-\ #endif
-
diff --git a/sys/boot/ficl/softwords/marker.fr b/sys/boot/ficl/softwords/marker.fr
deleted file mode 100644
index c80c2cf3f2ce..000000000000
--- a/sys/boot/ficl/softwords/marker.fr
+++ /dev/null
@@ -1,25 +0,0 @@
-\ ** ficl/softwords/marker.fr
-\ ** Ficl implementation of CORE EXT MARKER
-\ John Sadler, 4 Oct 98
-\ Requires ficl 2.02 FORGET-WID !!
-
-: marker ( "name" -- )
- create
- get-current ,
- get-order dup ,
- 0 ?do , loop
- does>
- 0 set-order \ clear search order
- dup body> >name drop
- here - allot \ reset HERE to my xt-addr
- dup @ ( pfa current-wid )
- dup set-current forget-wid ( pfa )
- cell+ dup @ swap ( count count-addr )
- over cells + swap ( last-wid-addr count )
- 0 ?do
- dup @ dup ( wid-addr wid wid )
- >search forget-wid ( wid-addr )
- cell-
- loop
- drop
-;
diff --git a/sys/boot/ficl/softwords/oo.fr b/sys/boot/ficl/softwords/oo.fr
deleted file mode 100644
index cd16c77b28b0..000000000000
--- a/sys/boot/ficl/softwords/oo.fr
+++ /dev/null
@@ -1,464 +0,0 @@
-\ ** ficl/softwords/oo.fr
-\ ** F I C L O - O E X T E N S I O N S
-\ ** john sadler aug 1998
-
-.( loading ficl O-O extensions ) cr
-7 ficl-vocabulary oop
-also oop definitions
-
-\ Design goals:
-\ 0. Traditional OOP: late binding by default for safety.
-\ Early binding if you ask for it.
-\ 1. Single inheritance
-\ 2. Object aggregation (has-a relationship)
-\ 3. Support objects in the dictionary and as proxies for
-\ existing structures (by reference):
-\ *** A ficl object can wrap a C struct ***
-\ 4. Separate name-spaces for methods - methods are
-\ only visible in the context of a class / object
-\ 5. Methods can be overridden, and subclasses can add methods.
-\ No limit on number of methods.
-
-\ General info:
-\ Classes are objects, too: all classes are instances of METACLASS
-\ All classes are derived (by convention) from OBJECT. This
-\ base class provides a default initializer and superclass
-\ access method
-
-\ A ficl object binds instance storage (payload) to a class.
-\ object ( -- instance class )
-\ All objects push their payload address and class address when
-\ executed. All objects have this footprint:
-\ cell 0: first payload cell
-
-\ A ficl class consists of a parent class pointer, a wordlist
-\ ID for the methods of the class, and a size for the payload
-\ of objects created by the class. A class is an object.
-\ The NEW method creates and initializes an instance of a class.
-\ Classes have this footprint:
-\ cell 0: parent class address
-\ cell 1: wordlist ID
-\ cell 2: size of instance's payload
-
-\ Methods expect an object couple ( instance class )
-\ on the stack.
-\ Overridden methods must maintain the same stack signature as
-\ their predecessors. Ficl has no way of enforcing this, though.
-
-user current-class
-0 current-class !
-
-\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
-\ ** L A T E B I N D I N G
-\ Compile the method name, and code to find and
-\ execute it at run-time...
-\ parse-method compiles the method name so that it pushes
-\ the string base address and count at run-time.
-\
-: parse-method \ name run: ( -- c-addr u )
- parse-word
- postpone sliteral
-; compile-only
-
-: lookup-method ( class c-addr u -- class xt )
- 2dup
- local u
- local c-addr
- end-locals
- 2 pick cell+ @ ( -- class c-addr u wid )
- search-wordlist ( -- class 0 | xt 1 | xt -1 )
- 0= if
- c-addr u type ." not found in "
- body> >name type
- cr abort
- endif
-;
-
-: exec-method ( instance class c-addr u -- <method-signature> )
- lookup-method execute
-;
-
-: find-method-xt \ name ( class -- class xt )
- parse-word lookup-method
-;
-
-
-\ Method lookup operator takes a class-addr and instance-addr
-\ and executes the method from the class's wordlist if
-\ interpreting. If compiling, bind late.
-\
-: --> ( instance class -- ??? )
- state @ 0= if
- find-method-xt execute
- else
- parse-method postpone exec-method
- endif
-; immediate
-
-
-\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
-\ ** E A R L Y B I N D I N G
-\ Early binding operator compiles code to execute a method
-\ given its class at compile time. Classes are immediate,
-\ so they leave their cell-pair on the stack when compiling.
-\ Example:
-\ : get-wid metaclass => .wid @ ;
-\ Usage
-\ my-class get-wid ( -- wid-of-my-class )
-\
-: => \ c:( class meta -- ) run: ( -- ??? ) invokes compiled method
- drop find-method-xt compile, drop
-; immediate compile-only
-
-
-\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
-\ ** I N S T A N C E V A R I A B L E S
-\ Instance variables (IV) are represented by words in the class's
-\ private wordlist. Each IV word contains the offset
-\ of the IV it represents, and runs code to add that offset
-\ to the base address of an instance when executed.
-\ The metaclass SUB method, defined below, leaves the address
-\ of the new class's offset field and its initial size on the
-\ stack for these words to update. When a class definition is
-\ complete, END-CLASS saves the final size in the class's size
-\ field, and restores the search order and compile wordlist to
-\ prior state. Note that these words are hidden in their own
-\ wordlist to prevent accidental use outside a SUB END-CLASS pair.
-\
-wordlist
-dup constant instance-vars
-dup >search ficl-set-current
-: do-instance-var
- does> ( instance class addr[offset] -- addr[field] )
- nip @ +
-;
-
-: addr-units: ( offset size "name" -- offset' )
- create over , +
- do-instance-var
-;
-
-: chars: \ ( offset nCells "name" -- offset' ) Create n char member.
- chars addr-units: ;
-
-: char: \ ( offset nCells "name" -- offset' ) Create 1 char member.
- 1 chars: ;
-
-: cells: ( offset nCells "name" -- offset' )
- cells >r aligned r> addr-units:
-;
-
-: cell: ( offset nCells "name" -- offset' )
- 1 cells: ;
-
-\ Aggregate an object into the class...
-\ Needs the class of the instance to create
-\ Example: object obj: m_obj
-\
-: do-aggregate
- does> ( instance class pfa -- a-instance a-class )
- 2@ ( inst class a-class a-offset )
- 2swap drop ( a-class a-offset inst )
- + swap ( a-inst a-class )
-;
-
-: obj: ( offset class meta "name" -- offset' )
- locals| meta class offset |
- create offset , class ,
- class meta --> get-size offset +
- do-aggregate
-;
-
-\ Aggregate an array of objects into a class
-\ Usage example:
-\ 3 my-class array: my-array
-\ Makes an instance variable array of 3 instances of my-class
-\ named my-array.
-\
-: array: ( offset n class meta "name" -- offset' )
- locals| meta class nobjs offset |
- create offset , class ,
- class meta --> get-size nobjs * offset +
- do-aggregate
-;
-
-\ Aggregate a pointer to an object: REF is a member variable
-\ whose class is set at compile time. This is useful for wrapping
-\ data structures in C, where there is only a pointer and the type
-\ it refers to is known. If you want polymorphism, see c_ref
-\ in classes.fr. REF is only useful for pre-initialized structures,
-\ since there's no supported way to set one.
-: ref: ( offset class meta "name" -- offset' )
- locals| meta class offset |
- create offset , class ,
- offset cell+
- does> ( inst class pfa -- ptr-inst ptr-class )
- 2@ ( inst class ptr-class ptr-offset )
- 2swap drop + @ swap
-;
-
-\ END-CLASS terminates construction of a class by storing
-\ the size of its instance variables in the class's size field
-\ ( -- old-wid addr[size] 0 )
-\
-: end-class ( old-wid addr[size] size -- )
- swap ! set-current
- search> drop \ pop struct builder wordlist
-;
-
-set-current previous
-\ E N D I N S T A N C E V A R I A B L E S
-
-
-\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
-\ D O - D O - I N S T A N C E
-\ Makes a class method that contains the code for an
-\ instance of the class. This word gets compiled into
-\ the wordlist of every class by the SUB method.
-\ PRECONDITION: current-class contains the class address
-\
-: do-do-instance ( -- )
- s" : .do-instance does> [ current-class @ ] literal ;"
- evaluate
-;
-
-\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
-\ ** M E T A C L A S S
-\ Every class is an instance of metaclass. This lets
-\ classes have methods that are different from those
-\ of their instances.
-\ Classes are IMMEDIATE to make early binding simpler
-\ See above...
-\
-:noname
- wordlist
- create immediate
- 0 , \ NULL parent class
- dup , \ wid
- 3 cells , \ instance size
- ficl-set-current
- does> dup
-; execute metaclass
-
-metaclass drop current-class !
-do-do-instance
-
-\
-\ C L A S S M E T H O D S
-\
-instance-vars >search
-
-create .super ( class metaclass -- parent-class )
- 0 cells , do-instance-var
-
-create .wid ( class metaclass -- wid ) \ return wid of class
- 1 cells , do-instance-var
-
-create .size ( class metaclass -- size ) \ return class's payload size
- 2 cells , do-instance-var
-
-previous
-
-: get-size metaclass => .size @ ;
-: get-wid metaclass => .wid @ ;
-: get-super metaclass => .super @ ;
-
-\ create an uninitialized instance of a class, leaving
-\ the address of the new instance and its class
-\
-: instance ( class metaclass "name" -- instance class )
- locals| meta parent |
- create
- here parent --> .do-instance \ ( inst class )
- parent meta metaclass => get-size
- allot \ allocate payload space
-;
-
-\ create an uninitialized array
-: array ( n class metaclass "name" -- n instance class )
- locals| meta parent nobj |
- create nobj
- here parent --> .do-instance \ ( nobj inst class )
- parent meta metaclass => get-size
- nobj * allot \ allocate payload space
-;
-
-\ create an initialized instance
-\
-: new \ ( class metaclass "name" -- )
- metaclass => instance --> init
-;
-
-\ create an initialized array of instances
-: new-array ( n class metaclass "name" -- )
- metaclass => array
- --> array-init
-;
-
-\ create a proxy object with initialized payload address given
-: ref ( instance-addr class metaclass "name" -- )
- drop create , ,
- does> 2@
-;
-
-\ create a subclass
-: sub ( class metaclass "name" -- old-wid addr[size] size )
- wordlist
- locals| wid meta parent |
- parent meta metaclass => get-wid
- wid wid-set-super
- create immediate
- here current-class ! \ prep for do-do-instance
- parent , \ save parent class
- wid , \ save wid
- here parent meta --> get-size dup , ( addr[size] size )
- metaclass => .do-instance
- wid ficl-set-current -rot
- do-do-instance
- instance-vars >search \ push struct builder wordlist
-;
-
-\ OFFSET-OF returns the offset of an instance variable
-\ from the instance base address. If the next token is not
-\ the name of in instance variable method, you get garbage
-\ results -- there is no way at present to check for this error.
-: offset-of ( class metaclass "name" -- offset )
- drop find-method-xt nip >body @ ;
-
-\ ID returns the string name cell-pair of its class
-: id ( class metaclass -- c-addr u )
- drop body> >name ;
-
-\ list methods of the class
-: methods \ ( class meta -- )
- locals| meta class |
- begin
- class body> >name type ." methods:" cr
- class meta --> get-wid >search words cr previous
- class meta metaclass => get-super
- dup to class
- 0= until cr
-;
-
-\ list class's ancestors
-: pedigree ( class meta -- )
- locals| meta class |
- begin
- class body> >name type space
- class meta metaclass => get-super
- dup to class
- 0= until cr
-;
-
-\ decompile a method
-: see ( class meta -- )
- metaclass => get-wid >search see previous ;
-
-set-current
-\ E N D M E T A C L A S S
-
-\ META is a nickname for the address of METACLASS...
-metaclass drop
-constant meta
-
-\ SUBCLASS is a nickname for a class's SUB method...
-\ Subclass compilation ends when you invoke end-class
-\ This method is late bound for safety...
-: subclass --> sub ;
-
-
-\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
-\ ** O B J E C T
-\ Root of all classes
-:noname
- wordlist
- create immediate
- 0 , \ NULL parent class
- dup , \ wid
- 0 , \ instance size
- ficl-set-current
- does> meta
-; execute object
-
-object drop current-class !
-do-do-instance
-
-\ O B J E C T M E T H O D S
-\ Convert instance cell-pair to class cell-pair
-\ Useful for binding class methods from an instance
-: class ( instance class -- class metaclass )
- nip meta ;
-
-\ default INIT method zero fills an instance
-: init ( instance class -- )
- meta
- metaclass => get-size ( inst size )
- erase ;
-
-\ Apply INIT to an array of NOBJ objects...
-\
-: array-init ( nobj inst class -- )
- 0 dup locals| &init &next class inst |
- \
- \ bind methods outside the loop to save time
- \
- class s" init" lookup-method to &init
- s" next" lookup-method to &next
- drop
- 0 ?do
- inst class 2dup
- &init execute
- &next execute drop to inst
- loop
-;
-
-\ Instance aliases for common class methods
-\ Upcast to parent class
-: super ( instance class -- instance parent-class )
- meta metaclass => get-super ;
-
-: pedigree ( instance class -- )
- object => class
- metaclass => pedigree ;
-
-: size ( instance class -- sizeof-instance )
- object => class
- metaclass => get-size ;
-
-: methods ( instance class -- )
- object => class
- metaclass => methods ;
-
-\ Array indexing methods...
-\ Usage examples:
-\ 10 object-array --> index
-\ obj --> next
-\
-: index ( n instance class -- instance[n] class )
- locals| class inst |
- inst class
- object => class
- metaclass => get-size * ( n*size )
- inst + class ;
-
-: next ( instance[n] class -- instance[n+1] class )
- locals| class inst |
- inst class
- object => class
- metaclass => get-size
- inst +
- class ;
-
-: prev ( instance[n] class -- instance[n-1] class )
- locals| class inst |
- inst class
- object => class
- metaclass => get-size
- inst swap -
- class ;
-
-set-current
-\ E N D O B J E C T
-
-
-previous definitions
diff --git a/sys/boot/ficl/softwords/softcore.awk b/sys/boot/ficl/softwords/softcore.awk
deleted file mode 100644
index b182b9950897..000000000000
--- a/sys/boot/ficl/softwords/softcore.awk
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/awk -f
-# Convert forth source files to a giant C string
-# Joe Abley <jabley@patho.gen.nz>, 12 January 1999
-
-BEGIN \
-{
- printf "/***************************************************************\n";
- printf "** s o f t c o r e . c\n";
- printf "** Forth Inspired Command Language -\n";
- printf "** Words from CORE set written in FICL\n";
- printf "** Author: John Sadler (john_sadler@alum.mit.edu)\n";
- printf "** Created: 27 December 1997\n";
- printf "** Last update: %s\n", strftime();
- printf "***************************************************************/\n";
- printf "\n/*\n";
- printf "** This file contains definitions that are compiled into the\n";
- printf "** system dictionary by the first virtual machine to be created.\n";
- printf "** Created automagically by ficl/softwords/softcore.awk\n";
- printf "*/\n";
- printf "\n#include \"ficl.h\"\n";
- printf "\nstatic char softWords[] =\n";
-
- commenting = 0;
-}
-
-# some general early substitutions
-{
- gsub("\t", " "); # replace each tab with 4 spaces
- gsub("\"", "\\\""); # escape quotes
- gsub("\\\\[[:space:]]+$", ""); # toss empty comments
-}
-
-# strip out empty lines
-/^ *$/ \
-{
- next;
-}
-
-# emit / ** lines as multi-line C comments
-/^\\[[:space:]]\*\*/ && (commenting == 0) \
-{
- sub("^\\\\[[:space:]]", "");
- printf "/*\n%s\n", $0;
- commenting = 1;
- next;
-}
-
-/^\\[[:space:]]\*\*/ \
-{
- sub("^\\\\[[:space:]]", "");
- printf "%s\n", $0;
- next;
-}
-
-# function to close a comment, used later
-function end_comments()
-{
- commenting = 0;
- printf "*/\n";
-}
-
-# pass commented preprocessor directives
-/^\\[[:space:]]#/ \
-{
- if (commenting) end_comments();
- sub("^\\\\[[:space:]]", "");
- printf "%s\n", $0;
- next;
-}
-
-# toss all other full-line comments
-/^\\/ \
-{
- if (commenting) end_comments();
- next;
-}
-
-# emit all other lines as quoted string fragments
-{
- if (commenting) end_comments();
-
- sub("\\\\[[:space:]]+.*$", ""); # lop off trailing \ comments
- sub("[[:space:]]+$", ""); # remove trailing spaces
- printf " \"%s \\n\"\n", $0;
- next;
-}
-
-END \
-{
- if (commenting) end_comments();
- printf " \"quit \";\n";
- printf "\n\nvoid ficlCompileSoftCore(FICL_VM *pVM)\n";
- printf "{\n";
- printf " assert(ficlExec(pVM, softWords) != VM_ERREXIT);\n";
- printf "}\n";
-}
diff --git a/sys/boot/ficl/softwords/softcore.fr b/sys/boot/ficl/softwords/softcore.fr
deleted file mode 100644
index bcc2696b6efd..000000000000
--- a/sys/boot/ficl/softwords/softcore.fr
+++ /dev/null
@@ -1,125 +0,0 @@
-\ ** ficl/softwords/softcore.fr
-\ ** FICL soft extensions
-\ ** John Sadler (john_sadler@alum.mit.edu)
-\ ** September, 1998
-
-\ ** Ficl USER variables
-\ ** See words.c for primitive def'n of USER
-\ #if FICL_WANT_USER
-
-variable nUser 0 nUser !
-: user \ name ( -- )
- nUser dup @ user 1 swap +! ;
-
-\ #endif
-
-\ ** ficl extras
-\ EMPTY cleans the parameter stack
-: empty ( xn..x1 -- ) depth 0 ?do drop loop ;
-\ CELL- undoes CELL+
-: cell- ( addr -- addr ) [ 1 cells ] literal - ;
-: -rot ( a b c -- c a b ) 2 -roll ;
-
-\ ** CORE
-: abs ( x -- x )
- dup 0< if negate endif ;
-decimal 32 constant bl
-
-: space ( -- ) bl emit ;
-
-: spaces ( n -- ) 0 ?do space loop ;
-
-: abort"
- postpone if
- postpone ."
- postpone cr
- postpone abort
- postpone endif
-; immediate
-
-
-\ ** CORE EXT
-0 constant false
--1 constant true
-: <> = invert ;
-: 0<> 0= invert ;
-: compile, , ;
-: erase ( addr u -- ) 0 fill ;
-: nip ( y x -- x ) swap drop ;
-: tuck ( y x -- x y x) swap over ;
-
-\ ** LOCAL EXT word set
-\ #if FICL_WANT_LOCALS
-: locals| ( name...name | -- )
- begin
- bl word count
- dup 0= abort" where's the delimiter??"
- over c@
- [char] | - over 1- or
- while
- (local)
- repeat 2drop 0 0 (local)
-; immediate
-
-: local ( name -- ) bl word count (local) ; immediate
-
-: end-locals ( -- ) 0 0 (local) ; immediate
-
-\ #endif
-
-\ ** TOOLS word set...
-: ? ( addr -- ) @ . ;
-: dump ( addr u -- )
- 0 ?do
- dup c@ . 1+
- i 7 and 7 = if cr endif
- loop drop
-;
-
-\ ** SEARCH+EXT words and ficl helpers
-\
-: wordlist ( -- )
- 1 ficl-wordlist ;
-
-\ DO_VOCABULARY handles the DOES> part of a VOCABULARY
-\ When executed, new voc replaces top of search stack
-: do-vocabulary ( -- )
- does> @ search> drop >search ;
-
-: vocabulary ( name -- )
- wordlist create , do-vocabulary ;
-
-: ficl-vocabulary ( nBuckets name -- )
- ficl-wordlist create , do-vocabulary ;
-
-\ ALSO dups the search stack...
-: also ( -- )
- search> dup >search >search ;
-
-\ FORTH drops the top of the search stack and pushes FORTH-WORDLIST
-: forth ( -- )
- search> drop
- forth-wordlist >search ;
-
-\ ONLY sets the search order to a default state
-: only ( -- )
- -1 set-order ;
-
-\ ORDER displays the compile wid and the search order list
-: order ( -- )
- ." Search: "
- get-order 0 ?do x. loop cr
- ." Compile: " get-current x. cr ;
-
-\ PREVIOUS drops the search order stack
-: previous ( -- ) search> drop ;
-
-\ FICL-SET-CURRENT sets the compile wordlist and pushes the previous value
-: ficl-set-current ( wid -- old-wid )
- get-current swap set-current ;
-
-wordlist constant hidden
-: hide hidden dup >search ficl-set-current ;
-
-\ ** E N D S O F T C O R E . F R
-
diff --git a/sys/boot/ficl/stack.c b/sys/boot/ficl/stack.c
deleted file mode 100644
index aee9f8f5ff56..000000000000
--- a/sys/boot/ficl/stack.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/*******************************************************************
-** s t a c k . c
-** Forth Inspired Command Language
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 16 Oct 1997
-**
-*******************************************************************/
-
-#ifdef TESTMAIN
-#include <stdlib.h>
-#else
-#include <stand.h>
-#endif
-#include "ficl.h"
-
-#define STKDEPTH(s) ((s)->sp - (s)->base)
-
-/*
-** N O T E: Stack convention:
-**
-** sp points to the first available cell
-** push: store value at sp, increment sp
-** pop: decrement sp, fetch value at sp
-** Stack grows from low to high memory
-*/
-
-/*******************************************************************
- v m C h e c k S t a c k
-** Check the parameter stack for underflow or overflow.
-** nCells controls the type of check: if nCells is zero,
-** the function checks the stack state for underflow and overflow.
-** If nCells > 0, checks to see that the stack has room to push
-** that many cells. If less than zero, checks to see that the
-** stack has room to pop that many cells. If any test fails,
-** the function throws (via vmThrow) a VM_ERREXIT exception.
-*******************************************************************/
-void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells)
-{
- FICL_STACK *pStack = pVM->pStack;
- int nFree = pStack->base + pStack->nCells - pStack->sp;
-
- if (popCells > STKDEPTH(pStack))
- {
- vmThrowErr(pVM, "Error: stack underflow");
- }
-
- if (nFree < pushCells - popCells)
- {
- vmThrowErr(pVM, "Error: stack overflow");
- }
-
- return;
-}
-
-/*******************************************************************
- s t a c k C r e a t e
-**
-*******************************************************************/
-
-FICL_STACK *stackCreate(unsigned nCells)
-{
- size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL);
- FICL_STACK *pStack = ficlMalloc(size);
-
-#if FICL_ROBUST
- assert (nCells != 0);
- assert (pStack != NULL);
-#endif
-
- pStack->nCells = nCells;
- pStack->sp = pStack->base;
- pStack->pFrame = NULL;
- return pStack;
-}
-
-
-/*******************************************************************
- s t a c k D e l e t e
-**
-*******************************************************************/
-
-void stackDelete(FICL_STACK *pStack)
-{
- if (pStack)
- ficlFree(pStack);
- return;
-}
-
-
-/*******************************************************************
- s t a c k D e p t h
-**
-*******************************************************************/
-
-int stackDepth(FICL_STACK *pStack)
-{
- return STKDEPTH(pStack);
-}
-
-/*******************************************************************
- s t a c k D r o p
-**
-*******************************************************************/
-
-void stackDrop(FICL_STACK *pStack, int n)
-{
-#if FICL_ROBUST
- assert(n > 0);
-#endif
- pStack->sp -= n;
- return;
-}
-
-
-/*******************************************************************
- s t a c k F e t c h
-**
-*******************************************************************/
-
-CELL stackFetch(FICL_STACK *pStack, int n)
-{
- return pStack->sp[-n-1];
-}
-
-void stackStore(FICL_STACK *pStack, int n, CELL c)
-{
- pStack->sp[-n-1] = c;
- return;
-}
-
-
-/*******************************************************************
- s t a c k G e t T o p
-**
-*******************************************************************/
-
-CELL stackGetTop(FICL_STACK *pStack)
-{
- return pStack->sp[-1];
-}
-
-
-/*******************************************************************
- s t a c k L i n k
-** Link a frame using the stack's frame pointer. Allot space for
-** nCells cells in the frame
-** 1) Push pFrame
-** 2) pFrame = sp
-** 3) sp += nCells
-*******************************************************************/
-
-void stackLink(FICL_STACK *pStack, int nCells)
-{
- stackPushPtr(pStack, pStack->pFrame);
- pStack->pFrame = pStack->sp;
- pStack->sp += nCells;
- return;
-}
-
-
-/*******************************************************************
- s t a c k U n l i n k
-** Unink a stack frame previously created by stackLink
-** 1) sp = pFrame
-** 2) pFrame = pop()
-*******************************************************************/
-
-void stackUnlink(FICL_STACK *pStack)
-{
- pStack->sp = pStack->pFrame;
- pStack->pFrame = stackPopPtr(pStack);
- return;
-}
-
-
-/*******************************************************************
- s t a c k P i c k
-**
-*******************************************************************/
-
-void stackPick(FICL_STACK *pStack, int n)
-{
- stackPush(pStack, stackFetch(pStack, n));
- return;
-}
-
-
-/*******************************************************************
- s t a c k P o p
-**
-*******************************************************************/
-
-CELL stackPop(FICL_STACK *pStack)
-{
- return *--pStack->sp;
-}
-
-void *stackPopPtr(FICL_STACK *pStack)
-{
- return (*--pStack->sp).p;
-}
-
-UNS32 stackPopUNS32(FICL_STACK *pStack)
-{
- return (*--pStack->sp).u;
-}
-
-INT32 stackPopINT32(FICL_STACK *pStack)
-{
- return (*--pStack->sp).i;
-}
-
-
-/*******************************************************************
- s t a c k P u s h
-**
-*******************************************************************/
-
-void stackPush(FICL_STACK *pStack, CELL c)
-{
- *pStack->sp++ = c;
-}
-
-void stackPushPtr(FICL_STACK *pStack, void *ptr)
-{
- *pStack->sp++ = LVALUEtoCELL(ptr);
-}
-
-void stackPushUNS32(FICL_STACK *pStack, UNS32 u)
-{
- *pStack->sp++ = LVALUEtoCELL(u);
-}
-
-void stackPushINT32(FICL_STACK *pStack, INT32 i)
-{
- *pStack->sp++ = LVALUEtoCELL(i);
-}
-
-/*******************************************************************
- s t a c k R e s e t
-**
-*******************************************************************/
-
-void stackReset(FICL_STACK *pStack)
-{
- pStack->sp = pStack->base;
- return;
-}
-
-
-/*******************************************************************
- s t a c k R o l l
-** Roll nth stack entry to the top (counting from zero), if n is
-** >= 0. Drop other entries as needed to fill the hole.
-** If n < 0, roll top-of-stack to nth entry, pushing others
-** upward as needed to fill the hole.
-*******************************************************************/
-
-void stackRoll(FICL_STACK *pStack, int n)
-{
- CELL c;
- CELL *pCell;
-
- if (n == 0)
- return;
- else if (n > 0)
- {
- pCell = pStack->sp - n - 1;
- c = *pCell;
-
- for (;n > 0; --n, pCell++)
- {
- *pCell = pCell[1];
- }
-
- *pCell = c;
- }
- else
- {
- pCell = pStack->sp - 1;
- c = *pCell;
-
- for (; n < 0; ++n, pCell--)
- {
- *pCell = pCell[-1];
- }
-
- *pCell = c;
- }
- return;
-}
-
-
-/*******************************************************************
- s t a c k S e t T o p
-**
-*******************************************************************/
-
-void stackSetTop(FICL_STACK *pStack, CELL c)
-{
- pStack->sp[-1] = c;
- return;
-}
-
-
diff --git a/sys/boot/ficl/sysdep.c b/sys/boot/ficl/sysdep.c
deleted file mode 100644
index 84a704dabdd8..000000000000
--- a/sys/boot/ficl/sysdep.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*******************************************************************
-** s y s d e p . c
-** Forth Inspired Command Language
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 16 Oct 1997
-** Implementations of FICL external interface functions...
-**
-*******************************************************************/
-
-#ifdef TESTMAIN
-#include <stdio.h>
-#include <stdlib.h>
-#else
-#include <stand.h>
-#ifdef __i386__
-#include <machine/cpufunc.h>
-#endif
-#endif
-#include "ficl.h"
-
-/*
-******************* FreeBSD P O R T B E G I N S H E R E ******************** Michael Smith
-*/
-
-UNS64 ficlLongMul(UNS32 x, UNS32 y)
-{
- UNS64 q;
- u_int64_t qx;
-
- qx = (u_int64_t)x * (u_int64_t) y;
-
- q.hi = (u_int32_t)( qx >> 32 );
- q.lo = (u_int32_t)( qx & 0xFFFFFFFFL);
-
- return q;
-}
-
-UNSQR ficlLongDiv(UNS64 q, UNS32 y)
-{
- UNSQR result;
- u_int64_t qx, qh;
-
- qh = q.hi;
- qx = (qh << 32) | q.lo;
-
- result.quot = qx / y;
- result.rem = qx % y;
-
- return result;
-}
-
-void ficlTextOut(FICL_VM *pVM, char *msg, int fNewline)
-{
- IGNORE(pVM);
-
- while(*msg != 0)
- putchar(*(msg++));
- if (fNewline)
- putchar('\n');
-
- return;
-}
-
-void *ficlMalloc (size_t size)
-{
- return malloc(size);
-}
-
-void ficlFree (void *p)
-{
- free(p);
-}
-
-#ifdef __i386__
-/*
- * outb ( port# c -- )
- * Store a byte to I/O port number port#
- */
-void
-ficlOutb(FICL_VM *pVM)
-{
- u_char c;
- u_int32_t port;
-
- port=stackPopUNS32(pVM->pStack);
- c=(u_char)stackPopINT32(pVM->pStack);
- outb(port,c);
-}
-
-/*
- * inb ( port# -- c )
- * Fetch a byte from I/O port number port#
- */
-void
-ficlInb(FICL_VM *pVM)
-{
- u_char c;
- u_int32_t port;
-
- port=stackPopUNS32(pVM->pStack);
- c=inb(port);
- stackPushINT32(pVM->pStack,c);
-}
-#endif
-
-/*
-** Stub function for dictionary access control - does nothing
-** by default, user can redefine to guarantee exclusive dict
-** access to a single thread for updates. All dict update code
-** is guaranteed to be bracketed as follows:
-** ficlLockDictionary(TRUE);
-** <code that updates dictionary>
-** ficlLockDictionary(FALSE);
-**
-** Returns zero if successful, nonzero if unable to acquire lock
-** befor timeout (optional - could also block forever)
-*/
-#if FICL_MULTITHREAD
-int ficlLockDictionary(short fLock)
-{
- IGNORE(fLock);
- return 0;
-}
-#endif /* FICL_MULTITHREAD */
-
-
diff --git a/sys/boot/ficl/sysdep.h b/sys/boot/ficl/sysdep.h
deleted file mode 100644
index 4095701cad2a..000000000000
--- a/sys/boot/ficl/sysdep.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*******************************************************************
- s y s d e p . h
-** Forth Inspired Command Language
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 16 Oct 1997
-** Ficl system dependent types and prototypes...
-**
-** Note: Ficl also depends on the use of "assert" when
-** FICL_ROBUST is enabled. This may require some consideration
-** in firmware systems since assert often
-** assumes stderr/stdout.
-**
-*******************************************************************/
-/*
-** N O T I C E -- DISCLAIMER OF WARRANTY
-**
-** Ficl is freeware. Use it in any way that you like, with
-** the understanding that the code is not supported.
-**
-** Any third party may reproduce, distribute, or modify the ficl
-** software code or any derivative works thereof without any
-** compensation or license, provided that the author information
-** and this disclaimer text are retained in the source code files.
-** The ficl software code is provided on an "as is" basis without
-** warranty of any kind, including, without limitation, the implied
-** warranties of merchantability and fitness for a particular purpose
-** and their equivalents under the laws of any jurisdiction.
-**
-** I am interested in hearing from anyone who uses ficl. If you have
-** a problem, a success story, a defect, an enhancement request, or
-** if you would like to contribute to the ficl release (yay!), please
-** send me email at the address above.
-*/
-
-#if !defined (__SYSDEP_H__)
-#define __SYSDEP_H__
-
-#include <sys/types.h>
-
-#include <stddef.h> /* size_t, NULL */
-#include <setjmp.h>
-
-#include <assert.h>
-
-#if !defined IGNORE /* Macro to silence unused param warnings */
-#define IGNORE(x) &x
-#endif
-
-
-/*
-** TRUE and FALSE for C boolean operations, and
-** portable 32 bit types for CELLs
-**
-*/
-#if !defined TRUE
-#define TRUE 1
-#endif
-#if !defined FALSE
-#define FALSE 0
-#endif
-
-
-#if !defined INT32
-#define INT32 int32_t
-#endif
-
-#if !defined UNS32
-#define UNS32 u_int32_t
-#endif
-
-#if !defined UNS16
-#define UNS16 u_int16_t
-#endif
-
-#if !defined UNS8
-#define UNS8 u_int8_t
-#endif
-
-#if !defined NULL
-#define NULL ((void *)0)
-#endif
-
-typedef struct
-{
- UNS32 hi;
- UNS32 lo;
-} UNS64;
-
-typedef struct
-{
- UNS32 quot;
- UNS32 rem;
-} UNSQR;
-
-typedef struct
-{
- INT32 hi;
- INT32 lo;
-} INT64;
-
-typedef struct
-{
- INT32 quot;
- INT32 rem;
-} INTQR;
-
-
-/*
-** Build controls
-** FICL_MULTITHREAD enables dictionary mutual exclusion
-** wia the ficlLockDictionary system dependent function.
-*/
-#if !defined FICL_MULTITHREAD
-#define FICL_MULTITHREAD 0
-#endif
-
-/*
-** FICL_ROBUST enables bounds checking of stacks and the dictionary.
-** This will detect stack over and underflows and dictionary overflows.
-** Any exceptional condition will result in an assertion failure.
-** (As generated by the ANSI assert macro)
-** FICL_ROBUST == 1 --> stack checking in the outer interpreter
-** FICL_ROBUST == 2 also enables checking in many primitives
-*/
-
-#if !defined FICL_ROBUST
-#define FICL_ROBUST 2
-#endif
-
-/*
-** FICL_DEFAULT_STACK Specifies the default size (in CELLs) of
-** a new virtual machine's stacks, unless overridden at
-** create time.
-*/
-#if !defined FICL_DEFAULT_STACK
-#define FICL_DEFAULT_STACK 128
-#endif
-
-/*
-** FICL_DEFAULT_DICT specifies the number of CELLs to allocate
-** for the system dictionary by default. The value
-** can be overridden at startup time as well.
-** FICL_DEFAULT_ENV specifies the number of cells to allot
-** for the environment-query dictionary.
-*/
-#if !defined FICL_DEFAULT_DICT
-#define FICL_DEFAULT_DICT 12288
-#endif
-
-#if !defined FICL_DEFAULT_ENV
-#define FICL_DEFAULT_ENV 260
-#endif
-
-/*
-** FICL_DEFAULT_VOCS specifies the maximum number of wordlists in
-** the dictionary search order. See Forth DPANS sec 16.3.3
-** (file://dpans16.htm#16.3.3)
-*/
-#if !defined FICL_DEFAULT_VOCS
-#define FICL_DEFAULT_VOCS 16
-#endif
-
-/*
-** User variables: per-instance variables bound to the VM.
-** Kinda like thread-local storage. Could be implemented in a
-** VM private dictionary, but I've chosen the lower overhead
-** approach of an array of CELLs instead.
-*/
-#if !defined FICL_WANT_USER
-#define FICL_WANT_USER 1
-#endif
-
-#if !defined FICL_USER_CELLS
-#define FICL_USER_CELLS 16
-#endif
-
-/*
-** FICL_WANT_LOCALS controls the creation of the LOCALS wordset and
-** a private dictionary for local variable compilation.
-*/
-#if !defined FICL_WANT_LOCALS
-#define FICL_WANT_LOCALS 1
-#endif
-
-/* Max number of local variables per definition */
-#if !defined FICL_MAX_LOCALS
-#define FICL_MAX_LOCALS 16
-#endif
-
-/*
-** FICL_ALIGN is the power of two to which the dictionary
-** pointer address must be aligned. This value is usually
-** either 1 or 2, depending on the memory architecture
-** of the target system; 2 is safe on any 16 or 32 bit
-** machine.
-*/
-#if !defined FICL_ALIGN
-#define FICL_ALIGN 2
-#define FICL_ALIGN_ADD ((1 << FICL_ALIGN) - 1)
-#endif
-
-/*
-** System dependent routines --
-** edit the implementations in sysdep.c to be compatible
-** with your runtime environment...
-** ficlTextOut sends a NULL terminated string to the
-** default output device - used for system error messages
-** ficlMalloc and ficlFree have the same semantics as malloc and free
-** in standard C
-** ficlLongMul multiplies two UNS32s and returns a 64 bit unsigned
-** product
-** ficlLongDiv divides an UNS64 by an UNS32 and returns UNS32 quotient
-** and remainder
-*/
-struct vm;
-void ficlTextOut(struct vm *pVM, char *msg, int fNewline);
-void *ficlMalloc (size_t size);
-void ficlFree (void *p);
-
-/*
-** Stub function for dictionary access control - does nothing
-** by default, user can redefine to guarantee exclusive dict
-** access to a single thread for updates. All dict update code
-** must be bracketed as follows:
-** ficlLockDictionary(TRUE);
-** <code that updates dictionary>
-** ficlLockDictionary(FALSE);
-**
-** Returns zero if successful, nonzero if unable to acquire lock
-** before timeout (optional - could also block forever)
-**
-** NOTE: this function must be implemented with lock counting
-** semantics: nested calls must behave properly.
-*/
-#if FICL_MULTITHREAD
-int ficlLockDictionary(short fLock);
-#else
-#define ficlLockDictionary(x) 0 /* ignore */
-#endif
-
-/*
-** 64 bit integer math support routines: multiply two UNS32s
-** to get a 64 bit prodict, & divide the product by an UNS32
-** to get an UNS32 quotient and remainder. Much easier in asm
-** on a 32 bit CPU than in C, which usually doesn't support
-** the double length result (but it should).
-*/
-UNS64 ficlLongMul(UNS32 x, UNS32 y);
-UNSQR ficlLongDiv(UNS64 q, UNS32 y);
-
-#endif /*__SYSDEP_H__*/
diff --git a/sys/boot/ficl/testmain.c b/sys/boot/ficl/testmain.c
deleted file mode 100644
index f7cdc4440a83..000000000000
--- a/sys/boot/ficl/testmain.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-** stub main for testing FICL
-**
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "ficl.h"
-
-/*
-** Ficl interface to getcwd
-** Prints the current working directory using the VM's
-** textOut method...
-*/
-static void ficlGetCWD(FICL_VM *pVM)
-{
- char *cp;
-
- cp = getcwd(NULL, 80);
- vmTextOut(pVM, cp, 1);
- free(cp);
- return;
-}
-
-/*
-** Ficl interface to chdir
-** Gets a newline (or NULL) delimited string from the input
-** and feeds it to chdir()
-** Example:
-** cd c:\tmp
-*/
-static void ficlChDir(FICL_VM *pVM)
-{
- FICL_STRING *pFS = (FICL_STRING *)pVM->pad;
- vmGetString(pVM, pFS, '\n');
- if (pFS->count > 0)
- {
- int err = chdir(pFS->text);
- if (err)
- {
- vmTextOut(pVM, "Error: path not found", 1);
- vmThrow(pVM, VM_QUIT);
- }
- }
- else
- {
- vmTextOut(pVM, "Warning (chdir): nothing happened", 1);
- }
- return;
-}
-
-/*
-** Ficl interface to system (ANSI)
-** Gets a newline (or NULL) delimited string from the input
-** and feeds it to system()
-** Example:
-** system del *.*
-** \ ouch!
-*/
-static void ficlSystem(FICL_VM *pVM)
-{
- FICL_STRING *pFS = (FICL_STRING *)pVM->pad;
-
- vmGetString(pVM, pFS, '\n');
- if (pFS->count > 0)
- {
- int err = system(pFS->text);
- if (err)
- {
- sprintf(pVM->pad, "System call returned %d", err);
- vmTextOut(pVM, pVM->pad, 1);
- vmThrow(pVM, VM_QUIT);
- }
- }
- else
- {
- vmTextOut(pVM, "Warning (system): nothing happened", 1);
- }
- return;
-}
-
-/*
-** Ficl add-in to load a text file and execute it...
-** Cheesy, but illustrative.
-** Line oriented... filename is newline (or NULL) delimited.
-** Example:
-** load test.ficl
-*/
-#define nLINEBUF 256
-static void ficlLoad(FICL_VM *pVM)
-{
- char cp[nLINEBUF];
- char filename[nLINEBUF];
- FICL_STRING *pFilename = (FICL_STRING *)filename;
- int nLine = 0;
- FILE *fp;
- int result;
- CELL id;
- struct stat buf;
-
-
- vmGetString(pVM, pFilename, '\n');
-
- if (pFilename->count <= 0)
- {
- vmTextOut(pVM, "Warning (load): nothing happened", 1);
- return;
- }
-
- /*
- ** get the file's size and make sure it exists
- */
- result = stat( pFilename->text, &buf );
-
- if (result != 0)
- {
- vmTextOut(pVM, "Unable to stat file: ", 0);
- vmTextOut(pVM, pFilename->text, 1);
- vmThrow(pVM, VM_QUIT);
- }
-
- fp = fopen(pFilename->text, "r");
- if (!fp)
- {
- vmTextOut(pVM, "Unable to open file ", 0);
- vmTextOut(pVM, pFilename->text, 1);
- vmThrow(pVM, VM_QUIT);
- }
-
- id = pVM->sourceID;
- pVM->sourceID.p = (void *)fp;
-
- /* feed each line to ficlExec */
- while (fgets(cp, nLINEBUF, fp))
- {
- int len = strlen(cp) - 1;
-
- nLine++;
- if (len <= 0)
- continue;
-
- if (cp[len] == '\n')
- cp[len] = '\0';
-
- result = ficlExec(pVM, cp);
- if (result >= VM_ERREXIT)
- {
- pVM->sourceID = id;
- fclose(fp);
- vmThrowErr(pVM, "Error loading file <%s> line %d", pFilename->text, nLine);
- break;
- }
- }
- /*
- ** Pass an empty line with SOURCE-ID == 0 to flush
- ** any pending REFILLs (as required by FILE wordset)
- */
- pVM->sourceID.i = -1;
- ficlExec(pVM, "");
-
- pVM->sourceID = id;
- fclose(fp);
-
- return;
-}
-
-/*
-** Dump a tab delimited file that summarizes the contents of the
-** dictionary hash table by hashcode...
-*/
-static void spewHash(FICL_VM *pVM)
-{
- FICL_HASH *pHash = ficlGetDict()->pForthWords;
- FICL_WORD *pFW;
- FILE *pOut;
- unsigned i;
- unsigned nHash = pHash->size;
-
- if (!vmGetWordToPad(pVM))
- vmThrow(pVM, VM_OUTOFTEXT);
-
- pOut = fopen(pVM->pad, "w");
- if (!pOut)
- {
- vmTextOut(pVM, "unable to open file", 1);
- return;
- }
-
- for (i=0; i < nHash; i++)
- {
- int n = 0;
-
- pFW = pHash->table[i];
- while (pFW)
- {
- n++;
- pFW = pFW->link;
- }
-
- fprintf(pOut, "%d\t%d", i, n);
-
- pFW = pHash->table[i];
- while (pFW)
- {
- fprintf(pOut, "\t%s", pFW->name);
- pFW = pFW->link;
- }
-
- fprintf(pOut, "\n");
- }
-
- fclose(pOut);
- return;
-}
-
-static void ficlBreak(FICL_VM *pVM)
-{
- pVM->state = pVM->state;
- return;
-}
-
-void buildTestInterface(void)
-{
- ficlBuild("break", ficlBreak, FW_DEFAULT);
- ficlBuild("cd", ficlChDir, FW_DEFAULT);
- ficlBuild("load", ficlLoad, FW_DEFAULT);
- ficlBuild("pwd", ficlGetCWD, FW_DEFAULT);
- ficlBuild("system", ficlSystem, FW_DEFAULT);
- ficlBuild("spewhash", spewHash, FW_DEFAULT);
-
- return;
-}
-
-
-int main(int argc, char **argv)
-{
- char in[256];
- FICL_VM *pVM;
-
- ficlInitSystem(10000);
- buildTestInterface();
- pVM = ficlNewVM();
-
- ficlExec(pVM, ".ver .( " __DATE__ " ) cr quit");
-
- /*
- ** load file from cmd line...
- */
- if (argc > 1)
- {
- sprintf(in, ".( loading %s ) cr load %s\n cr", argv[1], argv[1]);
- ficlExec(pVM, in);
- }
-
- for (;;)
- {
- int ret;
- if (fgets(in, sizeof(in) - 1, stdin) == NULL)
- break;
- ret = ficlExec(pVM, in);
- if (ret == VM_USEREXIT)
- {
- ficlTermSystem();
- break;
- }
- }
-
- return 0;
-}
-
diff --git a/sys/boot/ficl/vm.c b/sys/boot/ficl/vm.c
deleted file mode 100644
index 6852c62bd663..000000000000
--- a/sys/boot/ficl/vm.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*******************************************************************
-** v m . c
-** Forth Inspired Command Language - virtual machine methods
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 19 July 1997
-**
-*******************************************************************/
-/*
-** This file implements the virtual machine of FICL. Each virtual
-** machine retains the state of an interpreter. A virtual machine
-** owns a pair of stacks for parameters and return addresses, as
-** well as a pile of state variables and the two dedicated registers
-** of the interp.
-*/
-
-#ifdef TESTMAIN
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#else
-#include <stand.h>
-#endif
-#include <stdarg.h>
-#include <string.h>
-#include "ficl.h"
-
-static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-
-/**************************************************************************
- v m B r a n c h R e l a t i v e
-**
-**************************************************************************/
-void vmBranchRelative(FICL_VM *pVM, int offset)
-{
- pVM->ip += offset;
- return;
-}
-
-
-/**************************************************************************
- v m C r e a t e
-**
-**************************************************************************/
-FICL_VM *vmCreate(FICL_VM *pVM, unsigned nPStack, unsigned nRStack)
-{
- if (pVM == NULL)
- {
- pVM = (FICL_VM *)ficlMalloc(sizeof (FICL_VM));
- pVM->pStack = NULL;
- pVM->rStack = NULL;
- pVM->link = NULL;
- }
- assert (pVM);
-
- if (pVM->pStack)
- stackDelete(pVM->pStack);
- pVM->pStack = stackCreate(nPStack);
-
- if (pVM->rStack)
- stackDelete(pVM->rStack);
- pVM->rStack = stackCreate(nRStack);
-
- pVM->textOut = ficlTextOut;
-
- vmReset(pVM);
- return pVM;
-}
-
-
-/**************************************************************************
- v m D e l e t e
-**
-**************************************************************************/
-void vmDelete (FICL_VM *pVM)
-{
- if (pVM)
- {
- ficlFree(pVM->pStack);
- ficlFree(pVM->rStack);
- ficlFree(pVM);
- }
-
- return;
-}
-
-
-/**************************************************************************
- v m E x e c u t e
-**
-**************************************************************************/
-void vmExecute(FICL_VM *pVM, FICL_WORD *pWord)
-{
- pVM->runningWord = pWord;
- pWord->code(pVM);
- return;
-}
-
-
-/**************************************************************************
- v m G e t S t r i n g
-** Parses a string out of the VM input buffer and copies up to the first
-** FICL_STRING_MAX characters to the supplied destination buffer, a
-** FICL_STRING. The destination string is NULL terminated.
-**
-** Returns the address of the first unused character in the dest buffer.
-**************************************************************************/
-char *vmGetString(FICL_VM *pVM, FICL_STRING *spDest, char delimiter)
-{
- STRINGINFO si = vmParseString(pVM, delimiter);
-
- if (SI_COUNT(si) > FICL_STRING_MAX)
- {
- SI_SETLEN(si, FICL_STRING_MAX);
- }
-
- strncpy(spDest->text, SI_PTR(si), SI_COUNT(si));
- spDest->text[SI_COUNT(si)] = '\0';
- spDest->count = (FICL_COUNT)SI_COUNT(si);
-
- return spDest->text + SI_COUNT(si) + 1;
-}
-
-
-/**************************************************************************
- v m G e t W o r d
-** vmGetWord calls vmGetWord0 repeatedly until it gets a string with
-** non-zero length.
-**************************************************************************/
-STRINGINFO vmGetWord(FICL_VM *pVM)
-{
- STRINGINFO si = vmGetWord0(pVM);
-
- if (SI_COUNT(si) == 0)
- {
- vmThrow(pVM, VM_RESTART);
- }
-
- return si;
-}
-
-
-/**************************************************************************
- v m G e t W o r d 0
-** Skip leading whitespace and parse a space delimited word from the tib.
-** Returns the start address and length of the word. Updates the tib
-** to reflect characters consumed, including the trailing delimiter.
-** If there's nothing of interest in the tib, returns zero. This function
-** does not use vmParseString because it uses isspace() rather than a
-** single delimiter character.
-**************************************************************************/
-STRINGINFO vmGetWord0(FICL_VM *pVM)
-{
- char *pSrc = vmGetInBuf(pVM);
- STRINGINFO si;
- UNS32 count = 0;
- char ch;
-
- pSrc = skipSpace(pSrc);
- SI_SETPTR(si, pSrc);
-
- for (ch = *pSrc; ch != '\0' && !isspace(ch); ch = *++pSrc)
- {
- count++;
- }
-
- SI_SETLEN(si, count);
-
- if (isspace(ch)) /* skip one trailing delimiter */
- pSrc++;
-
- vmUpdateTib(pVM, pSrc);
-
- return si;
-}
-
-
-/**************************************************************************
- v m G e t W o r d T o P a d
-** Does vmGetWord0 and copies the result to the pad as a NULL terminated
-** string. Returns the length of the string. If the string is too long
-** to fit in the pad, it is truncated.
-**************************************************************************/
-int vmGetWordToPad(FICL_VM *pVM)
-{
- STRINGINFO si;
- char *cp = (char *)pVM->pad;
- si = vmGetWord0(pVM);
-
- if (SI_COUNT(si) > nPAD)
- SI_SETLEN(si, nPAD);
-
- strncpy(cp, SI_PTR(si), SI_COUNT(si));
- cp[SI_COUNT(si)] = '\0';
- return (int)(SI_COUNT(si));
-}
-
-
-/**************************************************************************
- v m P a r s e S t r i n g
-** Parses a string out of the input buffer using the delimiter
-** specified. Skips leading delimiters, marks the start of the string,
-** and counts characters to the next delimiter it encounters. It then
-** updates the vm input buffer to consume all these chars, including the
-** trailing delimiter.
-** Returns the address and length of the parsed string, not including the
-** trailing delimiter.
-**************************************************************************/
-STRINGINFO vmParseString(FICL_VM *pVM, char delim)
-{
- STRINGINFO si;
- char *pSrc = vmGetInBuf(pVM);
- char ch;
-
- while (*pSrc == delim) /* skip lead delimiters */
- pSrc++;
-
- SI_SETPTR(si, pSrc); /* mark start of text */
-
- for (ch = *pSrc; (ch != delim)
- && (ch != '\0')
- && (ch != '\r')
- && (ch != '\n'); ch = *++pSrc)
- {
- ; /* find next delimiter or end of line */
- }
-
- /* set length of result */
- SI_SETLEN(si, pSrc - SI_PTR(si));
-
- if (*pSrc == delim) /* gobble trailing delimiter */
- pSrc++;
-
- vmUpdateTib(pVM, pSrc);
- return si;
-}
-
-
-/**************************************************************************
- v m P o p I P
-**
-**************************************************************************/
-void vmPopIP(FICL_VM *pVM)
-{
- pVM->ip = (IPTYPE)(stackPopPtr(pVM->rStack));
- return;
-}
-
-
-/**************************************************************************
- v m P u s h I P
-**
-**************************************************************************/
-void vmPushIP(FICL_VM *pVM, IPTYPE newIP)
-{
- stackPushPtr(pVM->rStack, (void *)pVM->ip);
- pVM->ip = newIP;
- return;
-}
-
-
-/**************************************************************************
- v m P u s h T i b
-** Binds the specified input string to the VM and clears >IN (the index)
-**************************************************************************/
-void vmPushTib(FICL_VM *pVM, char *text, TIB *pSaveTib)
-{
- if (pSaveTib)
- {
- *pSaveTib = pVM->tib;
- }
-
- pVM->tib.cp = text;
- pVM->tib.index = 0;
-}
-
-
-void vmPopTib(FICL_VM *pVM, TIB *pTib)
-{
- if (pTib)
- {
- pVM->tib = *pTib;
- }
- return;
-}
-
-
-/**************************************************************************
- v m Q u i t
-**
-**************************************************************************/
-void vmQuit(FICL_VM *pVM)
-{
- static FICL_WORD *pInterp = NULL;
- if (!pInterp)
- pInterp = ficlLookup("interpret");
- assert(pInterp);
-
- stackReset(pVM->rStack);
- pVM->fRestart = 0;
- pVM->ip = &pInterp;
- pVM->runningWord = pInterp;
- pVM->state = INTERPRET;
- pVM->tib.cp = NULL;
- pVM->tib.index = 0;
- pVM->pad[0] = '\0';
- pVM->sourceID.i = 0;
- return;
-}
-
-
-/**************************************************************************
- v m R e s e t
-**
-**************************************************************************/
-void vmReset(FICL_VM *pVM)
-{
- vmQuit(pVM);
- stackReset(pVM->pStack);
- pVM->base = 10;
- return;
-}
-
-
-/**************************************************************************
- v m S e t T e x t O u t
-** Binds the specified output callback to the vm. If you pass NULL,
-** binds the default output function (ficlTextOut)
-**************************************************************************/
-void vmSetTextOut(FICL_VM *pVM, OUTFUNC textOut)
-{
- if (textOut)
- pVM->textOut = textOut;
- else
- pVM->textOut = ficlTextOut;
-
- return;
-}
-
-
-/**************************************************************************
- v m T e x t O u t
-** Feeds text to the vm's output callback
-**************************************************************************/
-void vmTextOut(FICL_VM *pVM, char *text, int fNewline)
-{
- assert(pVM);
- assert(pVM->textOut);
- (pVM->textOut)(pVM, text, fNewline);
-
- return;
-}
-
-
-/**************************************************************************
- v m T h r o w
-**
-**************************************************************************/
-void vmThrow(FICL_VM *pVM, int except)
-{
- longjmp(*(pVM->pState), except);
-}
-
-
-void vmThrowErr(FICL_VM *pVM, char *fmt, ...)
-{
- va_list va;
- va_start(va, fmt);
- vsprintf(pVM->pad, fmt, va);
- vmTextOut(pVM, pVM->pad, 1);
- va_end(va);
- longjmp(*(pVM->pState), VM_ERREXIT);
-}
-
-
-/**************************************************************************
- w o r d I s I m m e d i a t e
-**
-**************************************************************************/
-int wordIsImmediate(FICL_WORD *pFW)
-{
- return ((pFW != NULL) && (pFW->flags & FW_IMMEDIATE));
-}
-
-
-/**************************************************************************
- w o r d I s C o m p i l e O n l y
-**
-**************************************************************************/
-int wordIsCompileOnly(FICL_WORD *pFW)
-{
- return ((pFW != NULL) && (pFW->flags & FW_COMPILE));
-}
-
-
-/**************************************************************************
- s t r r e v
-**
-**************************************************************************/
-char *strrev( char *string )
-{ /* reverse a string in-place */
- int i = strlen(string);
- char *p1 = string; /* first char of string */
- char *p2 = string + i - 1; /* last non-NULL char of string */
- char c;
-
- if (i > 1)
- {
- while (p1 < p2)
- {
- c = *p2;
- *p2 = *p1;
- *p1 = c;
- p1++; p2--;
- }
- }
-
- return string;
-}
-
-
-/**************************************************************************
- d i g i t _ t o _ c h a r
-**
-**************************************************************************/
-char digit_to_char(int value)
-{
- return digits[value];
-}
-
-
-/**************************************************************************
- l t o a
-**
-**************************************************************************/
-char *ltoa( INT32 value, char *string, int radix )
-{ /* convert long to string, any base */
- char *cp = string;
- int sign = ((radix == 10) && (value < 0));
- UNSQR result;
- UNS64 v;
-
- assert(radix > 1);
- assert(radix < 37);
- assert(string);
-
- if (sign)
- value = -value;
-
- if (value == 0)
- *cp++ = '0';
- else
- {
- v.hi = 0;
- v.lo = (UNS32)value;
- while (v.lo)
- {
- result = ficlLongDiv(v, (UNS32)radix);
- *cp++ = digits[result.rem];
- v.lo = result.quot;
- }
- }
-
- if (sign)
- *cp++ = '-';
-
- *cp++ = '\0';
-
- return strrev(string);
-}
-
-
-/**************************************************************************
- u l t o a
-**
-**************************************************************************/
-char *ultoa(UNS32 value, char *string, int radix )
-{ /* convert long to string, any base */
- char *cp = string;
- UNS64 ud;
- UNSQR result;
-
- assert(radix > 1);
- assert(radix < 37);
- assert(string);
-
- if (value == 0)
- *cp++ = '0';
- else
- {
- ud.hi = 0;
- ud.lo = value;
- result.quot = value;
-
- while (ud.lo)
- {
- result = ficlLongDiv(ud, (UNS32)radix);
- ud.lo = result.quot;
- *cp++ = digits[result.rem];
- }
- }
-
- *cp++ = '\0';
-
- return strrev(string);
-}
-
-
-/**************************************************************************
- c a s e F o l d
-** Case folds a NULL terminated string in place. All characters
-** get converted to lower case.
-**************************************************************************/
-char *caseFold(char *cp)
-{
- char *oldCp = cp;
-
- while (*cp)
- {
- if (isupper(*cp))
- *cp = (char)tolower(*cp);
- cp++;
- }
-
- return oldCp;
-}
-
-
-/**************************************************************************
- s t r i n c m p
-**
-**************************************************************************/
-int strincmp(char *cp1, char *cp2, FICL_COUNT count)
-{
- int i = 0;
- char c1, c2;
-
- for (c1 = *cp1, c2 = *cp2;
- ((i == 0) && count && c1 && c2);
- c1 = *++cp1, c2 = *++cp2, count--)
- {
- i = tolower(c1) - tolower(c2);
- }
-
- return i;
-}
-
-
-
-/**************************************************************************
- s k i p S p a c e
-** Given a string pointer, returns a pointer to the first non-space
-** char of the string, or to the NULL terminator if no such char found.
-**************************************************************************/
-char *skipSpace(char *cp)
-{
- assert(cp);
-
- while (isspace(*cp))
- cp++;
-
- return cp;
-}
-
-
diff --git a/sys/boot/ficl/words.c b/sys/boot/ficl/words.c
deleted file mode 100644
index c76c169a83d3..000000000000
--- a/sys/boot/ficl/words.c
+++ /dev/null
@@ -1,4544 +0,0 @@
-/*******************************************************************
-** w o r d s . c
-** Forth Inspired Command Language
-** ANS Forth CORE word-set written in C
-** Author: John Sadler (john_sadler@alum.mit.edu)
-** Created: 19 July 1997
-**
-*******************************************************************/
-
-#ifdef TESTMAIN
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <fcntl.h>
-#else
-#include <stand.h>
-#endif
-#include <string.h>
-#include "ficl.h"
-#include "math64.h"
-
-static void colonParen(FICL_VM *pVM);
-static void literalIm(FICL_VM *pVM);
-static void interpWord(FICL_VM *pVM, STRINGINFO si);
-
-/*
-** Control structure building words use these
-** strings' addresses as markers on the stack to
-** check for structure completion.
-*/
-static char doTag[] = "do";
-static char ifTag[] = "if";
-static char colonTag[] = "colon";
-static char leaveTag[] = "leave";
-static char beginTag[] = "begin";
-static char whileTag[] = "while";
-
-/*
-** Pointers to various words in the dictionary
-** -- initialized by ficlCompileCore, below --
-** for use by compiling words. Colon definitions
-** in ficl are lists of pointers to words. A bit
-** simple-minded...
-*/
-static FICL_WORD *pBranchParen = NULL;
-static FICL_WORD *pComma = NULL;
-static FICL_WORD *pDoParen = NULL;
-static FICL_WORD *pDoesParen = NULL;
-static FICL_WORD *pExitParen = NULL;
-static FICL_WORD *pIfParen = NULL;
-static FICL_WORD *pInterpret = NULL;
-static FICL_WORD *pLitParen = NULL;
-static FICL_WORD *pLoopParen = NULL;
-static FICL_WORD *pPLoopParen = NULL;
-static FICL_WORD *pQDoParen = NULL;
-static FICL_WORD *pSemiParen = NULL;
-static FICL_WORD *pStore = NULL;
-static FICL_WORD *pStringLit = NULL;
-static FICL_WORD *pType = NULL;
-
-#if FICL_WANT_LOCALS
-static FICL_WORD *pGetLocalParen= NULL;
-static FICL_WORD *pGetLocal0 = NULL;
-static FICL_WORD *pGetLocal1 = NULL;
-static FICL_WORD *pToLocalParen = NULL;
-static FICL_WORD *pToLocal0 = NULL;
-static FICL_WORD *pToLocal1 = NULL;
-static FICL_WORD *pLinkParen = NULL;
-static FICL_WORD *pUnLinkParen = NULL;
-static int nLocals = 0;
-#endif
-
-
-/*
-** C O N T R O L S T R U C T U R E B U I L D E R S
-**
-** Push current dict location for later branch resolution.
-** The location may be either a branch target or a patch address...
-*/
-static void markBranch(FICL_DICT *dp, FICL_VM *pVM, char *tag)
-{
- stackPushPtr(pVM->pStack, dp->here);
- stackPushPtr(pVM->pStack, tag);
- return;
-}
-
-static void markControlTag(FICL_VM *pVM, char *tag)
-{
- stackPushPtr(pVM->pStack, tag);
- return;
-}
-
-static void matchControlTag(FICL_VM *pVM, char *tag)
-{
- char *cp = (char *)stackPopPtr(pVM->pStack);
- if ( strcmp(cp, tag) )
- {
- vmTextOut(pVM, "Warning -- unmatched control word: ", 0);
- vmTextOut(pVM, tag, 1);
- }
-
- return;
-}
-
-/*
-** Expect a branch target address on the param stack,
-** compile a literal offset from the current dict location
-** to the target address
-*/
-static void resolveBackBranch(FICL_DICT *dp, FICL_VM *pVM, char *tag)
-{
- long offset;
- CELL *patchAddr;
-
- matchControlTag(pVM, tag);
-
- patchAddr = (CELL *)stackPopPtr(pVM->pStack);
- offset = patchAddr - dp->here;
- dictAppendCell(dp, LVALUEtoCELL(offset));
-
- return;
-}
-
-
-/*
-** Expect a branch patch address on the param stack,
-** compile a literal offset from the patch location
-** to the current dict location
-*/
-static void resolveForwardBranch(FICL_DICT *dp, FICL_VM *pVM, char *tag)
-{
- long offset;
- CELL *patchAddr;
-
- matchControlTag(pVM, tag);
-
- patchAddr = (CELL *)stackPopPtr(pVM->pStack);
- offset = dp->here - patchAddr;
- *patchAddr = LVALUEtoCELL(offset);
-
- return;
-}
-
-/*
-** Match the tag to the top of the stack. If success,
-** sopy "here" address into the cell whose address is next
-** on the stack. Used by do..leave..loop.
-*/
-static void resolveAbsBranch(FICL_DICT *dp, FICL_VM *pVM, char *tag)
-{
- CELL *patchAddr;
- char *cp;
-
- cp = stackPopPtr(pVM->pStack);
- if (strcmp(cp, tag))
- {
- vmTextOut(pVM, "Warning -- Unmatched control word: ", 0);
- vmTextOut(pVM, tag, 1);
- }
-
- patchAddr = (CELL *)stackPopPtr(pVM->pStack);
- *patchAddr = LVALUEtoCELL(dp->here);
-
- return;
-}
-
-
-/**************************************************************************
- i s N u m b e r
-** Attempts to convert the NULL terminated string in the VM's pad to
-** a number using the VM's current base. If successful, pushes the number
-** onto the param stack and returns TRUE. Otherwise, returns FALSE.
-**************************************************************************/
-
-static int isNumber(FICL_VM *pVM, STRINGINFO si)
-{
- INT32 accum = 0;
- char isNeg = FALSE;
- unsigned base = pVM->base;
- char *cp = SI_PTR(si);
- FICL_COUNT count= (FICL_COUNT)SI_COUNT(si);
- unsigned ch;
- unsigned digit;
-
- if (*cp == '-')
- {
- cp++;
- count--;
- isNeg = TRUE;
- }
- else if ((cp[0] == '0') && (cp[1] == 'x'))
- { /* detect 0xNNNN format for hex numbers */
- cp += 2;
- count -= 2;
- base = 16;
- }
-
- if (count == 0)
- return FALSE;
-
- while (count-- && ((ch = *cp++) != '\0'))
- {
- if (ch < '0')
- return FALSE;
-
- digit = ch - '0';
-
- if (digit > 9)
- digit = tolower(ch) - 'a' + 10;
- /*
- ** Note: following test also catches chars between 9 and a
- ** because 'digit' is unsigned!
- */
- if (digit >= base)
- return FALSE;
-
- accum = accum * base + digit;
- }
-
- if (isNeg)
- accum = -accum;
-
- stackPushINT32(pVM->pStack, accum);
-
- return TRUE;
-}
-
-
-/**************************************************************************
- a d d & f r i e n d s
-**
-**************************************************************************/
-
-static void add(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- i = stackPopINT32(pVM->pStack);
- i += stackGetTop(pVM->pStack).i;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void sub(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- i = stackPopINT32(pVM->pStack);
- i = stackGetTop(pVM->pStack).i - i;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void mul(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- i = stackPopINT32(pVM->pStack);
- i *= stackGetTop(pVM->pStack).i;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void negate(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- i = -stackPopINT32(pVM->pStack);
- stackPushINT32(pVM->pStack, i);
- return;
-}
-
-static void ficlDiv(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- i = stackPopINT32(pVM->pStack);
- i = stackGetTop(pVM->pStack).i / i;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-/*
-** slash-mod CORE ( n1 n2 -- n3 n4 )
-** Divide n1 by n2, giving the single-cell remainder n3 and the single-cell
-** quotient n4. An ambiguous condition exists if n2 is zero. If n1 and n2
-** differ in sign, the implementation-defined result returned will be the
-** same as that returned by either the phrase
-** >R S>D R> FM/MOD or the phrase >R S>D R> SM/REM .
-** NOTE: Ficl complies with the second phrase (symmetric division)
-*/
-static void slashMod(FICL_VM *pVM)
-{
- INT64 n1;
- INT32 n2;
- INTQR qr;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 2);
-#endif
- n2 = stackPopINT32(pVM->pStack);
- n1.lo = stackPopINT32(pVM->pStack);
- i64Extend(n1);
-
- qr = m64SymmetricDivI(n1, n2);
- stackPushINT32(pVM->pStack, qr.rem);
- stackPushINT32(pVM->pStack, qr.quot);
- return;
-}
-
-static void onePlus(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- i = stackGetTop(pVM->pStack).i;
- i += 1;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void oneMinus(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- i = stackGetTop(pVM->pStack).i;
- i -= 1;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void twoMul(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- i = stackGetTop(pVM->pStack).i;
- i *= 2;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void twoDiv(FICL_VM *pVM)
-{
- INT32 i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- i = stackGetTop(pVM->pStack).i;
- i >>= 1;
- stackSetTop(pVM->pStack, LVALUEtoCELL(i));
- return;
-}
-
-static void mulDiv(FICL_VM *pVM)
-{
- INT32 x, y, z;
- INT64 prod;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 3, 1);
-#endif
- z = stackPopINT32(pVM->pStack);
- y = stackPopINT32(pVM->pStack);
- x = stackPopINT32(pVM->pStack);
-
- prod = m64MulI(x,y);
- x = m64SymmetricDivI(prod, z).quot;
-
- stackPushINT32(pVM->pStack, x);
- return;
-}
-
-
-static void mulDivRem(FICL_VM *pVM)
-{
- INT32 x, y, z;
- INT64 prod;
- INTQR qr;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 3, 2);
-#endif
- z = stackPopINT32(pVM->pStack);
- y = stackPopINT32(pVM->pStack);
- x = stackPopINT32(pVM->pStack);
-
- prod = m64MulI(x,y);
- qr = m64SymmetricDivI(prod, z);
-
- stackPushINT32(pVM->pStack, qr.rem);
- stackPushINT32(pVM->pStack, qr.quot);
- return;
-}
-
-
-/**************************************************************************
- b y e
-** TOOLS
-** Signal the system to shut down - this causes ficlExec to return
-** VM_USEREXIT. The rest is up to you.
-**************************************************************************/
-
-static void bye(FICL_VM *pVM)
-{
- vmThrow(pVM, VM_USEREXIT);
- return;
-}
-
-
-/**************************************************************************
- c o l o n d e f i n i t i o n s
-** Code to begin compiling a colon definition
-** This function sets the state to COMPILE, then creates a
-** new word whose name is the next word in the input stream
-** and whose code is colonParen.
-**************************************************************************/
-
-static void colon(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- STRINGINFO si = vmGetWord(pVM);
-
- pVM->state = COMPILE;
- markControlTag(pVM, colonTag);
- dictAppendWord2(dp, si, colonParen, FW_DEFAULT | FW_SMUDGE);
-#if FICL_WANT_LOCALS
- nLocals = 0;
-#endif
- return;
-}
-
-
-/**************************************************************************
- c o l o n P a r e n
-** This is the code that executes a colon definition. It assumes that the
-** virtual machine is running a "next" loop (See the vm.c
-** for its implementation of member function vmExecute()). The colon
-** code simply copies the address of the first word in the list of words
-** to interpret into IP after saving its old value. When we return to the
-** "next" loop, the virtual machine will call the code for each word in
-** turn.
-**
-**************************************************************************/
-
-static void colonParen(FICL_VM *pVM)
-{
- IPTYPE tempIP = (IPTYPE) (pVM->runningWord->param);
- vmPushIP(pVM, tempIP);
-
- return;
-}
-
-
-/**************************************************************************
- s e m i c o l o n C o I m
-**
-** IMMEDIATE code for ";". This function sets the state to INTERPRET and
-** terminates a word under compilation by appending code for "(;)" to
-** the definition. TO DO: checks for leftover branch target tags on the
-** return stack and complains if any are found.
-**************************************************************************/
-static void semiParen(FICL_VM *pVM)
-{
- vmPopIP(pVM);
- return;
-}
-
-
-static void semicolonCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pSemiParen);
- matchControlTag(pVM, colonTag);
-
-#if FICL_WANT_LOCALS
- assert(pUnLinkParen);
- if (nLocals > 0)
- {
- FICL_DICT *pLoc = ficlGetLoc();
- dictEmpty(pLoc, pLoc->pForthWords->size);
- dictAppendCell(dp, LVALUEtoCELL(pUnLinkParen));
- }
- nLocals = 0;
-#endif
-
- dictAppendCell(dp, LVALUEtoCELL(pSemiParen));
- pVM->state = INTERPRET;
- dictUnsmudge(dp);
- return;
-}
-
-
-/**************************************************************************
- e x i t
-** CORE
-** This function simply pops the previous instruction
-** pointer and returns to the "next" loop. Used for exiting from within
-** a definition. Note that exitParen is identical to semiParen - they
-** are in two different functions so that "see" can correctly identify
-** the end of a colon definition, even if it uses "exit".
-**************************************************************************/
-static void exitParen(FICL_VM *pVM)
-{
- vmPopIP(pVM);
- return;
-}
-
-static void exitCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- assert(pExitParen);
- IGNORE(pVM);
-
-#if FICL_WANT_LOCALS
- if (nLocals > 0)
- {
- dictAppendCell(dp, LVALUEtoCELL(pUnLinkParen));
- }
-#endif
- dictAppendCell(dp, LVALUEtoCELL(pExitParen));
- return;
-}
-
-
-/**************************************************************************
- c o n s t a n t P a r e n
-** This is the run-time code for "constant". It simply returns the
-** contents of its word's first data cell.
-**
-**************************************************************************/
-
-void constantParen(FICL_VM *pVM)
-{
- FICL_WORD *pFW = pVM->runningWord;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
- stackPush(pVM->pStack, pFW->param[0]);
- return;
-}
-
-void twoConstParen(FICL_VM *pVM)
-{
- FICL_WORD *pFW = pVM->runningWord;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 2);
-#endif
- stackPush(pVM->pStack, pFW->param[0]); /* lo */
- stackPush(pVM->pStack, pFW->param[1]); /* hi */
- return;
-}
-
-
-/**************************************************************************
- c o n s t a n t
-** IMMEDIATE
-** Compiles a constant into the dictionary. Constants return their
-** value when invoked. Expects a value on top of the parm stack.
-**************************************************************************/
-
-static void constant(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- STRINGINFO si = vmGetWord(pVM);
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- dictAppendWord2(dp, si, constantParen, FW_DEFAULT);
- dictAppendCell(dp, stackPop(pVM->pStack));
- return;
-}
-
-
-static void twoConstant(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- STRINGINFO si = vmGetWord(pVM);
- CELL c;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- c = stackPop(pVM->pStack);
- dictAppendWord2(dp, si, twoConstParen, FW_DEFAULT);
- dictAppendCell(dp, stackPop(pVM->pStack));
- dictAppendCell(dp, c);
- return;
-}
-
-
-/**************************************************************************
- d i s p l a y C e l l
-** Drop and print the contents of the cell at the top of the param
-** stack
-**************************************************************************/
-
-static void displayCell(FICL_VM *pVM)
-{
- CELL c;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- c = stackPop(pVM->pStack);
- ltoa((c).i, pVM->pad, pVM->base);
- strcat(pVM->pad, " ");
- vmTextOut(pVM, pVM->pad, 0);
- return;
-}
-
-static void displayCellNoPad(FICL_VM *pVM)
-{
- CELL c;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- c = stackPop(pVM->pStack);
- ltoa((c).i, pVM->pad, pVM->base);
- vmTextOut(pVM, pVM->pad, 0);
- return;
-}
-
-static void uDot(FICL_VM *pVM)
-{
- UNS32 u;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- u = stackPopUNS32(pVM->pStack);
- ultoa(u, pVM->pad, pVM->base);
- strcat(pVM->pad, " ");
- vmTextOut(pVM, pVM->pad, 0);
- return;
-}
-
-
-static void hexDot(FICL_VM *pVM)
-{
- UNS32 u;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- u = stackPopUNS32(pVM->pStack);
- ultoa(u, pVM->pad, 16);
- strcat(pVM->pad, " ");
- vmTextOut(pVM, pVM->pad, 0);
- return;
-}
-
-
-/**************************************************************************
- d i s p l a y S t a c k
-** Display the parameter stack (code for ".s")
-**************************************************************************/
-
-static void displayStack(FICL_VM *pVM)
-{
- int d = stackDepth(pVM->pStack);
- int i;
- CELL *pCell;
-
- vmCheckStack(pVM, 0, 0);
-
- if (d == 0)
- vmTextOut(pVM, "(Stack Empty)", 1);
- else
- {
- pCell = pVM->pStack->sp;
- for (i = 0; i < d; i++)
- {
- vmTextOut(pVM, ltoa((*--pCell).i, pVM->pad, pVM->base), 1);
- }
- }
-}
-
-
-/**************************************************************************
- d u p & f r i e n d s
-**
-**************************************************************************/
-
-static void depth(FICL_VM *pVM)
-{
- int i;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
- i = stackDepth(pVM->pStack);
- stackPushINT32(pVM->pStack, i);
- return;
-}
-
-
-static void drop(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- stackDrop(pVM->pStack, 1);
- return;
-}
-
-
-static void twoDrop(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- stackDrop(pVM->pStack, 2);
- return;
-}
-
-
-static void dup(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 2);
-#endif
- stackPick(pVM->pStack, 0);
- return;
-}
-
-
-static void twoDup(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 4);
-#endif
- stackPick(pVM->pStack, 1);
- stackPick(pVM->pStack, 1);
- return;
-}
-
-
-static void over(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 3);
-#endif
- stackPick(pVM->pStack, 1);
- return;
-}
-
-static void twoOver(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 4, 6);
-#endif
- stackPick(pVM->pStack, 3);
- stackPick(pVM->pStack, 3);
- return;
-}
-
-
-static void pick(FICL_VM *pVM)
-{
- CELL c = stackPop(pVM->pStack);
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, c.i+1, c.i+2);
-#endif
- stackPick(pVM->pStack, c.i);
- return;
-}
-
-
-static void questionDup(FICL_VM *pVM)
-{
- CELL c;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 2);
-#endif
- c = stackGetTop(pVM->pStack);
-
- if (c.i != 0)
- stackPick(pVM->pStack, 0);
-
- return;
-}
-
-
-static void roll(FICL_VM *pVM)
-{
- int i = stackPop(pVM->pStack).i;
- i = (i > 0) ? i : 0;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, i+1, i+1);
-#endif
- stackRoll(pVM->pStack, i);
- return;
-}
-
-
-static void minusRoll(FICL_VM *pVM)
-{
- int i = stackPop(pVM->pStack).i;
- i = (i > 0) ? i : 0;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, i+1, i+1);
-#endif
- stackRoll(pVM->pStack, -i);
- return;
-}
-
-
-static void rot(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 3, 3);
-#endif
- stackRoll(pVM->pStack, 2);
- return;
-}
-
-
-static void swap(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 2);
-#endif
- stackRoll(pVM->pStack, 1);
- return;
-}
-
-
-static void twoSwap(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 4, 4);
-#endif
- stackRoll(pVM->pStack, 3);
- stackRoll(pVM->pStack, 3);
- return;
-}
-
-
-/**************************************************************************
- e m i t & f r i e n d s
-**
-**************************************************************************/
-
-static void emit(FICL_VM *pVM)
-{
- char *cp = pVM->pad;
- int i;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- i = stackPopINT32(pVM->pStack);
- cp[0] = (char)i;
- cp[1] = '\0';
- vmTextOut(pVM, cp, 0);
- return;
-}
-
-
-static void cr(FICL_VM *pVM)
-{
- vmTextOut(pVM, "", 1);
- return;
-}
-
-
-static void commentLine(FICL_VM *pVM)
-{
- char *cp = vmGetInBuf(pVM);
- char ch = *cp;
-
- while ((ch != '\0') && (ch != '\r') && (ch != '\n'))
- {
- ch = *++cp;
- }
-
- /*
- ** Cope with DOS or UNIX-style EOLs -
- ** Check for /r, /n, /r/n, or /n/r end-of-line sequences,
- ** and point cp to next char. If EOL is \0, we're done.
- */
- if (ch != '\0')
- {
- cp++;
-
- if ( (ch != *cp)
- && ((*cp == '\r') || (*cp == '\n')) )
- cp++;
- }
-
- vmUpdateTib(pVM, cp);
- return;
-}
-
-
-/*
-** paren CORE
-** Compilation: Perform the execution semantics given below.
-** Execution: ( "ccc<paren>" -- )
-** Parse ccc delimited by ) (right parenthesis). ( is an immediate word.
-** The number of characters in ccc may be zero to the number of characters
-** in the parse area.
-**
-*/
-static void commentHang(FICL_VM *pVM)
-{
- vmParseString(pVM, ')');
- return;
-}
-
-
-/**************************************************************************
- F E T C H & S T O R E
-**
-**************************************************************************/
-
-static void fetch(FICL_VM *pVM)
-{
- CELL *pCell;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- pCell = (CELL *)stackPopPtr(pVM->pStack);
- stackPush(pVM->pStack, *pCell);
- return;
-}
-
-/*
-** two-fetch CORE ( a-addr -- x1 x2 )
-** Fetch the cell pair x1 x2 stored at a-addr. x2 is stored at a-addr and
-** x1 at the next consecutive cell. It is equivalent to the sequence
-** DUP CELL+ @ SWAP @ .
-*/
-static void twoFetch(FICL_VM *pVM)
-{
- CELL *pCell;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 2);
-#endif
- pCell = (CELL *)stackPopPtr(pVM->pStack);
- stackPush(pVM->pStack, *pCell++);
- stackPush(pVM->pStack, *pCell);
- swap(pVM);
- return;
-}
-
-/*
-** store CORE ( x a-addr -- )
-** Store x at a-addr.
-*/
-static void store(FICL_VM *pVM)
-{
- CELL *pCell;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- pCell = (CELL *)stackPopPtr(pVM->pStack);
- *pCell = stackPop(pVM->pStack);
-}
-
-/*
-** two-store CORE ( x1 x2 a-addr -- )
-** Store the cell pair x1 x2 at a-addr, with x2 at a-addr and x1 at the
-** next consecutive cell. It is equivalent to the sequence
-** SWAP OVER ! CELL+ ! .
-*/
-static void twoStore(FICL_VM *pVM)
-{
- CELL *pCell;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 3, 0);
-#endif
- pCell = (CELL *)stackPopPtr(pVM->pStack);
- *pCell++ = stackPop(pVM->pStack);
- *pCell = stackPop(pVM->pStack);
-}
-
-static void plusStore(FICL_VM *pVM)
-{
- CELL *pCell;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- pCell = (CELL *)stackPopPtr(pVM->pStack);
- pCell->i += stackPop(pVM->pStack).i;
-}
-
-
-static void wFetch(FICL_VM *pVM)
-{
- UNS16 *pw;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- pw = (UNS16 *)stackPopPtr(pVM->pStack);
- stackPushUNS32(pVM->pStack, (UNS32)*pw);
- return;
-}
-
-static void wStore(FICL_VM *pVM)
-{
- UNS16 *pw;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- pw = (UNS16 *)stackPopPtr(pVM->pStack);
- *pw = (UNS16)(stackPop(pVM->pStack).u);
-}
-
-static void cFetch(FICL_VM *pVM)
-{
- UNS8 *pc;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- pc = (UNS8 *)stackPopPtr(pVM->pStack);
- stackPushUNS32(pVM->pStack, (UNS32)*pc);
- return;
-}
-
-static void cStore(FICL_VM *pVM)
-{
- UNS8 *pc;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- pc = (UNS8 *)stackPopPtr(pVM->pStack);
- *pc = (UNS8)(stackPop(pVM->pStack).u);
-}
-
-
-/**************************************************************************
- i f C o I m
-** IMMEDIATE
-** Compiles code for a conditional branch into the dictionary
-** and pushes the branch patch address on the stack for later
-** patching by ELSE or THEN/ENDIF.
-**************************************************************************/
-
-static void ifCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pIfParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pIfParen));
- markBranch(dp, pVM, ifTag);
- dictAppendUNS32(dp, 1);
- return;
-}
-
-
-/**************************************************************************
- i f P a r e n
-** Runtime code to do "if" or "until": pop a flag from the stack,
-** fall through if true, branch if false. Probably ought to be
-** called (not?branch) since it does "branch if false".
-**************************************************************************/
-
-static void ifParen(FICL_VM *pVM)
-{
- UNS32 flag;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- flag = stackPopUNS32(pVM->pStack);
-
- if (flag)
- { /* fall through */
- vmBranchRelative(pVM, 1);
- }
- else
- { /* take branch (to else/endif/begin) */
- vmBranchRelative(pVM, (int)(*pVM->ip));
- }
-
- return;
-}
-
-
-/**************************************************************************
- e l s e C o I m
-**
-** IMMEDIATE -- compiles an "else"...
-** 1) Compile a branch and a patch address; the address gets patched
-** by "endif" to point past the "else" code.
-** 2) Pop the the "if" patch address
-** 3) Patch the "if" branch to point to the current compile address.
-** 4) Push the "else" patch address. ("endif" patches this to jump past
-** the "else" code.
-**************************************************************************/
-
-static void elseCoIm(FICL_VM *pVM)
-{
- CELL *patchAddr;
- int offset;
- FICL_DICT *dp = ficlGetDict();
-
- assert(pBranchParen);
- /* (1) compile branch runtime */
- dictAppendCell(dp, LVALUEtoCELL(pBranchParen));
- matchControlTag(pVM, ifTag);
- patchAddr =
- (CELL *)stackPopPtr(pVM->pStack); /* (2) pop "if" patch addr */
- markBranch(dp, pVM, ifTag); /* (4) push "else" patch addr */
- dictAppendUNS32(dp, 1); /* (1) compile patch placeholder */
- offset = dp->here - patchAddr;
- *patchAddr = LVALUEtoCELL(offset); /* (3) Patch "if" */
-
- return;
-}
-
-
-/**************************************************************************
- b r a n c h P a r e n
-**
-** Runtime for "(branch)" -- expects a literal offset in the next
-** compilation address, and branches to that location.
-**************************************************************************/
-
-static void branchParen(FICL_VM *pVM)
-{
- vmBranchRelative(pVM, *(int *)(pVM->ip));
- return;
-}
-
-
-/**************************************************************************
- e n d i f C o I m
-**
-**************************************************************************/
-
-static void endifCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- resolveForwardBranch(dp, pVM, ifTag);
- return;
-}
-
-
-/**************************************************************************
- i n t e r p r e t
-** This is the "user interface" of a Forth. It does the following:
-** while there are words in the VM's Text Input Buffer
-** Copy next word into the pad (vmGetWord)
-** Attempt to find the word in the dictionary (dictLookup)
-** If successful, execute the word.
-** Otherwise, attempt to convert the word to a number (isNumber)
-** If successful, push the number onto the parameter stack.
-** Otherwise, print an error message and exit loop...
-** End Loop
-**
-** From the standard, section 3.4
-** Text interpretation (see 6.1.1360 EVALUATE and 6.1.2050 QUIT) shall
-** repeat the following steps until either the parse area is empty or an
-** ambiguous condition exists:
-** a) Skip leading spaces and parse a name (see 3.4.1);
-**************************************************************************/
-
-static void interpret(FICL_VM *pVM)
-{
- STRINGINFO si = vmGetWord0(pVM);
- assert(pVM);
-
- vmBranchRelative(pVM, -1);
-
- /*
- // Get next word...if out of text, we're done.
- */
- if (si.count == 0)
- {
- vmThrow(pVM, VM_OUTOFTEXT);
- }
-
- interpWord(pVM, si);
-
-
- return; /* back to inner interpreter */
-}
-
-/**************************************************************************
-** From the standard, section 3.4
-** b) Search the dictionary name space (see 3.4.2). If a definition name
-** matching the string is found:
-** 1.if interpreting, perform the interpretation semantics of the definition
-** (see 3.4.3.2), and continue at a);
-** 2.if compiling, perform the compilation semantics of the definition
-** (see 3.4.3.3), and continue at a).
-**
-** c) If a definition name matching the string is not found, attempt to
-** convert the string to a number (see 3.4.1.3). If successful:
-** 1.if interpreting, place the number on the data stack, and continue at a);
-** 2.if compiling, compile code that when executed will place the number on
-** the stack (see 6.1.1780 LITERAL), and continue at a);
-**
-** d) If unsuccessful, an ambiguous condition exists (see 3.4.4).
-**************************************************************************/
-static void interpWord(FICL_VM *pVM, STRINGINFO si)
-{
- FICL_DICT *dp = ficlGetDict();
- FICL_WORD *tempFW;
-
-#if FICL_ROBUST
- dictCheck(dp, pVM, 0);
- vmCheckStack(pVM, 0, 0);
-#endif
-
-#if FICL_WANT_LOCALS
- if (nLocals > 0)
- {
- tempFW = dictLookupLoc(dp, si);
- }
- else
-#endif
- tempFW = dictLookup(dp, si);
-
- if (pVM->state == INTERPRET)
- {
- if (tempFW != NULL)
- {
- if (wordIsCompileOnly(tempFW))
- {
- vmThrowErr(pVM, "Error: Compile only!");
- }
-
- vmExecute(pVM, tempFW);
- }
-
- else if (!isNumber(pVM, si))
- {
- int i = SI_COUNT(si);
- vmThrowErr(pVM, "%.*s not found", i, SI_PTR(si));
- }
- }
-
- else /* (pVM->state == COMPILE) */
- {
- if (tempFW != NULL)
- {
- if (wordIsImmediate(tempFW))
- {
- vmExecute(pVM, tempFW);
- }
- else
- {
- dictAppendCell(dp, LVALUEtoCELL(tempFW));
- }
- }
- else if (isNumber(pVM, si))
- {
- literalIm(pVM);
- }
- else
- {
- int i = SI_COUNT(si);
- vmThrowErr(pVM, "%.*s not found", i, SI_PTR(si));
- }
- }
-
- return;
-}
-
-
-/**************************************************************************
- l i t e r a l P a r e n
-**
-** This is the runtime for (literal). It assumes that it is part of a colon
-** definition, and that the next CELL contains a value to be pushed on the
-** parameter stack at runtime. This code is compiled by "literal".
-**
-**************************************************************************/
-
-static void literalParen(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
- stackPushINT32(pVM->pStack, *(INT32 *)(pVM->ip));
- vmBranchRelative(pVM, 1);
- return;
-}
-
-
-/**************************************************************************
- l i t e r a l I m
-**
-** IMMEDIATE code for "literal". This function gets a value from the stack
-** and compiles it into the dictionary preceded by the code for "(literal)".
-** IMMEDIATE
-**************************************************************************/
-
-static void literalIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- assert(pLitParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pLitParen));
- dictAppendCell(dp, stackPop(pVM->pStack));
-
- return;
-}
-
-
-/**************************************************************************
- l i s t W o r d s
-**
-**************************************************************************/
-#define nCOLWIDTH 8
-static void listWords(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- FICL_HASH *pHash = dp->pSearch[dp->nLists - 1];
- FICL_WORD *wp;
- int nChars = 0;
- int len;
- int y = 0;
- unsigned i;
- int nWords = 0;
- char *cp;
- char *pPad = pVM->pad;
-
- for (i = 0; i < pHash->size; i++)
- {
- for (wp = pHash->table[i]; wp != NULL; wp = wp->link, nWords++)
- {
- if (wp->nName == 0) /* ignore :noname defs */
- continue;
-
- cp = wp->name;
- nChars += sprintf(pPad + nChars, "%s", cp);
-
- if (nChars > 70)
- {
- pPad[nChars] = '\0';
- nChars = 0;
- y++;
- if(y>23) {
- y=0;
- vmTextOut(pVM, "--- Press Enter to continue ---",0);
- getchar();
- vmTextOut(pVM,"\r",0);
- }
- vmTextOut(pVM, pPad, 1);
- }
- else
- {
- len = nCOLWIDTH - nChars % nCOLWIDTH;
- while (len-- > 0)
- pPad[nChars++] = ' ';
- }
-
- if (nChars > 70)
- {
- pPad[nChars] = '\0';
- nChars = 0;
- y++;
- if(y>23) {
- y=0;
- vmTextOut(pVM, "--- Press Enter to continue ---",0);
- getchar();
- vmTextOut(pVM,"\r",0);
- }
- vmTextOut(pVM, pPad, 1);
- }
- }
- }
-
- if (nChars > 0)
- {
- pPad[nChars] = '\0';
- nChars = 0;
- vmTextOut(pVM, pPad, 1);
- }
-
- sprintf(pVM->pad, "Dictionary: %d words, %ld cells used of %lu total",
- nWords, dp->here - dp->dict, dp->size);
- vmTextOut(pVM, pVM->pad, 1);
- return;
-}
-
-
-static void listEnv(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetEnv();
- FICL_HASH *pHash = dp->pForthWords;
- FICL_WORD *wp;
- unsigned i;
- int nWords = 0;
-
- for (i = 0; i < pHash->size; i++)
- {
- for (wp = pHash->table[i]; wp != NULL; wp = wp->link, nWords++)
- {
- vmTextOut(pVM, wp->name, 1);
- }
- }
-
- sprintf(pVM->pad, "Environment: %d words, %ld cells used of %lu total",
- nWords, dp->here - dp->dict, dp->size);
- vmTextOut(pVM, pVM->pad, 1);
- return;
-}
-
-
-/**************************************************************************
- l o g i c a n d c o m p a r i s o n s
-**
-**************************************************************************/
-
-static void zeroEquals(FICL_VM *pVM)
-{
- CELL c;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- c.i = FICL_BOOL(stackPopINT32(pVM->pStack) == 0);
- stackPush(pVM->pStack, c);
- return;
-}
-
-static void zeroLess(FICL_VM *pVM)
-{
- CELL c;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- c.i = FICL_BOOL(stackPopINT32(pVM->pStack) < 0);
- stackPush(pVM->pStack, c);
- return;
-}
-
-static void zeroGreater(FICL_VM *pVM)
-{
- CELL c;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- c.i = FICL_BOOL(stackPopINT32(pVM->pStack) > 0);
- stackPush(pVM->pStack, c);
- return;
-}
-
-static void isEqual(FICL_VM *pVM)
-{
- CELL x, y;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- x = stackPop(pVM->pStack);
- y = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, FICL_BOOL(x.i == y.i));
- return;
-}
-
-static void isLess(FICL_VM *pVM)
-{
- CELL x, y;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- y = stackPop(pVM->pStack);
- x = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, FICL_BOOL(x.i < y.i));
- return;
-}
-
-static void uIsLess(FICL_VM *pVM)
-{
- UNS32 u1, u2;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- u2 = stackPopUNS32(pVM->pStack);
- u1 = stackPopUNS32(pVM->pStack);
- stackPushINT32(pVM->pStack, FICL_BOOL(u1 < u2));
- return;
-}
-
-static void isGreater(FICL_VM *pVM)
-{
- CELL x, y;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- y = stackPop(pVM->pStack);
- x = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, FICL_BOOL(x.i > y.i));
- return;
-}
-
-static void bitwiseAnd(FICL_VM *pVM)
-{
- CELL x, y;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- x = stackPop(pVM->pStack);
- y = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, x.i & y.i);
- return;
-}
-
-static void bitwiseOr(FICL_VM *pVM)
-{
- CELL x, y;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- x = stackPop(pVM->pStack);
- y = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, x.i | y.i);
- return;
-}
-
-static void bitwiseXor(FICL_VM *pVM)
-{
- CELL x, y;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- x = stackPop(pVM->pStack);
- y = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, x.i ^ y.i);
- return;
-}
-
-static void bitwiseNot(FICL_VM *pVM)
-{
- CELL x;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- x = stackPop(pVM->pStack);
- stackPushINT32(pVM->pStack, ~x.i);
- return;
-}
-
-
-/**************************************************************************
- D o / L o o p
-** do -- IMMEDIATE COMPILE ONLY
-** Compiles code to initialize a loop: compile (do),
-** allot space to hold the "leave" address, push a branch
-** target address for the loop.
-** (do) -- runtime for "do"
-** pops index and limit from the p stack and moves them
-** to the r stack, then skips to the loop body.
-** loop -- IMMEDIATE COMPILE ONLY
-** +loop
-** Compiles code for the test part of a loop:
-** compile (loop), resolve forward branch from "do", and
-** copy "here" address to the "leave" address allotted by "do"
-** i,j,k -- COMPILE ONLY
-** Runtime: Push loop indices on param stack (i is innermost loop...)
-** Note: each loop has three values on the return stack:
-** ( R: leave limit index )
-** "leave" is the absolute address of the next cell after the loop
-** limit and index are the loop control variables.
-** leave -- COMPILE ONLY
-** Runtime: pop the loop control variables, then pop the
-** "leave" address and jump (absolute) there.
-**************************************************************************/
-
-static void doCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pDoParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pDoParen));
- /*
- ** Allot space for a pointer to the end
- ** of the loop - "leave" uses this...
- */
- markBranch(dp, pVM, leaveTag);
- dictAppendUNS32(dp, 0);
- /*
- ** Mark location of head of loop...
- */
- markBranch(dp, pVM, doTag);
-
- return;
-}
-
-
-static void doParen(FICL_VM *pVM)
-{
- CELL index, limit;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- index = stackPop(pVM->pStack);
- limit = stackPop(pVM->pStack);
-
- /* copy "leave" target addr to stack */
- stackPushPtr(pVM->rStack, *(pVM->ip++));
- stackPush(pVM->rStack, limit);
- stackPush(pVM->rStack, index);
-
- return;
-}
-
-
-static void qDoCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pQDoParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pQDoParen));
- /*
- ** Allot space for a pointer to the end
- ** of the loop - "leave" uses this...
- */
- markBranch(dp, pVM, leaveTag);
- dictAppendUNS32(dp, 0);
- /*
- ** Mark location of head of loop...
- */
- markBranch(dp, pVM, doTag);
-
- return;
-}
-
-
-static void qDoParen(FICL_VM *pVM)
-{
- CELL index, limit;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- index = stackPop(pVM->pStack);
- limit = stackPop(pVM->pStack);
-
- /* copy "leave" target addr to stack */
- stackPushPtr(pVM->rStack, *(pVM->ip++));
-
- if (limit.u == index.u)
- {
- vmPopIP(pVM);
- }
- else
- {
- stackPush(pVM->rStack, limit);
- stackPush(pVM->rStack, index);
- }
-
- return;
-}
-
-
-/*
-** Runtime code to break out of a do..loop construct
-** Drop the loop control variables; the branch address
-** past "loop" is next on the return stack.
-*/
-static void leaveCo(FICL_VM *pVM)
-{
- /* almost unloop */
- stackDrop(pVM->rStack, 2);
- /* exit */
- vmPopIP(pVM);
- return;
-}
-
-
-static void unloopCo(FICL_VM *pVM)
-{
- stackDrop(pVM->rStack, 3);
- return;
-}
-
-
-static void loopCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pLoopParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pLoopParen));
- resolveBackBranch(dp, pVM, doTag);
- resolveAbsBranch(dp, pVM, leaveTag);
- return;
-}
-
-
-static void plusLoopCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pPLoopParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pPLoopParen));
- resolveBackBranch(dp, pVM, doTag);
- resolveAbsBranch(dp, pVM, leaveTag);
- return;
-}
-
-
-static void loopParen(FICL_VM *pVM)
-{
- INT32 index = stackGetTop(pVM->rStack).i;
- INT32 limit = stackFetch(pVM->rStack, 1).i;
-
- index++;
-
- if (index >= limit)
- {
- stackDrop(pVM->rStack, 3); /* nuke the loop indices & "leave" addr */
- vmBranchRelative(pVM, 1); /* fall through the loop */
- }
- else
- { /* update index, branch to loop head */
- stackSetTop(pVM->rStack, LVALUEtoCELL(index));
- vmBranchRelative(pVM, *(int *)(pVM->ip));
- }
-
- return;
-}
-
-
-static void plusLoopParen(FICL_VM *pVM)
-{
- INT32 index = stackGetTop(pVM->rStack).i;
- INT32 limit = stackFetch(pVM->rStack, 1).i;
- INT32 increment = stackPop(pVM->pStack).i;
- int flag;
-
- index += increment;
-
- if (increment < 0)
- flag = (index < limit);
- else
- flag = (index >= limit);
-
- if (flag)
- {
- stackDrop(pVM->rStack, 3); /* nuke the loop indices & "leave" addr */
- vmBranchRelative(pVM, 1); /* fall through the loop */
- }
- else
- { /* update index, branch to loop head */
- stackSetTop(pVM->rStack, LVALUEtoCELL(index));
- vmBranchRelative(pVM, *(int *)(pVM->ip));
- }
-
- return;
-}
-
-
-static void loopICo(FICL_VM *pVM)
-{
- CELL index = stackGetTop(pVM->rStack);
- stackPush(pVM->pStack, index);
-
- return;
-}
-
-
-static void loopJCo(FICL_VM *pVM)
-{
- CELL index = stackFetch(pVM->rStack, 3);
- stackPush(pVM->pStack, index);
-
- return;
-}
-
-
-static void loopKCo(FICL_VM *pVM)
-{
- CELL index = stackFetch(pVM->rStack, 6);
- stackPush(pVM->pStack, index);
-
- return;
-}
-
-
-/**************************************************************************
- r e t u r n s t a c k
-**
-**************************************************************************/
-
-static void toRStack(FICL_VM *pVM)
-{
- stackPush(pVM->rStack, stackPop(pVM->pStack));
- return;
-}
-
-static void fromRStack(FICL_VM *pVM)
-{
- stackPush(pVM->pStack, stackPop(pVM->rStack));
- return;
-}
-
-static void fetchRStack(FICL_VM *pVM)
-{
- stackPush(pVM->pStack, stackGetTop(pVM->rStack));
- return;
-}
-
-
-/**************************************************************************
- v a r i a b l e
-**
-**************************************************************************/
-
-static void variableParen(FICL_VM *pVM)
-{
- FICL_WORD *fw = pVM->runningWord;
- stackPushPtr(pVM->pStack, fw->param);
- return;
-}
-
-
-static void variable(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- STRINGINFO si = vmGetWord(pVM);
-
- dictAppendWord2(dp, si, variableParen, FW_DEFAULT);
- dictAllotCells(dp, 1);
- return;
-}
-
-
-
-/**************************************************************************
- b a s e & f r i e n d s
-**
-**************************************************************************/
-
-static void base(FICL_VM *pVM)
-{
- CELL *pBase = (CELL *)(&pVM->base);
- stackPush(pVM->pStack, LVALUEtoCELL(pBase));
- return;
-}
-
-
-static void decimal(FICL_VM *pVM)
-{
- pVM->base = 10;
- return;
-}
-
-
-static void hex(FICL_VM *pVM)
-{
- pVM->base = 16;
- return;
-}
-
-
-/**************************************************************************
- a l l o t & f r i e n d s
-**
-**************************************************************************/
-
-static void allot(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- INT32 i = stackPopINT32(pVM->pStack);
-#if FICL_ROBUST
- dictCheck(dp, pVM, i);
-#endif
- dictAllot(dp, i);
- return;
-}
-
-
-static void here(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- stackPushPtr(pVM->pStack, dp->here);
- return;
-}
-
-
-static void comma(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- CELL c = stackPop(pVM->pStack);
- dictAppendCell(dp, c);
- return;
-}
-
-
-static void cComma(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- char c = (char)stackPopINT32(pVM->pStack);
- dictAppendChar(dp, c);
- return;
-}
-
-
-static void cells(FICL_VM *pVM)
-{
- INT32 i = stackPopINT32(pVM->pStack);
- stackPushINT32(pVM->pStack, i * (INT32)sizeof (CELL));
- return;
-}
-
-
-static void cellPlus(FICL_VM *pVM)
-{
- char *cp = stackPopPtr(pVM->pStack);
- stackPushPtr(pVM->pStack, cp + sizeof (CELL));
- return;
-}
-
-
-/**************************************************************************
- t i c k
-** tick CORE ( "<spaces>name" -- xt )
-** Skip leading space delimiters. Parse name delimited by a space. Find
-** name and return xt, the execution token for name. An ambiguous condition
-** exists if name is not found.
-**************************************************************************/
-static void tick(FICL_VM *pVM)
-{
- FICL_WORD *pFW = NULL;
- STRINGINFO si = vmGetWord(pVM);
-
- pFW = dictLookup(ficlGetDict(), si);
- if (!pFW)
- {
- int i = SI_COUNT(si);
- vmThrowErr(pVM, "%.*s not found", i, SI_PTR(si));
- }
- stackPushPtr(pVM->pStack, pFW);
- return;
-}
-
-
-static void bracketTickCoIm(FICL_VM *pVM)
-{
- tick(pVM);
- literalIm(pVM);
-
- return;
-}
-
-
-/**************************************************************************
- p o s t p o n e
-** Lookup the next word in the input stream and compile code to
-** insert it into definitions created by the resulting word
-** (defers compilation, even of immediate words)
-**************************************************************************/
-
-static void postponeCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- FICL_WORD *pFW;
- assert(pComma);
-
- tick(pVM);
- pFW = stackGetTop(pVM->pStack).p;
- if (wordIsImmediate(pFW))
- {
- dictAppendCell(dp, stackPop(pVM->pStack));
- }
- else
- {
- literalIm(pVM);
- dictAppendCell(dp, LVALUEtoCELL(pComma));
- }
-
- return;
-}
-
-
-
-/**************************************************************************
- e x e c u t e
-** Pop an execution token (pointer to a word) off the stack and
-** run it
-**************************************************************************/
-
-static void execute(FICL_VM *pVM)
-{
- FICL_WORD *pFW;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
-
- pFW = stackPopPtr(pVM->pStack);
- vmExecute(pVM, pFW);
-
- return;
-}
-
-
-/**************************************************************************
- i m m e d i a t e
-** Make the most recently compiled word IMMEDIATE -- it executes even
-** in compile state (most often used for control compiling words
-** such as IF, THEN, etc)
-**************************************************************************/
-
-static void immediate(FICL_VM *pVM)
-{
- IGNORE(pVM);
- dictSetImmediate(ficlGetDict());
- return;
-}
-
-
-static void compileOnly(FICL_VM *pVM)
-{
- IGNORE(pVM);
- dictSetFlags(ficlGetDict(), FW_COMPILE, 0);
- return;
-}
-
-
-/**************************************************************************
- d o t Q u o t e
-** IMMEDIATE word that compiles a string literal for later display
-** Compile stringLit, then copy the bytes of the string from the TIB
-** to the dictionary. Backpatch the count byte and align the dictionary.
-**
-** stringlit: Fetch the count from the dictionary, then push the address
-** and count on the stack. Finally, update ip to point to the first
-** aligned address after the string text.
-**************************************************************************/
-
-static void stringLit(FICL_VM *pVM)
-{
- FICL_STRING *sp = (FICL_STRING *)(pVM->ip);
- FICL_COUNT count = sp->count;
- char *cp = sp->text;
- stackPushPtr(pVM->pStack, cp);
- stackPushUNS32(pVM->pStack, count);
- cp += count + 1;
- cp = alignPtr(cp);
- pVM->ip = (IPTYPE)(void *)cp;
- return;
-}
-
-static void dotQuoteCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- dictAppendCell(dp, LVALUEtoCELL(pStringLit));
- dp->here = PTRtoCELL vmGetString(pVM, (FICL_STRING *)dp->here, '\"');
- dictAlign(dp);
- dictAppendCell(dp, LVALUEtoCELL(pType));
- return;
-}
-
-
-static void dotParen(FICL_VM *pVM)
-{
- char *pSrc = vmGetInBuf(pVM);
- char *pDest = pVM->pad;
- char ch;
-
- pSrc = skipSpace(pSrc);
-
- for (ch = *pSrc; (ch != '\0') && (ch != ')'); ch = *++pSrc)
- *pDest++ = ch;
-
- *pDest = '\0';
- if (ch == ')')
- pSrc++;
-
- vmTextOut(pVM, pVM->pad, 0);
- vmUpdateTib(pVM, pSrc);
-
- return;
-}
-
-
-/**************************************************************************
- s l i t e r a l
-** STRING
-** Interpretation: Interpretation semantics for this word are undefined.
-** Compilation: ( c-addr1 u -- )
-** Append the run-time semantics given below to the current definition.
-** Run-time: ( -- c-addr2 u )
-** Return c-addr2 u describing a string consisting of the characters
-** specified by c-addr1 u during compilation. A program shall not alter
-** the returned string.
-**************************************************************************/
-static void sLiteralCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- char *cp, *cpDest;
- UNS32 u;
- u = stackPopUNS32(pVM->pStack);
- cp = stackPopPtr(pVM->pStack);
-
- dictAppendCell(dp, LVALUEtoCELL(pStringLit));
- cpDest = (char *) dp->here;
- *cpDest++ = (char) u;
-
- for (; u > 0; --u)
- {
- *cpDest++ = *cp++;
- }
-
- *cpDest++ = 0;
- dp->here = PTRtoCELL alignPtr(cpDest);
- return;
-}
-
-
-/**************************************************************************
- s t a t e
-** Return the address of the VM's state member (must be sized the
-** same as a CELL for this reason)
-**************************************************************************/
-static void state(FICL_VM *pVM)
-{
- stackPushPtr(pVM->pStack, &pVM->state);
- return;
-}
-
-
-/**************************************************************************
- c r e a t e . . . d o e s >
-** Make a new word in the dictionary with the run-time effect of
-** a variable (push my address), but with extra space allotted
-** for use by does> .
-**************************************************************************/
-
-static void createParen(FICL_VM *pVM)
-{
- CELL *pCell = pVM->runningWord->param;
- stackPushPtr(pVM->pStack, pCell+1);
- return;
-}
-
-
-static void create(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- STRINGINFO si = vmGetWord(pVM);
-
- dictAppendWord2(dp, si, createParen, FW_DEFAULT);
- dictAllotCells(dp, 1);
- return;
-}
-
-
-static void doDoes(FICL_VM *pVM)
-{
- CELL *pCell = pVM->runningWord->param;
- IPTYPE tempIP = (IPTYPE)((*pCell).p);
- stackPushPtr(pVM->pStack, pCell+1);
- vmPushIP(pVM, tempIP);
- return;
-}
-
-
-static void doesParen(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- dp->smudge->code = doDoes;
- dp->smudge->param[0] = LVALUEtoCELL(pVM->ip);
- vmPopIP(pVM);
- return;
-}
-
-
-static void doesCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-#if FICL_WANT_LOCALS
- assert(pUnLinkParen);
- if (nLocals > 0)
- {
- FICL_DICT *pLoc = ficlGetLoc();
- dictEmpty(pLoc, pLoc->pForthWords->size);
- dictAppendCell(dp, LVALUEtoCELL(pUnLinkParen));
- }
-
- nLocals = 0;
-#endif
- IGNORE(pVM);
-
- dictAppendCell(dp, LVALUEtoCELL(pDoesParen));
- return;
-}
-
-
-/**************************************************************************
- t o b o d y
-** to-body CORE ( xt -- a-addr )
-** a-addr is the data-field address corresponding to xt. An ambiguous
-** condition exists if xt is not for a word defined via CREATE.
-**************************************************************************/
-static void toBody(FICL_VM *pVM)
-{
- FICL_WORD *pFW = stackPopPtr(pVM->pStack);
- stackPushPtr(pVM->pStack, pFW->param + 1);
- return;
-}
-
-
-/*
-** from-body ficl ( a-addr -- xt )
-** Reverse effect of >body
-*/
-static void fromBody(FICL_VM *pVM)
-{
- char *ptr = (char *) stackPopPtr(pVM->pStack) - sizeof (FICL_WORD);
- stackPushPtr(pVM->pStack, ptr);
- return;
-}
-
-
-/*
-** >name ficl ( xt -- c-addr u )
-** Push the address and length of a word's name given its address
-** xt.
-*/
-static void toName(FICL_VM *pVM)
-{
- FICL_WORD *pFW = stackPopPtr(pVM->pStack);
- stackPushPtr(pVM->pStack, pFW->name);
- stackPushUNS32(pVM->pStack, pFW->nName);
- return;
-}
-
-
-/**************************************************************************
- l b r a c k e t e t c
-**
-**************************************************************************/
-
-static void lbracketCoIm(FICL_VM *pVM)
-{
- pVM->state = INTERPRET;
- return;
-}
-
-
-static void rbracket(FICL_VM *pVM)
-{
- pVM->state = COMPILE;
- return;
-}
-
-
-/**************************************************************************
- p i c t u r e d n u m e r i c w o r d s
-**
-** less-number-sign CORE ( -- )
-** Initialize the pictured numeric output conversion process.
-** (clear the pad)
-**************************************************************************/
-static void lessNumberSign(FICL_VM *pVM)
-{
- FICL_STRING *sp = PTRtoSTRING pVM->pad;
- sp->count = 0;
- return;
-}
-
-/*
-** number-sign CORE ( ud1 -- ud2 )
-** Divide ud1 by the number in BASE giving the quotient ud2 and the remainder
-** n. (n is the least-significant digit of ud1.) Convert n to external form
-** and add the resulting character to the beginning of the pictured numeric
-** output string. An ambiguous condition exists if # executes outside of a
-** <# #> delimited number conversion.
-*/
-static void numberSign(FICL_VM *pVM)
-{
- FICL_STRING *sp = PTRtoSTRING pVM->pad;
- UNS64 u;
- UNS16 rem;
-
- u = u64Pop(pVM->pStack);
- rem = m64UMod(&u, (UNS16)(pVM->base));
- sp->text[sp->count++] = digit_to_char(rem);
- u64Push(pVM->pStack, u);
- return;
-}
-
-/*
-** number-sign-greater CORE ( xd -- c-addr u )
-** Drop xd. Make the pictured numeric output string available as a character
-** string. c-addr and u specify the resulting character string. A program
-** may replace characters within the string.
-*/
-static void numberSignGreater(FICL_VM *pVM)
-{
- FICL_STRING *sp = PTRtoSTRING pVM->pad;
- sp->text[sp->count] = '\0';
- strrev(sp->text);
- stackDrop(pVM->pStack, 2);
- stackPushPtr(pVM->pStack, sp->text);
- stackPushUNS32(pVM->pStack, sp->count);
- return;
-}
-
-/*
-** number-sign-s CORE ( ud1 -- ud2 )
-** Convert one digit of ud1 according to the rule for #. Continue conversion
-** until the quotient is zero. ud2 is zero. An ambiguous condition exists if
-** #S executes outside of a <# #> delimited number conversion.
-** TO DO: presently does not use ud1 hi cell - use it!
-*/
-static void numberSignS(FICL_VM *pVM)
-{
- FICL_STRING *sp = PTRtoSTRING pVM->pad;
- UNS64 u;
- UNS16 rem;
-
- u = u64Pop(pVM->pStack);
-
- do
- {
- rem = m64UMod(&u, (UNS16)(pVM->base));
- sp->text[sp->count++] = digit_to_char(rem);
- }
- while (u.hi || u.lo);
-
- u64Push(pVM->pStack, u);
- return;
-}
-
-/*
-** HOLD CORE ( char -- )
-** Add char to the beginning of the pictured numeric output string. An ambiguous
-** condition exists if HOLD executes outside of a <# #> delimited number conversion.
-*/
-static void hold(FICL_VM *pVM)
-{
- FICL_STRING *sp = PTRtoSTRING pVM->pad;
- int i = stackPopINT32(pVM->pStack);
- sp->text[sp->count++] = (char) i;
- return;
-}
-
-/*
-** SIGN CORE ( n -- )
-** If n is negative, add a minus sign to the beginning of the pictured
-** numeric output string. An ambiguous condition exists if SIGN
-** executes outside of a <# #> delimited number conversion.
-*/
-static void sign(FICL_VM *pVM)
-{
- FICL_STRING *sp = PTRtoSTRING pVM->pad;
- int i = stackPopINT32(pVM->pStack);
- if (i < 0)
- sp->text[sp->count++] = '-';
- return;
-}
-
-
-/**************************************************************************
- t o N u m b e r
-** to-number CORE ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 )
-** ud2 is the unsigned result of converting the characters within the
-** string specified by c-addr1 u1 into digits, using the number in BASE,
-** and adding each into ud1 after multiplying ud1 by the number in BASE.
-** Conversion continues left-to-right until a character that is not
-** convertible, including any + or -, is encountered or the string is
-** entirely converted. c-addr2 is the location of the first unconverted
-** character or the first character past the end of the string if the string
-** was entirely converted. u2 is the number of unconverted characters in the
-** string. An ambiguous condition exists if ud2 overflows during the
-** conversion.
-** TO DO: presently does not use ud1 hi cell - use it!
-**************************************************************************/
-static void toNumber(FICL_VM *pVM)
-{
- UNS32 count = stackPopUNS32(pVM->pStack);
- char *cp = (char *)stackPopPtr(pVM->pStack);
- UNS64 accum;
- UNS32 base = pVM->base;
- UNS32 ch;
- UNS32 digit;
-
- accum = u64Pop(pVM->pStack);
-
- for (ch = *cp; count > 0; ch = *++cp, count--)
- {
- if (ch < '0')
- break;
-
- digit = ch - '0';
-
- if (digit > 9)
- digit = tolower(ch) - 'a' + 10;
- /*
- ** Note: following test also catches chars between 9 and a
- ** because 'digit' is unsigned!
- */
- if (digit >= base)
- break;
-
- accum = m64Mac(accum, base, digit);
- }
-
- u64Push(pVM->pStack, accum);
- stackPushPtr (pVM->pStack, cp);
- stackPushUNS32(pVM->pStack, count);
-
- return;
-}
-
-
-
-/**************************************************************************
- q u i t & a b o r t
-** quit CORE ( -- ) ( R: i*x -- )
-** Empty the return stack, store zero in SOURCE-ID if it is present, make
-** the user input device the input source, and enter interpretation state.
-** Do not display a message. Repeat the following:
-**
-** Accept a line from the input source into the input buffer, set >IN to
-** zero, and interpret.
-** Display the implementation-defined system prompt if in
-** interpretation state, all processing has been completed, and no
-** ambiguous condition exists.
-**************************************************************************/
-
-static void quit(FICL_VM *pVM)
-{
- vmThrow(pVM, VM_QUIT);
- return;
-}
-
-
-static void ficlAbort(FICL_VM *pVM)
-{
- vmThrow(pVM, VM_ERREXIT);
- return;
-}
-
-
-/**************************************************************************
- a c c e p t
-** accept CORE ( c-addr +n1 -- +n2 )
-** Receive a string of at most +n1 characters. An ambiguous condition
-** exists if +n1 is zero or greater than 32,767. Display graphic characters
-** as they are received. A program that depends on the presence or absence
-** of non-graphic characters in the string has an environmental dependency.
-** The editing functions, if any, that the system performs in order to
-** construct the string are implementation-defined.
-**
-** (Although the standard text doesn't say so, I assume that the intent
-** of 'accept' is to store the string at the address specified on
-** the stack.)
-** Implementation: if there's more text in the TIB, use it. Otherwise
-** throw out for more text. Copy characters up to the max count into the
-** address given, and return the number of actual characters copied.
-**************************************************************************/
-static void accept(FICL_VM *pVM)
-{
- UNS32 count, len;
- char *cp;
- char *pBuf = vmGetInBuf(pVM);
-
- len = strlen(pBuf);
- if (len == 0)
- vmThrow(pVM, VM_RESTART);
- /* OK - now we have something in the text buffer - use it */
- count = stackPopUNS32(pVM->pStack);
- cp = stackPopPtr(pVM->pStack);
-
- strncpy(cp, vmGetInBuf(pVM), count);
- len = (count < len) ? count : len;
- pBuf += len;
- vmUpdateTib(pVM, pBuf);
- stackPushUNS32(pVM->pStack, len);
-
- return;
-}
-
-
-/**************************************************************************
- a l i g n
-** 6.1.0705 ALIGN CORE ( -- )
-** If the data-space pointer is not aligned, reserve enough space to
-** align it.
-**************************************************************************/
-static void align(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- IGNORE(pVM);
- dictAlign(dp);
- return;
-}
-
-
-/**************************************************************************
- a l i g n e d
-**
-**************************************************************************/
-static void aligned(FICL_VM *pVM)
-{
- void *addr = stackPopPtr(pVM->pStack);
- stackPushPtr(pVM->pStack, alignPtr(addr));
- return;
-}
-
-
-/**************************************************************************
- b e g i n & f r i e n d s
-** Indefinite loop control structures
-** A.6.1.0760 BEGIN
-** Typical use:
-** : X ... BEGIN ... test UNTIL ;
-** or
-** : X ... BEGIN ... test WHILE ... REPEAT ;
-**************************************************************************/
-static void beginCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- markBranch(dp, pVM, beginTag);
- return;
-}
-
-static void untilCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pIfParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pIfParen));
- resolveBackBranch(dp, pVM, beginTag);
- return;
-}
-
-static void whileCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pIfParen);
-
- dictAppendCell(dp, LVALUEtoCELL(pIfParen));
- markBranch(dp, pVM, whileTag);
- twoSwap(pVM);
- dictAppendUNS32(dp, 1);
- return;
-}
-
-static void repeatCoIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- assert(pBranchParen);
- dictAppendCell(dp, LVALUEtoCELL(pBranchParen));
-
- /* expect "begin" branch marker */
- resolveBackBranch(dp, pVM, beginTag);
- /* expect "while" branch marker */
- resolveForwardBranch(dp, pVM, whileTag);
- return;
-}
-
-
-/**************************************************************************
- c h a r & f r i e n d s
-** 6.1.0895 CHAR CORE ( "<spaces>name" -- char )
-** Skip leading space delimiters. Parse name delimited by a space.
-** Put the value of its first character onto the stack.
-**
-** bracket-char CORE
-** Interpretation: Interpretation semantics for this word are undefined.
-** Compilation: ( "<spaces>name" -- )
-** Skip leading space delimiters. Parse name delimited by a space.
-** Append the run-time semantics given below to the current definition.
-** Run-time: ( -- char )
-** Place char, the value of the first character of name, on the stack.
-**************************************************************************/
-static void ficlChar(FICL_VM *pVM)
-{
- STRINGINFO si = vmGetWord(pVM);
- stackPushUNS32(pVM->pStack, (UNS32)(si.cp[0]));
-
- return;
-}
-
-static void charCoIm(FICL_VM *pVM)
-{
- ficlChar(pVM);
- literalIm(pVM);
- return;
-}
-
-/**************************************************************************
- c h a r P l u s
-** char-plus CORE ( c-addr1 -- c-addr2 )
-** Add the size in address units of a character to c-addr1, giving c-addr2.
-**************************************************************************/
-static void charPlus(FICL_VM *pVM)
-{
- char *cp = stackPopPtr(pVM->pStack);
- stackPushPtr(pVM->pStack, cp + 1);
- return;
-}
-
-/**************************************************************************
- c h a r s
-** chars CORE ( n1 -- n2 )
-** n2 is the size in address units of n1 characters.
-** For most processors, this function can be a no-op. To guarantee
-** portability, we'll multiply by sizeof (char).
-**************************************************************************/
-#if defined (_M_IX86)
-#pragma warning(disable: 4127)
-#endif
-static void ficlChars(FICL_VM *pVM)
-{
- if (sizeof (char) > 1)
- {
- INT32 i = stackPopINT32(pVM->pStack);
- stackPushINT32(pVM->pStack, i * sizeof (char));
- }
- /* otherwise no-op! */
- return;
-}
-#if defined (_M_IX86)
-#pragma warning(default: 4127)
-#endif
-
-
-/**************************************************************************
- c o u n t
-** COUNT CORE ( c-addr1 -- c-addr2 u )
-** Return the character string specification for the counted string stored
-** at c-addr1. c-addr2 is the address of the first character after c-addr1.
-** u is the contents of the character at c-addr1, which is the length in
-** characters of the string at c-addr2.
-**************************************************************************/
-static void count(FICL_VM *pVM)
-{
- FICL_STRING *sp = stackPopPtr(pVM->pStack);
- stackPushPtr(pVM->pStack, sp->text);
- stackPushUNS32(pVM->pStack, sp->count);
- return;
-}
-
-/**************************************************************************
- e n v i r o n m e n t ?
-** environment-query CORE ( c-addr u -- false | i*x true )
-** c-addr is the address of a character string and u is the string's
-** character count. u may have a value in the range from zero to an
-** implementation-defined maximum which shall not be less than 31. The
-** character string should contain a keyword from 3.2.6 Environmental
-** queries or the optional word sets to be checked for correspondence
-** with an attribute of the present environment. If the system treats the
-** attribute as unknown, the returned flag is false; otherwise, the flag
-** is true and the i*x returned is of the type specified in the table for
-** the attribute queried.
-**************************************************************************/
-static void environmentQ(FICL_VM *pVM)
-{
- FICL_DICT *envp = ficlGetEnv();
- FICL_COUNT len = (FICL_COUNT)stackPopUNS32(pVM->pStack);
- char *cp = stackPopPtr(pVM->pStack);
- FICL_WORD *pFW;
- STRINGINFO si;
-
- SI_PSZ(si, cp);
- pFW = dictLookup(envp, si);
-
- if (pFW != NULL)
- {
- vmExecute(pVM, pFW);
- stackPushINT32(pVM->pStack, FICL_TRUE);
- }
- else
- {
- stackPushINT32(pVM->pStack, FICL_FALSE);
- }
-
- return;
-}
-
-/**************************************************************************
- e v a l u a t e
-** EVALUATE CORE ( i*x c-addr u -- j*x )
-** Save the current input source specification. Store minus-one (-1) in
-** SOURCE-ID if it is present. Make the string described by c-addr and u
-** both the input source and input buffer, set >IN to zero, and interpret.
-** When the parse area is empty, restore the prior input source
-** specification. Other stack effects are due to the words EVALUATEd.
-**
-** DEFICIENCY: this version does not handle errors or restarts.
-**************************************************************************/
-static void evaluate(FICL_VM *pVM)
-{
- UNS32 count = stackPopUNS32(pVM->pStack);
- char *cp = stackPopPtr(pVM->pStack);
- CELL id;
-
- IGNORE(count);
- id = pVM->sourceID;
- pVM->sourceID.i = -1;
- vmPushIP(pVM, &pInterpret);
- ficlExec(pVM, cp);
- vmPopIP(pVM);
- pVM->sourceID = id;
- return;
-}
-
-
-/**************************************************************************
- s t r i n g q u o t e
-** Intrpreting: get string delimited by a quote from the input stream,
-** copy to a scratch area, and put its count and address on the stack.
-** Compiling: compile code to push the address and count of a string
-** literal, compile the string from the input stream, and align the dict
-** pointer.
-**************************************************************************/
-static void stringQuoteIm(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- if (pVM->state == INTERPRET)
- {
- FICL_STRING *sp = (FICL_STRING *) dp->here;
- vmGetString(pVM, sp, '\"');
- stackPushPtr(pVM->pStack, sp->text);
- stackPushUNS32(pVM->pStack, sp->count);
- }
- else /* COMPILE state */
- {
- dictAppendCell(dp, LVALUEtoCELL(pStringLit));
- dp->here = PTRtoCELL vmGetString(pVM, (FICL_STRING *)dp->here, '\"');
- dictAlign(dp);
- }
-
- return;
-}
-
-/**************************************************************************
- t y p e
-** Pop count and char address from stack and print the designated string.
-**************************************************************************/
-static void type(FICL_VM *pVM)
-{
- UNS32 count = stackPopUNS32(pVM->pStack);
- char *cp = stackPopPtr(pVM->pStack);
-
- /*
- ** Since we don't have an output primitive for a counted string
- ** (oops), make sure the string is null terminated. If not, copy
- ** and terminate it.
- */
- /* XXX Uses free space on top of dictionary. Is it guaranteed
- * XXX to always fit? (abial)
- */
- if (cp[count] != '\0')
- {
- char *pDest = (char *)ficlGetDict()->here;
- if (cp != pDest)
- strncpy(pDest, cp, count);
-
- pDest[count] = '\0';
- cp = pDest;
- }
-
- vmTextOut(pVM, cp, 0);
- return;
-}
-
-/**************************************************************************
- w o r d
-** word CORE ( char "<chars>ccc<char>" -- c-addr )
-** Skip leading delimiters. Parse characters ccc delimited by char. An
-** ambiguous condition exists if the length of the parsed string is greater
-** than the implementation-defined length of a counted string.
-**
-** c-addr is the address of a transient region containing the parsed word
-** as a counted string. If the parse area was empty or contained no
-** characters other than the delimiter, the resulting string has a zero
-** length. A space, not included in the length, follows the string. A
-** program may replace characters within the string.
-** NOTE! Ficl also NULL-terminates the dest string.
-**************************************************************************/
-static void ficlWord(FICL_VM *pVM)
-{
- FICL_STRING *sp = (FICL_STRING *)pVM->pad;
- char delim = (char)stackPopINT32(pVM->pStack);
- STRINGINFO si;
-
- si = vmParseString(pVM, delim);
-
- if (SI_COUNT(si) > nPAD-1)
- SI_SETLEN(si, nPAD-1);
-
- sp->count = (FICL_COUNT)SI_COUNT(si);
- strncpy(sp->text, SI_PTR(si), SI_COUNT(si));
- strcat(sp->text, " ");
-
- stackPushPtr(pVM->pStack, sp);
- return;
-}
-
-
-/**************************************************************************
- p a r s e - w o r d
-** ficl PARSE-WORD ( <spaces>name -- c-addr u )
-** Skip leading spaces and parse name delimited by a space. c-addr is the
-** address within the input buffer and u is the length of the selected
-** string. If the parse area is empty, the resulting string has a zero length.
-**************************************************************************/
-static void parseNoCopy(FICL_VM *pVM)
-{
- STRINGINFO si = vmGetWord0(pVM);
- stackPushPtr(pVM->pStack, SI_PTR(si));
- stackPushUNS32(pVM->pStack, SI_COUNT(si));
- return;
-}
-
-
-/**************************************************************************
- p a r s e
-** CORE EXT ( char "ccc<char>" -- c-addr u )
-** Parse ccc delimited by the delimiter char.
-** c-addr is the address (within the input buffer) and u is the length of
-** the parsed string. If the parse area was empty, the resulting string has
-** a zero length.
-** NOTE! PARSE differs from WORD: it does not skip leading delimiters.
-**************************************************************************/
-static void parse(FICL_VM *pVM)
-{
- char *pSrc = vmGetInBuf(pVM);
- char *cp;
- UNS32 count;
- char delim = (char)stackPopINT32(pVM->pStack);
-
- cp = pSrc; /* mark start of text */
-
- while ((*pSrc != delim) && (*pSrc != '\0'))
- pSrc++; /* find next delimiter or end */
-
- count = pSrc - cp; /* set length of result */
-
- if (*pSrc == delim) /* gobble trailing delimiter */
- pSrc++;
-
- vmUpdateTib(pVM, pSrc);
- stackPushPtr(pVM->pStack, cp);
- stackPushUNS32(pVM->pStack, count);
- return;
-}
-
-
-/**************************************************************************
- f i l l
-** CORE ( c-addr u char -- )
-** If u is greater than zero, store char in each of u consecutive
-** characters of memory beginning at c-addr.
-**************************************************************************/
-static void fill(FICL_VM *pVM)
-{
- char ch = (char)stackPopINT32(pVM->pStack);
- UNS32 u = stackPopUNS32(pVM->pStack);
- char *cp = (char *)stackPopPtr(pVM->pStack);
-
- while (u > 0)
- {
- *cp++ = ch;
- u--;
- }
-
- return;
-}
-
-
-/**************************************************************************
- f i n d
-** FIND CORE ( c-addr -- c-addr 0 | xt 1 | xt -1 )
-** Find the definition named in the counted string at c-addr. If the
-** definition is not found, return c-addr and zero. If the definition is
-** found, return its execution token xt. If the definition is immediate,
-** also return one (1), otherwise also return minus-one (-1). For a given
-** string, the values returned by FIND while compiling may differ from
-** those returned while not compiling.
-**************************************************************************/
-static void find(FICL_VM *pVM)
-{
- FICL_STRING *sp = stackPopPtr(pVM->pStack);
- FICL_WORD *pFW;
- STRINGINFO si;
-
- SI_PFS(si, sp);
- pFW = dictLookup(ficlGetDict(), si);
- if (pFW)
- {
- stackPushPtr(pVM->pStack, pFW);
- stackPushINT32(pVM->pStack, (wordIsImmediate(pFW) ? 1 : -1));
- }
- else
- {
- stackPushPtr(pVM->pStack, sp);
- stackPushUNS32(pVM->pStack, 0);
- }
- return;
-}
-
-
-/**************************************************************************
- f m S l a s h M o d
-** f-m-slash-mod CORE ( d1 n1 -- n2 n3 )
-** Divide d1 by n1, giving the floored quotient n3 and the remainder n2.
-** Input and output stack arguments are signed. An ambiguous condition
-** exists if n1 is zero or if the quotient lies outside the range of a
-** single-cell signed integer.
-**************************************************************************/
-static void fmSlashMod(FICL_VM *pVM)
-{
- INT64 d1;
- INT32 n1;
- INTQR qr;
-
- n1 = stackPopINT32(pVM->pStack);
- d1 = i64Pop(pVM->pStack);
- qr = m64FlooredDivI(d1, n1);
- stackPushINT32(pVM->pStack, qr.rem);
- stackPushINT32(pVM->pStack, qr.quot);
- return;
-}
-
-
-/**************************************************************************
- s m S l a s h R e m
-** s-m-slash-rem CORE ( d1 n1 -- n2 n3 )
-** Divide d1 by n1, giving the symmetric quotient n3 and the remainder n2.
-** Input and output stack arguments are signed. An ambiguous condition
-** exists if n1 is zero or if the quotient lies outside the range of a
-** single-cell signed integer.
-**************************************************************************/
-static void smSlashRem(FICL_VM *pVM)
-{
- INT64 d1;
- INT32 n1;
- INTQR qr;
-
- n1 = stackPopINT32(pVM->pStack);
- d1 = i64Pop(pVM->pStack);
- qr = m64SymmetricDivI(d1, n1);
- stackPushINT32(pVM->pStack, qr.rem);
- stackPushINT32(pVM->pStack, qr.quot);
- return;
-}
-
-
-static void ficlMod(FICL_VM *pVM)
-{
- INT64 d1;
- INT32 n1;
- INTQR qr;
-
- n1 = stackPopINT32(pVM->pStack);
- d1.lo = stackPopINT32(pVM->pStack);
- i64Extend(d1);
- qr = m64SymmetricDivI(d1, n1);
- stackPushINT32(pVM->pStack, qr.rem);
- return;
-}
-
-
-/**************************************************************************
- u m S l a s h M o d
-** u-m-slash-mod CORE ( ud u1 -- u2 u3 )
-** Divide ud by u1, giving the quotient u3 and the remainder u2.
-** All values and arithmetic are unsigned. An ambiguous condition
-** exists if u1 is zero or if the quotient lies outside the range of a
-** single-cell unsigned integer.
-*************************************************************************/
-static void umSlashMod(FICL_VM *pVM)
-{
- UNS64 ud;
- UNS32 u1;
- UNSQR qr;
-
- u1 = stackPopUNS32(pVM->pStack);
- ud = u64Pop(pVM->pStack);
- qr = ficlLongDiv(ud, u1);
- stackPushUNS32(pVM->pStack, qr.rem);
- stackPushUNS32(pVM->pStack, qr.quot);
- return;
-}
-
-
-/**************************************************************************
- l s h i f t
-** l-shift CORE ( x1 u -- x2 )
-** Perform a logical left shift of u bit-places on x1, giving x2.
-** Put zeroes into the least significant bits vacated by the shift.
-** An ambiguous condition exists if u is greater than or equal to the
-** number of bits in a cell.
-**
-** r-shift CORE ( x1 u -- x2 )
-** Perform a logical right shift of u bit-places on x1, giving x2.
-** Put zeroes into the most significant bits vacated by the shift. An
-** ambiguous condition exists if u is greater than or equal to the
-** number of bits in a cell.
-**************************************************************************/
-static void lshift(FICL_VM *pVM)
-{
- UNS32 nBits = stackPopUNS32(pVM->pStack);
- UNS32 x1 = stackPopUNS32(pVM->pStack);
-
- stackPushUNS32(pVM->pStack, x1 << nBits);
- return;
-}
-
-
-static void rshift(FICL_VM *pVM)
-{
- UNS32 nBits = stackPopUNS32(pVM->pStack);
- UNS32 x1 = stackPopUNS32(pVM->pStack);
-
- stackPushUNS32(pVM->pStack, x1 >> nBits);
- return;
-}
-
-
-/**************************************************************************
- m S t a r
-** m-star CORE ( n1 n2 -- d )
-** d is the signed product of n1 times n2.
-**************************************************************************/
-static void mStar(FICL_VM *pVM)
-{
- INT32 n2 = stackPopINT32(pVM->pStack);
- INT32 n1 = stackPopINT32(pVM->pStack);
- INT64 d;
-
- d = m64MulI(n1, n2);
- i64Push(pVM->pStack, d);
- return;
-}
-
-
-static void umStar(FICL_VM *pVM)
-{
- UNS32 u2 = stackPopUNS32(pVM->pStack);
- UNS32 u1 = stackPopUNS32(pVM->pStack);
- UNS64 ud;
-
- ud = ficlLongMul(u1, u2);
- u64Push(pVM->pStack, ud);
- return;
-}
-
-
-/**************************************************************************
- m a x & m i n
-**
-**************************************************************************/
-static void ficlMax(FICL_VM *pVM)
-{
- INT32 n2 = stackPopINT32(pVM->pStack);
- INT32 n1 = stackPopINT32(pVM->pStack);
-
- stackPushINT32(pVM->pStack, (n1 > n2) ? n1 : n2);
- return;
-}
-
-static void ficlMin(FICL_VM *pVM)
-{
- INT32 n2 = stackPopINT32(pVM->pStack);
- INT32 n1 = stackPopINT32(pVM->pStack);
-
- stackPushINT32(pVM->pStack, (n1 < n2) ? n1 : n2);
- return;
-}
-
-
-/**************************************************************************
- m o v e
-** CORE ( addr1 addr2 u -- )
-** If u is greater than zero, copy the contents of u consecutive address
-** units at addr1 to the u consecutive address units at addr2. After MOVE
-** completes, the u consecutive address units at addr2 contain exactly
-** what the u consecutive address units at addr1 contained before the move.
-** NOTE! This implementation assumes that a char is the same size as
-** an address unit.
-**************************************************************************/
-static void move(FICL_VM *pVM)
-{
- UNS32 u = stackPopUNS32(pVM->pStack);
- char *addr2 = stackPopPtr(pVM->pStack);
- char *addr1 = stackPopPtr(pVM->pStack);
-
- if (u == 0)
- return;
- /*
- ** Do the copy carefully, so as to be
- ** correct even if the two ranges overlap
- */
- if (addr1 >= addr2)
- {
- for (; u > 0; u--)
- *addr2++ = *addr1++;
- }
- else
- {
- addr2 += u-1;
- addr1 += u-1;
- for (; u > 0; u--)
- *addr2-- = *addr1--;
- }
-
- return;
-}
-
-
-/**************************************************************************
- r e c u r s e
-**
-**************************************************************************/
-static void recurseCoIm(FICL_VM *pVM)
-{
- FICL_DICT *pDict = ficlGetDict();
-
- IGNORE(pVM);
- dictAppendCell(pDict, LVALUEtoCELL(pDict->smudge));
- return;
-}
-
-
-/**************************************************************************
- s t o d
-** s-to-d CORE ( n -- d )
-** Convert the number n to the double-cell number d with the same
-** numerical value.
-**************************************************************************/
-static void sToD(FICL_VM *pVM)
-{
- INT32 s = stackPopINT32(pVM->pStack);
-
- /* sign extend to 64 bits.. */
- stackPushINT32(pVM->pStack, s);
- stackPushINT32(pVM->pStack, (s < 0) ? -1 : 0);
- return;
-}
-
-
-/**************************************************************************
- s o u r c e
-** CORE ( -- c-addr u )
-** c-addr is the address of, and u is the number of characters in, the
-** input buffer.
-**************************************************************************/
-static void source(FICL_VM *pVM)
-{
- stackPushPtr(pVM->pStack, pVM->tib.cp);
- stackPushINT32(pVM->pStack, strlen(pVM->tib.cp));
- return;
-}
-
-
-/**************************************************************************
- v e r s i o n
-** non-standard...
-**************************************************************************/
-static void ficlVersion(FICL_VM *pVM)
-{
- vmTextOut(pVM, "ficl Version " FICL_VER, 1);
- return;
-}
-
-
-/**************************************************************************
- t o I n
-** to-in CORE
-**************************************************************************/
-static void toIn(FICL_VM *pVM)
-{
- stackPushPtr(pVM->pStack, &pVM->tib.index);
- return;
-}
-
-
-/**************************************************************************
- d e f i n i t i o n s
-** SEARCH ( -- )
-** Make the compilation word list the same as the first word list in the
-** search order. Specifies that the names of subsequent definitions will
-** be placed in the compilation word list. Subsequent changes in the search
-** order will not affect the compilation word list.
-**************************************************************************/
-static void definitions(FICL_VM *pVM)
-{
- FICL_DICT *pDict = ficlGetDict();
-
- assert(pDict);
- if (pDict->nLists < 1)
- {
- vmThrowErr(pVM, "DEFINITIONS error - empty search order");
- }
-
- pDict->pCompile = pDict->pSearch[pDict->nLists-1];
- return;
-}
-
-
-/**************************************************************************
- f o r t h - w o r d l i s t
-** SEARCH ( -- wid )
-** Return wid, the identifier of the word list that includes all standard
-** words provided by the implementation. This word list is initially the
-** compilation word list and is part of the initial search order.
-**************************************************************************/
-static void forthWordlist(FICL_VM *pVM)
-{
- FICL_HASH *pHash = ficlGetDict()->pForthWords;
- stackPushPtr(pVM->pStack, pHash);
- return;
-}
-
-
-/**************************************************************************
- g e t - c u r r e n t
-** SEARCH ( -- wid )
-** Return wid, the identifier of the compilation word list.
-**************************************************************************/
-static void getCurrent(FICL_VM *pVM)
-{
- ficlLockDictionary(TRUE);
- stackPushPtr(pVM->pStack, ficlGetDict()->pCompile);
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- g e t - o r d e r
-** SEARCH ( -- widn ... wid1 n )
-** Returns the number of word lists n in the search order and the word list
-** identifiers widn ... wid1 identifying these word lists. wid1 identifies
-** the word list that is searched first, and widn the word list that is
-** searched last. The search order is unaffected.
-**************************************************************************/
-static void getOrder(FICL_VM *pVM)
-{
- FICL_DICT *pDict = ficlGetDict();
- int nLists = pDict->nLists;
- int i;
-
- ficlLockDictionary(TRUE);
- for (i = 0; i < nLists; i++)
- {
- stackPushPtr(pVM->pStack, pDict->pSearch[i]);
- }
-
- stackPushUNS32(pVM->pStack, nLists);
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- s e a r c h - w o r d l i s t
-** SEARCH ( c-addr u wid -- 0 | xt 1 | xt -1 )
-** Find the definition identified by the string c-addr u in the word list
-** identified by wid. If the definition is not found, return zero. If the
-** definition is found, return its execution token xt and one (1) if the
-** definition is immediate, minus-one (-1) otherwise.
-**************************************************************************/
-static void searchWordlist(FICL_VM *pVM)
-{
- STRINGINFO si;
- UNS16 hashCode;
- FICL_WORD *pFW;
- FICL_HASH *pHash = stackPopPtr(pVM->pStack);
-
- si.count = (FICL_COUNT)stackPopUNS32(pVM->pStack);
- si.cp = stackPopPtr(pVM->pStack);
- hashCode = hashHashCode(si);
-
- ficlLockDictionary(TRUE);
- pFW = hashLookup(pHash, si, hashCode);
- ficlLockDictionary(FALSE);
-
- if (pFW)
- {
- stackPushPtr(pVM->pStack, pFW);
- stackPushINT32(pVM->pStack, (wordIsImmediate(pFW) ? 1 : -1));
- }
- else
- {
- stackPushUNS32(pVM->pStack, 0);
- }
-
- return;
-}
-
-
-/**************************************************************************
- s e t - c u r r e n t
-** SEARCH ( wid -- )
-** Set the compilation word list to the word list identified by wid.
-**************************************************************************/
-static void setCurrent(FICL_VM *pVM)
-{
- FICL_HASH *pHash = stackPopPtr(pVM->pStack);
- FICL_DICT *pDict = ficlGetDict();
- ficlLockDictionary(TRUE);
- pDict->pCompile = pHash;
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- s e t - o r d e r
-** SEARCH ( widn ... wid1 n -- )
-** Set the search order to the word lists identified by widn ... wid1.
-** Subsequently, word list wid1 will be searched first, and word list
-** widn searched last. If n is zero, empty the search order. If n is minus
-** one, set the search order to the implementation-defined minimum
-** search order. The minimum search order shall include the words
-** FORTH-WORDLIST and SET-ORDER. A system shall allow n to
-** be at least eight.
-**************************************************************************/
-static void setOrder(FICL_VM *pVM)
-{
- int i;
- int nLists = stackPopINT32(pVM->pStack);
- FICL_DICT *dp = ficlGetDict();
-
- if (nLists > FICL_DEFAULT_VOCS)
- {
- vmThrowErr(pVM, "set-order error: list would be too large");
- }
-
- ficlLockDictionary(TRUE);
-
- if (nLists >= 0)
- {
- dp->nLists = nLists;
- for (i = nLists-1; i >= 0; --i)
- {
- dp->pSearch[i] = stackPopPtr(pVM->pStack);
- }
- }
- else
- {
- dictResetSearchOrder(dp);
- }
-
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- w o r d l i s t
-** SEARCH ( -- wid )
-** Create a new empty word list, returning its word list identifier wid.
-** The new word list may be returned from a pool of preallocated word
-** lists or may be dynamically allocated in data space. A system shall
-** allow the creation of at least 8 new word lists in addition to any
-** provided as part of the system.
-** Notes:
-** 1. ficl creates a new single-list hash in the dictionary and returns
-** its address.
-** 2. ficl-wordlist takes an arg off the stack indicating the number of
-** hash entries in the wordlist. Ficl 2.02 and later define WORDLIST as
-** : wordlist 1 ficl-wordlist ;
-**************************************************************************/
-static void wordlist(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- FICL_HASH *pHash;
- UNS32 nBuckets;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- nBuckets = stackPopUNS32(pVM->pStack);
-
- dictAlign(dp);
- pHash = (FICL_HASH *)dp->here;
- dictAllot(dp, sizeof (FICL_HASH)
- + (nBuckets-1) * sizeof (FICL_WORD *));
-
- pHash->size = nBuckets;
- hashReset(pHash);
-
- stackPushPtr(pVM->pStack, pHash);
- return;
-}
-
-
-/**************************************************************************
- S E A R C H >
-** ficl ( -- wid )
-** Pop wid off the search order. Error if the search order is empty
-**************************************************************************/
-static void searchPop(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- int nLists;
-
- ficlLockDictionary(TRUE);
- nLists = dp->nLists;
- if (nLists == 0)
- {
- vmThrowErr(pVM, "search> error: empty search order");
- }
- stackPushPtr(pVM->pStack, dp->pSearch[--dp->nLists]);
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- > S E A R C H
-** ficl ( wid -- )
-** Push wid onto the search order. Error if the search order is full.
-**************************************************************************/
-static void searchPush(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
-
- ficlLockDictionary(TRUE);
- if (dp->nLists > FICL_DEFAULT_VOCS)
- {
- vmThrowErr(pVM, ">search error: search order overflow");
- }
- dp->pSearch[dp->nLists++] = stackPopPtr(pVM->pStack);
- ficlLockDictionary(FALSE);
- return;
-}
-
-
-/**************************************************************************
- c o l o n N o N a m e
-** CORE EXT ( C: -- colon-sys ) ( S: -- xt )
-** Create an unnamed colon definition and push its address.
-** Change state to compile.
-**************************************************************************/
-static void colonNoName(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- FICL_WORD *pFW;
- STRINGINFO si;
-
- SI_SETLEN(si, 0);
- SI_SETPTR(si, NULL);
-
- pVM->state = COMPILE;
- pFW = dictAppendWord2(dp, si, colonParen, FW_DEFAULT | FW_SMUDGE);
- stackPushPtr(pVM->pStack, pFW);
- markControlTag(pVM, colonTag);
- return;
-}
-
-
-/**************************************************************************
- u s e r V a r i a b l e
-** user ( u -- ) "<spaces>name"
-** Get a name from the input stream and create a user variable
-** with the name and the index supplied. The run-time effect
-** of a user variable is to push the address of the indexed cell
-** in the running vm's user array.
-**
-** User variables are vm local cells. Each vm has an array of
-** FICL_USER_CELLS of them when FICL_WANT_USER is nonzero.
-** Ficl's user facility is implemented with two primitives,
-** "user" and "(user)", a variable ("nUser") (in softcore.c) that
-** holds the index of the next free user cell, and a redefinition
-** (also in softcore) of "user" that defines a user word and increments
-** nUser.
-**************************************************************************/
-#if FICL_WANT_USER
-static void userParen(FICL_VM *pVM)
-{
- INT32 i = pVM->runningWord->param[0].i;
- stackPushPtr(pVM->pStack, &pVM->user[i]);
- return;
-}
-
-
-static void userVariable(FICL_VM *pVM)
-{
- FICL_DICT *dp = ficlGetDict();
- STRINGINFO si = vmGetWord(pVM);
- CELL c;
-
- c = stackPop(pVM->pStack);
- if (c.i >= FICL_USER_CELLS)
- {
- vmThrowErr(pVM, "Error - out of user space");
- }
-
- dictAppendWord2(dp, si, userParen, FW_DEFAULT);
- dictAppendCell(dp, c);
- return;
-}
-#endif
-
-
-/**************************************************************************
- t o V a l u e
-** CORE EXT
-** Interpretation: ( x "<spaces>name" -- )
-** Skip leading spaces and parse name delimited by a space. Store x in
-** name. An ambiguous condition exists if name was not defined by VALUE.
-** NOTE: In ficl, VALUE is an alias of CONSTANT
-**************************************************************************/
-static void toValue(FICL_VM *pVM)
-{
- STRINGINFO si = vmGetWord(pVM);
- FICL_DICT *dp = ficlGetDict();
- FICL_WORD *pFW;
-
-#if FICL_WANT_LOCALS
- FICL_DICT *pLoc = ficlGetLoc();
- if ((nLocals > 0) && (pVM->state == COMPILE))
- {
- pFW = dictLookup(pLoc, si);
- if (pFW)
- {
- dictAppendCell(dp, LVALUEtoCELL(pToLocalParen));
- dictAppendCell(dp, LVALUEtoCELL(pFW->param[0]));
- return;
- }
- }
-#endif
-
- assert(pStore);
-
- pFW = dictLookup(dp, si);
- if (!pFW)
- {
- int i = SI_COUNT(si);
- vmThrowErr(pVM, "%.*s not found", i, SI_PTR(si));
- }
-
- if (pVM->state == INTERPRET)
- pFW->param[0] = stackPop(pVM->pStack);
- else /* compile code to store to word's param */
- {
- stackPushPtr(pVM->pStack, &pFW->param[0]);
- literalIm(pVM);
- dictAppendCell(dp, LVALUEtoCELL(pStore));
- }
- return;
-}
-
-
-#if FICL_WANT_LOCALS
-/**************************************************************************
- l i n k P a r e n
-** ( -- )
-** Link a frame on the return stack, reserving nCells of space for
-** locals - the value of nCells is the next cell in the instruction
-** stream.
-**************************************************************************/
-static void linkParen(FICL_VM *pVM)
-{
- INT32 nLink = *(INT32 *)(pVM->ip);
- vmBranchRelative(pVM, 1);
- stackLink(pVM->rStack, nLink);
- return;
-}
-
-
-static void unlinkParen(FICL_VM *pVM)
-{
- stackUnlink(pVM->rStack);
- return;
-}
-
-
-/**************************************************************************
- d o L o c a l I m
-** Immediate - cfa of a local while compiling - when executed, compiles
-** code to fetch the value of a local given the local's index in the
-** word's pfa
-**************************************************************************/
-static void getLocalParen(FICL_VM *pVM)
-{
- INT32 nLocal = *(INT32 *)(pVM->ip++);
- stackPush(pVM->pStack, pVM->rStack->pFrame[nLocal]);
- return;
-}
-
-
-static void toLocalParen(FICL_VM *pVM)
-{
- INT32 nLocal = *(INT32 *)(pVM->ip++);
- pVM->rStack->pFrame[nLocal] = stackPop(pVM->pStack);
- return;
-}
-
-
-static void getLocal0(FICL_VM *pVM)
-{
- stackPush(pVM->pStack, pVM->rStack->pFrame[0]);
- return;
-}
-
-
-static void toLocal0(FICL_VM *pVM)
-{
- pVM->rStack->pFrame[0] = stackPop(pVM->pStack);
- return;
-}
-
-
-static void getLocal1(FICL_VM *pVM)
-{
- stackPush(pVM->pStack, pVM->rStack->pFrame[1]);
- return;
-}
-
-
-static void toLocal1(FICL_VM *pVM)
-{
- pVM->rStack->pFrame[1] = stackPop(pVM->pStack);
- return;
-}
-
-
-/*
-** Each local is recorded in a private locals dictionary as a
-** word that does doLocalIm at runtime. DoLocalIm compiles code
-** into the client definition to fetch the value of the
-** corresponding local variable from the return stack.
-** The private dictionary gets initialized at the end of each block
-** that uses locals (in ; and does> for example).
-*/
-static void doLocalIm(FICL_VM *pVM)
-{
- FICL_DICT *pDict = ficlGetDict();
- int nLocal = pVM->runningWord->param[0].i;
-
- if (pVM->state == INTERPRET)
- {
- stackPush(pVM->pStack, pVM->rStack->pFrame[nLocal]);
- }
- else
- {
-
- if (nLocal == 0)
- {
- dictAppendCell(pDict, LVALUEtoCELL(pGetLocal0));
- }
- else if (nLocal == 1)
- {
- dictAppendCell(pDict, LVALUEtoCELL(pGetLocal1));
- }
- else
- {
- dictAppendCell(pDict, LVALUEtoCELL(pGetLocalParen));
- dictAppendCell(pDict, LVALUEtoCELL(nLocal));
- }
- }
- return;
-}
-
-
-/**************************************************************************
- l o c a l P a r e n
-** paren-local-paren LOCAL
-** Interpretation: Interpretation semantics for this word are undefined.
-** Execution: ( c-addr u -- )
-** When executed during compilation, (LOCAL) passes a message to the
-** system that has one of two meanings. If u is non-zero,
-** the message identifies a new local whose definition name is given by
-** the string of characters identified by c-addr u. If u is zero,
-** the message is last local and c-addr has no significance.
-**
-** The result of executing (LOCAL) during compilation of a definition is
-** to create a set of named local identifiers, each of which is
-** a definition name, that only have execution semantics within the scope
-** of that definition's source.
-**
-** local Execution: ( -- x )
-**
-** Push the local's value, x, onto the stack. The local's value is
-** initialized as described in 13.3.3 Processing locals and may be
-** changed by preceding the local's name with TO. An ambiguous condition
-** exists when local is executed while in interpretation state.
-**************************************************************************/
-static void localParen(FICL_VM *pVM)
-{
- static CELL *pMark = NULL;
- FICL_DICT *pDict = ficlGetDict();
- STRINGINFO si;
- SI_SETLEN(si, stackPopUNS32(pVM->pStack));
- SI_SETPTR(si, (char *)stackPopPtr(pVM->pStack));
-
- if (SI_COUNT(si) > 0)
- { /* add a local to the dict and update nLocals */
- FICL_DICT *pLoc = ficlGetLoc();
- if (nLocals >= FICL_MAX_LOCALS)
- {
- vmThrowErr(pVM, "Error: out of local space");
- }
-
- dictAppendWord2(pLoc, si, doLocalIm, FW_COMPIMMED);
- dictAppendCell(pLoc, LVALUEtoCELL(nLocals));
-
- if (nLocals == 0)
- { /* compile code to create a local stack frame */
- dictAppendCell(pDict, LVALUEtoCELL(pLinkParen));
- /* save location in dictionary for #locals */
- pMark = pDict->here;
- dictAppendCell(pDict, LVALUEtoCELL(nLocals));
- /* compile code to initialize first local */
- dictAppendCell(pDict, LVALUEtoCELL(pToLocal0));
- }
- else if (nLocals == 1)
- {
- dictAppendCell(pDict, LVALUEtoCELL(pToLocal1));
- }
- else
- {
- dictAppendCell(pDict, LVALUEtoCELL(pToLocalParen));
- dictAppendCell(pDict, LVALUEtoCELL(nLocals));
- }
-
- nLocals++;
- }
- else if (nLocals > 0)
- { /* write nLocals to (link) param area in dictionary */
- *(INT32 *)pMark = nLocals;
- }
-
- return;
-}
-
-
-#endif
-/**************************************************************************
- setParentWid
-** FICL
-** setparentwid ( parent-wid wid -- )
-** Set WID's link field to the parent-wid. search-wordlist will
-** iterate through all the links when finding words in the child wid.
-**************************************************************************/
-static void setParentWid(FICL_VM *pVM)
-{
- FICL_HASH *parent, *child;
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- child = (FICL_HASH *)stackPopPtr(pVM->pStack);
- parent = (FICL_HASH *)stackPopPtr(pVM->pStack);
-
- child->link = parent;
- return;
-}
-
-
-/**************************************************************************
- s e e
-** TOOLS ( "<spaces>name" -- )
-** Display a human-readable representation of the named word's definition.
-** The source of the representation (object-code decompilation, source
-** block, etc.) and the particular form of the display is implementation
-** defined.
-** NOTE: these funcs come late in the file because they reference all
-** of the word-builder funcs without declaring them again. Call me lazy.
-**************************************************************************/
-/*
-** isAFiclWord
-** Vet a candidate pointer carefully to make sure
-** it's not some chunk o' inline data...
-** It has to have a name, and it has to look
-** like it's in the dictionary address range.
-** NOTE: this excludes :noname words!
-*/
-static int isAFiclWord(FICL_WORD *pFW)
-{
- void *pv = (void *)pFW;
- FICL_DICT *pd = ficlGetDict();
-
- if (!dictIncludes(pd, pFW))
- return 0;
-
- if (!dictIncludes(pd, pFW->name))
- return 0;
-
- return ((pFW->nName > 0) && (pFW->name[pFW->nName] == '\0'));
-}
-
-/*
-** seeColon (for proctologists only)
-** Walks a colon definition, decompiling
-** on the fly. Knows about primitive control structures.
-*/
-static void seeColon(FICL_VM *pVM, CELL *pc)
-{
- for (; pc->p != pSemiParen; pc++)
- {
- FICL_WORD *pFW = (FICL_WORD *)(pc->p);
-
- if (isAFiclWord(pFW))
- {
- if (pFW->code == literalParen)
- {
- CELL v = *++pc;
- if (isAFiclWord(v.p))
- {
- FICL_WORD *pLit = (FICL_WORD *)v.p;
- sprintf(pVM->pad, " literal %.*s (%#lx)",
- pLit->nName, pLit->name, v.u);
- }
- else
- sprintf(pVM->pad, " literal %ld (%#lx)", v.i, v.u);
- }
- else if (pFW->code == stringLit)
- {
- FICL_STRING *sp = (FICL_STRING *)(void *)++pc;
- pc = (CELL *)alignPtr(sp->text + sp->count + 1) - 1;
- sprintf(pVM->pad, " s\" %.*s\"", sp->count, sp->text);
- }
- else if (pFW->code == ifParen)
- {
- CELL c = *++pc;
- if (c.i > 0)
- sprintf(pVM->pad, " if / while (branch rel %ld)", c.i);
- else
- sprintf(pVM->pad, " until (branch rel %ld)", c.i);
- }
- else if (pFW->code == branchParen)
- {
- CELL c = *++pc;
- if (c.i > 0)
- sprintf(pVM->pad, " else (branch rel %ld)", c.i);
- else
- sprintf(pVM->pad, " repeat (branch rel %ld)", c.i);
- }
- else if (pFW->code == qDoParen)
- {
- CELL c = *++pc;
- sprintf(pVM->pad, " ?do (leave abs %#lx)", c.u);
- }
- else if (pFW->code == doParen)
- {
- CELL c = *++pc;
- sprintf(pVM->pad, " do (leave abs %#lx)", c.u);
- }
- else if (pFW->code == loopParen)
- {
- CELL c = *++pc;
- sprintf(pVM->pad, " loop (branch rel %#ld)", c.i);
- }
- else if (pFW->code == plusLoopParen)
- {
- CELL c = *++pc;
- sprintf(pVM->pad, " +loop (branch rel %#ld)", c.i);
- }
- else /* default: print word's name */
- {
- sprintf(pVM->pad, " %.*s", pFW->nName, pFW->name);
- }
-
- vmTextOut(pVM, pVM->pad, 1);
- }
- else /* probably not a word - punt and print value */
- {
- sprintf(pVM->pad, " %ld (%#lx)", pc->i, pc->u);
- vmTextOut(pVM, pVM->pad, 1);
- }
- }
-
- vmTextOut(pVM, ";", 1);
-}
-
-/*
-** Here's the outer part of the decompiler. It's
-** just a big nested conditional that checks the
-** CFA of the word to decompile for each kind of
-** known word-builder code, and tries to do
-** something appropriate. If the CFA is not recognized,
-** just indicate that it is a primitive.
-*/
-static void see(FICL_VM *pVM)
-{
- FICL_DICT *pd = ficlGetDict();
- FICL_WORD *pFW;
-
- tick(pVM);
- pFW = (FICL_WORD *)stackPopPtr(pVM->pStack);
-
- if (pFW->code == colonParen)
- {
- sprintf(pVM->pad, ": %.*s", pFW->nName, pFW->name);
- vmTextOut(pVM, pVM->pad, 1);
- seeColon(pVM, pFW->param);
- }
- else if (pFW->code == doDoes)
- {
- vmTextOut(pVM, "does>", 1);
- seeColon(pVM, (CELL *)pFW->param->p);
- }
- else if (pFW->code == createParen)
- {
- vmTextOut(pVM, "create", 1);
- }
- else if (pFW->code == variableParen)
- {
- sprintf(pVM->pad, "variable = %ld (%#lx)",
- pFW->param->i, pFW->param->u);
- vmTextOut(pVM, pVM->pad, 1);
- }
- else if (pFW->code == userParen)
- {
- sprintf(pVM->pad, "user variable %ld (%#lx)",
- pFW->param->i, pFW->param->u);
- vmTextOut(pVM, pVM->pad, 1);
- }
- else if (pFW->code == constantParen)
- {
- sprintf(pVM->pad, "constant = %ld (%#lx)",
- pFW->param->i, pFW->param->u);
- vmTextOut(pVM, pVM->pad, 1);
- }
- else
- {
- vmTextOut(pVM, "primitive", 1);
- }
-
- if (pFW->flags & FW_IMMEDIATE)
- {
- vmTextOut(pVM, "immediate", 1);
- }
-
- return;
-}
-
-
-/**************************************************************************
- c o m p a r e
-** STRING ( c-addr1 u1 c-addr2 u2 -- n )
-** Compare the string specified by c-addr1 u1 to the string specified by
-** c-addr2 u2. The strings are compared, beginning at the given addresses,
-** character by character, up to the length of the shorter string or until a
-** difference is found. If the two strings are identical, n is zero. If the two
-** strings are identical up to the length of the shorter string, n is minus-one
-** (-1) if u1 is less than u2 and one (1) otherwise. If the two strings are not
-** identical up to the length of the shorter string, n is minus-one (-1) if the
-** first non-matching character in the string specified by c-addr1 u1 has a
-** lesser numeric value than the corresponding character in the string specified
-** by c-addr2 u2 and one (1) otherwise.
-**************************************************************************/
-static void compareString(FICL_VM *pVM)
-{
- char *cp1, *cp2;
- UNS32 u1, u2, uMin;
- int n = 0;
-
- vmCheckStack(pVM, 4, 1);
- u2 = stackPopUNS32(pVM->pStack);
- cp2 = (char *)stackPopPtr(pVM->pStack);
- u1 = stackPopUNS32(pVM->pStack);
- cp1 = (char *)stackPopPtr(pVM->pStack);
-
- uMin = (u1 < u2)? u1 : u2;
- for ( ; (uMin > 0) && (n == 0); uMin--)
- {
- n = (int)(*cp1++ - *cp2++);
- }
-
- if (n == 0)
- n = (int)(u1 - u2);
-
- if (n < 0)
- n = -1;
- else if (n > 0)
- n = 1;
-
- stackPushINT32(pVM->pStack, n);
- return;
-}
-
-
-/**************************************************************************
- r e f i l l
-** CORE EXT ( -- flag )
-** Attempt to fill the input buffer from the input source, returning a true
-** flag if successful.
-** When the input source is the user input device, attempt to receive input
-** into the terminal input buffer. If successful, make the result the input
-** buffer, set >IN to zero, and return true. Receipt of a line containing no
-** characters is considered successful. If there is no input available from
-** the current input source, return false.
-** When the input source is a string from EVALUATE, return false and
-** perform no other action.
-**************************************************************************/
-static void refill(FICL_VM *pVM)
-{
- INT32 ret = (pVM->sourceID.i == -1) ? FICL_FALSE : FICL_TRUE;
- stackPushINT32(pVM->pStack, ret);
- if (ret)
- vmThrow(pVM, VM_OUTOFTEXT);
- return;
-}
-
-
-/**************************************************************************
- f o r g e t
-** TOOLS EXT ( "<spaces>name" -- )
-** Skip leading space delimiters. Parse name delimited by a space.
-** Find name, then delete name from the dictionary along with all
-** words added to the dictionary after name. An ambiguous
-** condition exists if name cannot be found.
-**
-** If the Search-Order word set is present, FORGET searches the
-** compilation word list. An ambiguous condition exists if the
-** compilation word list is deleted.
-**************************************************************************/
-static void forgetWid(FICL_VM *pVM)
-{
- FICL_DICT *pDict = ficlGetDict();
- FICL_HASH *pHash;
-
- pHash = (FICL_HASH *)stackPopPtr(pVM->pStack);
- hashForget(pHash, pDict->here);
-
- return;
-}
-
-
-static void forget(FICL_VM *pVM)
-{
- void *where;
- FICL_DICT *pDict = ficlGetDict();
- FICL_HASH *pHash = pDict->pCompile;
-
- tick(pVM);
- where = ((FICL_WORD *)stackPopPtr(pVM->pStack))->name;
- hashForget(pHash, where);
- pDict->here = PTRtoCELL where;
-
- return;
-}
-
-/************************* freebsd added I/O words **************************/
-
-/* fopen - open a file and return new fd on stack.
- *
- * fopen ( count ptr -- fd )
- */
-static void pfopen(FICL_VM *pVM)
-{
- int fd;
- char *p;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 1);
-#endif
- (void)stackPopINT32(pVM->pStack); /* don't need count value */
- p = stackPopPtr(pVM->pStack);
- fd = open(p, O_RDONLY);
- stackPushINT32(pVM->pStack, fd);
- return;
-}
-
-/* fclose - close a file who's fd is on stack.
- *
- * fclose ( fd -- )
- */
-static void pfclose(FICL_VM *pVM)
-{
- int fd;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- fd = stackPopINT32(pVM->pStack); /* get fd */
- if (fd != -1)
- close(fd);
- return;
-}
-
-/* fread - read file contents
- *
- * fread ( fd buf nbytes -- nread )
- */
-static void pfread(FICL_VM *pVM)
-{
- int fd, len;
- char *buf;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 3, 1);
-#endif
- len = stackPopINT32(pVM->pStack); /* get number of bytes to read */
- buf = stackPopPtr(pVM->pStack); /* get buffer */
- fd = stackPopINT32(pVM->pStack); /* get fd */
- if (len > 0 && buf && fd != -1)
- stackPushINT32(pVM->pStack, read(fd, buf, len));
- else
- stackPushINT32(pVM->pStack, -1);
- return;
-}
-
-/* fload - interpret file contents
- *
- * fload ( fd -- )
- */
-static void pfload(FICL_VM *pVM)
-{
- int fd;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 0);
-#endif
- fd = stackPopINT32(pVM->pStack); /* get fd */
- if (fd != -1)
- ficlExecFD(pVM, fd);
- return;
-}
-
-/* key - get a character from stdin
- *
- * key ( -- char )
- */
-static void key(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
- stackPushINT32(pVM->pStack, getchar());
- return;
-}
-
-/* key? - check for a character from stdin (FACILITY)
- *
- * key? ( -- flag )
- */
-static void keyQuestion(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 0, 1);
-#endif
-#ifdef TESTMAIN
- /* XXX Since we don't fiddle with termios, let it always succeed... */
- stackPushINT32(pVM->pStack, FICL_TRUE);
-#else
- /* But here do the right thing. */
- stackPushINT32(pVM->pStack, ischar()? FICL_TRUE : FICL_FALSE);
-#endif
- return;
-}
-
-/* seconds - gives number of seconds since beginning of time
- *
- * beginning of time is defined as:
- *
- * BTX - number of seconds since midnight
- * FreeBSD - number of seconds since Jan 1 1970
- *
- * seconds ( -- u )
- */
-static void pseconds(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM,0,1);
-#endif
- stackPushUNS32(pVM->pStack, (u_int32_t) time(NULL));
- return;
-}
-
-/* ms - wait at least that many milliseconds (FACILITY)
- *
- * ms ( u -- )
- *
- */
-static void ms(FICL_VM *pVM)
-{
-#if FICL_ROBUST > 1
- vmCheckStack(pVM,1,0);
-#endif
-#ifdef TESTMAIN
- usleep(stackPopUNS32(pVM->pStack)*1000);
-#else
- delay(stackPopUNS32(pVM->pStack)*1000);
-#endif
- return;
-}
-
-/* fkey - get a character from a file
- *
- * fkey ( file -- char )
- */
-static void fkey(FICL_VM *pVM)
-{
- int i, fd;
- char ch;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 1, 1);
-#endif
- fd = stackPopINT32(pVM->pStack);
- i = read(fd, &ch, 1);
- stackPushINT32(pVM->pStack, i > 0 ? ch : -1);
- return;
-}
-
-
-/**************************************************************************
- f i c l C o m p i l e C o r e
-** Builds the primitive wordset and the environment-query namespace.
-**************************************************************************/
-
-void ficlCompileCore(FICL_DICT *dp)
-{
- assert (dp);
-
- /*
- ** CORE word set
- ** see softcore.c for definitions of: abs bl space spaces abort"
- */
- pStore =
- dictAppendWord(dp, "!", store, FW_DEFAULT);
- dictAppendWord(dp, "#", numberSign, FW_DEFAULT);
- dictAppendWord(dp, "#>", numberSignGreater,FW_DEFAULT);
- dictAppendWord(dp, "#s", numberSignS, FW_DEFAULT);
- dictAppendWord(dp, "\'", tick, FW_DEFAULT);
- dictAppendWord(dp, "(", commentHang, FW_IMMEDIATE);
- dictAppendWord(dp, "*", mul, FW_DEFAULT);
- dictAppendWord(dp, "*/", mulDiv, FW_DEFAULT);
- dictAppendWord(dp, "*/mod", mulDivRem, FW_DEFAULT);
- dictAppendWord(dp, "+", add, FW_DEFAULT);
- dictAppendWord(dp, "+!", plusStore, FW_DEFAULT);
- dictAppendWord(dp, "+loop", plusLoopCoIm, FW_COMPIMMED);
- pComma =
- dictAppendWord(dp, ",", comma, FW_DEFAULT);
- dictAppendWord(dp, "-", sub, FW_DEFAULT);
- dictAppendWord(dp, ".", displayCell, FW_DEFAULT);
- dictAppendWord(dp, ".#", displayCellNoPad, FW_DEFAULT);
- dictAppendWord(dp, ".\"", dotQuoteCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "/", ficlDiv, FW_DEFAULT);
- dictAppendWord(dp, "/mod", slashMod, FW_DEFAULT);
- dictAppendWord(dp, "0<", zeroLess, FW_DEFAULT);
- dictAppendWord(dp, "0=", zeroEquals, FW_DEFAULT);
- dictAppendWord(dp, "0>", zeroGreater, FW_DEFAULT);
- dictAppendWord(dp, "1+", onePlus, FW_DEFAULT);
- dictAppendWord(dp, "1-", oneMinus, FW_DEFAULT);
- dictAppendWord(dp, "2!", twoStore, FW_DEFAULT);
- dictAppendWord(dp, "2*", twoMul, FW_DEFAULT);
- dictAppendWord(dp, "2/", twoDiv, FW_DEFAULT);
- dictAppendWord(dp, "2@", twoFetch, FW_DEFAULT);
- dictAppendWord(dp, "2drop", twoDrop, FW_DEFAULT);
- dictAppendWord(dp, "2dup", twoDup, FW_DEFAULT);
- dictAppendWord(dp, "2over", twoOver, FW_DEFAULT);
- dictAppendWord(dp, "2swap", twoSwap, FW_DEFAULT);
- dictAppendWord(dp, ":", colon, FW_DEFAULT);
- dictAppendWord(dp, ";", semicolonCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "<", isLess, FW_DEFAULT);
- dictAppendWord(dp, "<#", lessNumberSign, FW_DEFAULT);
- dictAppendWord(dp, "=", isEqual, FW_DEFAULT);
- dictAppendWord(dp, ">", isGreater, FW_DEFAULT);
- dictAppendWord(dp, ">body", toBody, FW_DEFAULT);
- dictAppendWord(dp, ">in", toIn, FW_DEFAULT);
- dictAppendWord(dp, ">number", toNumber, FW_DEFAULT);
- dictAppendWord(dp, ">r", toRStack, FW_DEFAULT);
- dictAppendWord(dp, "?dup", questionDup, FW_DEFAULT);
- dictAppendWord(dp, "@", fetch, FW_DEFAULT);
- dictAppendWord(dp, "abort", ficlAbort, FW_DEFAULT);
- dictAppendWord(dp, "accept", accept, FW_DEFAULT);
- dictAppendWord(dp, "align", align, FW_DEFAULT);
- dictAppendWord(dp, "aligned", aligned, FW_DEFAULT);
- dictAppendWord(dp, "allot", allot, FW_DEFAULT);
- dictAppendWord(dp, "and", bitwiseAnd, FW_DEFAULT);
- dictAppendWord(dp, "base", base, FW_DEFAULT);
- dictAppendWord(dp, "begin", beginCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "c!", cStore, FW_DEFAULT);
- dictAppendWord(dp, "c,", cComma, FW_DEFAULT);
- dictAppendWord(dp, "c@", cFetch, FW_DEFAULT);
- dictAppendWord(dp, "cell+", cellPlus, FW_DEFAULT);
- dictAppendWord(dp, "cells", cells, FW_DEFAULT);
- dictAppendWord(dp, "char", ficlChar, FW_DEFAULT);
- dictAppendWord(dp, "char+", charPlus, FW_DEFAULT);
- dictAppendWord(dp, "chars", ficlChars, FW_DEFAULT);
- dictAppendWord(dp, "constant", constant, FW_DEFAULT);
- dictAppendWord(dp, "count", count, FW_DEFAULT);
- dictAppendWord(dp, "cr", cr, FW_DEFAULT);
- dictAppendWord(dp, "create", create, FW_DEFAULT);
- dictAppendWord(dp, "decimal", decimal, FW_DEFAULT);
- dictAppendWord(dp, "depth", depth, FW_DEFAULT);
- dictAppendWord(dp, "do", doCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "does>", doesCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "drop", drop, FW_DEFAULT);
- dictAppendWord(dp, "dup", dup, FW_DEFAULT);
- dictAppendWord(dp, "else", elseCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "emit", emit, FW_DEFAULT);
- dictAppendWord(dp, "environment?", environmentQ,FW_DEFAULT);
- dictAppendWord(dp, "evaluate", evaluate, FW_DEFAULT);
- dictAppendWord(dp, "execute", execute, FW_DEFAULT);
- dictAppendWord(dp, "exit", exitCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "fill", fill, FW_DEFAULT);
- dictAppendWord(dp, "find", find, FW_DEFAULT);
- dictAppendWord(dp, "fm/mod", fmSlashMod, FW_DEFAULT);
- dictAppendWord(dp, "here", here, FW_DEFAULT);
- dictAppendWord(dp, "hex", hex, FW_DEFAULT);
- dictAppendWord(dp, "hold", hold, FW_DEFAULT);
- dictAppendWord(dp, "i", loopICo, FW_COMPILE);
- dictAppendWord(dp, "if", ifCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "immediate", immediate, FW_DEFAULT);
- dictAppendWord(dp, "invert", bitwiseNot, FW_DEFAULT);
- dictAppendWord(dp, "j", loopJCo, FW_COMPILE);
- dictAppendWord(dp, "k", loopKCo, FW_COMPILE);
- dictAppendWord(dp, "leave", leaveCo, FW_COMPILE);
- dictAppendWord(dp, "literal", literalIm, FW_IMMEDIATE);
- dictAppendWord(dp, "loop", loopCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "lshift", lshift, FW_DEFAULT);
- dictAppendWord(dp, "m*", mStar, FW_DEFAULT);
- dictAppendWord(dp, "max", ficlMax, FW_DEFAULT);
- dictAppendWord(dp, "min", ficlMin, FW_DEFAULT);
- dictAppendWord(dp, "mod", ficlMod, FW_DEFAULT);
- dictAppendWord(dp, "move", move, FW_DEFAULT);
- dictAppendWord(dp, "negate", negate, FW_DEFAULT);
- dictAppendWord(dp, "or", bitwiseOr, FW_DEFAULT);
- dictAppendWord(dp, "over", over, FW_DEFAULT);
- dictAppendWord(dp, "postpone", postponeCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "quit", quit, FW_DEFAULT);
- dictAppendWord(dp, "r>", fromRStack, FW_DEFAULT);
- dictAppendWord(dp, "r@", fetchRStack, FW_DEFAULT);
- dictAppendWord(dp, "recurse", recurseCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "repeat", repeatCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "rot", rot, FW_DEFAULT);
- dictAppendWord(dp, "rshift", rshift, FW_DEFAULT);
- dictAppendWord(dp, "s\"", stringQuoteIm, FW_IMMEDIATE);
- dictAppendWord(dp, "s>d", sToD, FW_DEFAULT);
- dictAppendWord(dp, "sign", sign, FW_DEFAULT);
- dictAppendWord(dp, "sm/rem", smSlashRem, FW_DEFAULT);
- dictAppendWord(dp, "source", source, FW_DEFAULT);
- dictAppendWord(dp, "state", state, FW_DEFAULT);
- dictAppendWord(dp, "swap", swap, FW_DEFAULT);
- dictAppendWord(dp, "then", endifCoIm, FW_COMPIMMED);
- pType =
- dictAppendWord(dp, "type", type, FW_DEFAULT);
- dictAppendWord(dp, "u.", uDot, FW_DEFAULT);
- dictAppendWord(dp, "u<", uIsLess, FW_DEFAULT);
- dictAppendWord(dp, "um*", umStar, FW_DEFAULT);
- dictAppendWord(dp, "um/mod", umSlashMod, FW_DEFAULT);
- dictAppendWord(dp, "unloop", unloopCo, FW_COMPILE);
- dictAppendWord(dp, "until", untilCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "variable", variable, FW_DEFAULT);
- dictAppendWord(dp, "while", whileCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "word", ficlWord, FW_DEFAULT);
- dictAppendWord(dp, "xor", bitwiseXor, FW_DEFAULT);
- dictAppendWord(dp, "[", lbracketCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "[\']", bracketTickCoIm,FW_COMPIMMED);
- dictAppendWord(dp, "[char]", charCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "]", rbracket, FW_DEFAULT);
- /*
- ** CORE EXT word set...
- ** see softcore.c for other definitions
- */
- dictAppendWord(dp, ".(", dotParen, FW_DEFAULT);
- dictAppendWord(dp, ":noname", colonNoName, FW_DEFAULT);
- dictAppendWord(dp, "?do", qDoCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "parse", parse, FW_DEFAULT);
- dictAppendWord(dp, "pick", pick, FW_DEFAULT);
- dictAppendWord(dp, "roll", roll, FW_DEFAULT);
- dictAppendWord(dp, "refill", refill, FW_DEFAULT);
- dictAppendWord(dp, "to", toValue, FW_IMMEDIATE);
- dictAppendWord(dp, "value", constant, FW_DEFAULT);
- dictAppendWord(dp, "\\", commentLine, FW_IMMEDIATE);
-
- /* FreeBSD extension words */
- dictAppendWord(dp, "fopen", pfopen, FW_DEFAULT);
- dictAppendWord(dp, "fclose", pfclose, FW_DEFAULT);
- dictAppendWord(dp, "fread", pfread, FW_DEFAULT);
- dictAppendWord(dp, "fload", pfload, FW_DEFAULT);
- dictAppendWord(dp, "fkey", fkey, FW_DEFAULT);
- dictAppendWord(dp, "key", key, FW_DEFAULT);
- dictAppendWord(dp, "key?", keyQuestion, FW_DEFAULT);
- dictAppendWord(dp, "ms", ms, FW_DEFAULT);
- dictAppendWord(dp, "seconds", pseconds, FW_DEFAULT);
-#ifdef __i386__
-#ifndef TESTMAIN
- dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT);
- dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT);
-#endif
- ficlSetEnv("arch-i386", FICL_TRUE);
-#else
- ficlSetEnv("arch-i386", FICL_FALSE);
-#endif
-
- /*
- ** Set CORE environment query values
- */
- ficlSetEnv("/counted-string", FICL_STRING_MAX);
- ficlSetEnv("/hold", nPAD);
- ficlSetEnv("/pad", nPAD);
- ficlSetEnv("address-unit-bits", 8);
- ficlSetEnv("core", FICL_TRUE);
- ficlSetEnv("core-ext", FICL_FALSE);
- ficlSetEnv("floored", FICL_FALSE);
- ficlSetEnv("max-char", UCHAR_MAX);
- ficlSetEnvD("max-d", 0x7fffffff, 0xffffffff );
- ficlSetEnv("max-n", 0x7fffffff);
- ficlSetEnv("max-u", 0xffffffff);
- ficlSetEnvD("max-ud", 0xffffffff, 0xffffffff);
- ficlSetEnv("return-stack-cells",FICL_DEFAULT_STACK);
- ficlSetEnv("stack-cells", FICL_DEFAULT_STACK);
-
- /*
- ** LOCAL and LOCAL EXT
- ** see softcore.c for implementation of locals|
- */
-#if FICL_WANT_LOCALS
- pLinkParen =
- dictAppendWord(dp, "(link)", linkParen, FW_COMPILE);
- pUnLinkParen =
- dictAppendWord(dp, "(unlink)", unlinkParen, FW_COMPILE);
- dictAppendWord(dp, "doLocal", doLocalIm, FW_COMPIMMED);
- pGetLocalParen =
- dictAppendWord(dp, "(@local)", getLocalParen, FW_COMPILE);
- pToLocalParen =
- dictAppendWord(dp, "(toLocal)", toLocalParen, FW_COMPILE);
- pGetLocal0 =
- dictAppendWord(dp, "(@local0)", getLocal0, FW_COMPILE);
- pToLocal0 =
- dictAppendWord(dp, "(toLocal0)",toLocal0, FW_COMPILE);
- pGetLocal1 =
- dictAppendWord(dp, "(@local1)", getLocal1, FW_COMPILE);
- pToLocal1 =
- dictAppendWord(dp, "(toLocal1)",toLocal1, FW_COMPILE);
- dictAppendWord(dp, "(local)", localParen, FW_COMPILE);
-
- ficlSetEnv("locals", FICL_TRUE);
- ficlSetEnv("locals-ext", FICL_TRUE);
- ficlSetEnv("#locals", FICL_MAX_LOCALS);
-#endif
-
- /*
- ** optional SEARCH-ORDER word set
- */
- dictAppendWord(dp, ">search", searchPush, FW_DEFAULT);
- dictAppendWord(dp, "search>", searchPop, FW_DEFAULT);
- dictAppendWord(dp, "definitions",
- definitions, FW_DEFAULT);
- dictAppendWord(dp, "forth-wordlist",
- forthWordlist, FW_DEFAULT);
- dictAppendWord(dp, "get-current",
- getCurrent, FW_DEFAULT);
- dictAppendWord(dp, "get-order", getOrder, FW_DEFAULT);
- dictAppendWord(dp, "search-wordlist",
- searchWordlist, FW_DEFAULT);
- dictAppendWord(dp, "set-current",
- setCurrent, FW_DEFAULT);
- dictAppendWord(dp, "set-order", setOrder, FW_DEFAULT);
- dictAppendWord(dp, "ficl-wordlist", wordlist, FW_DEFAULT);
-
- /*
- ** Set SEARCH environment query values
- */
- ficlSetEnv("search-order", FICL_TRUE);
- ficlSetEnv("search-order-ext", FICL_TRUE);
- ficlSetEnv("wordlists", FICL_DEFAULT_VOCS);
-
- /*
- ** TOOLS and TOOLS EXT
- */
- dictAppendWord(dp, ".s", displayStack, FW_DEFAULT);
- dictAppendWord(dp, "bye", bye, FW_DEFAULT);
- dictAppendWord(dp, "forget", forget, FW_DEFAULT);
- dictAppendWord(dp, "see", see, FW_DEFAULT);
- dictAppendWord(dp, "words", listWords, FW_DEFAULT);
-
- /*
- ** Set TOOLS environment query values
- */
- ficlSetEnv("tools", FICL_TRUE);
- ficlSetEnv("tools-ext", FICL_FALSE);
-
- /*
- ** Ficl extras
- */
- dictAppendWord(dp, ".env", listEnv, FW_DEFAULT);
- dictAppendWord(dp, ".hash", dictHashSummary,FW_DEFAULT);
- dictAppendWord(dp, ".ver", ficlVersion, FW_DEFAULT);
- dictAppendWord(dp, "-roll", minusRoll, FW_DEFAULT);
- dictAppendWord(dp, "2constant", twoConstant, FW_IMMEDIATE); /* DOUBLE */
- dictAppendWord(dp, ">name", toName, FW_DEFAULT);
- dictAppendWord(dp, "body>", fromBody, FW_DEFAULT);
- dictAppendWord(dp, "compare", compareString, FW_DEFAULT); /* STRING */
- dictAppendWord(dp, "compile-only",
- compileOnly, FW_DEFAULT);
- dictAppendWord(dp, "endif", endifCoIm, FW_COMPIMMED);
- dictAppendWord(dp, "forget-wid",forgetWid, FW_DEFAULT);
- dictAppendWord(dp, "parse-word",parseNoCopy, FW_DEFAULT);
- dictAppendWord(dp, "sliteral", sLiteralCoIm, FW_COMPIMMED); /* STRING */
- dictAppendWord(dp, "wid-set-super",
- setParentWid, FW_DEFAULT);
- dictAppendWord(dp, "w@", wFetch, FW_DEFAULT);
- dictAppendWord(dp, "w!", wStore, FW_DEFAULT);
- dictAppendWord(dp, "x.", hexDot, FW_DEFAULT);
-#if FICL_WANT_USER
- dictAppendWord(dp, "(user)", userParen, FW_DEFAULT);
- dictAppendWord(dp, "user", userVariable, FW_DEFAULT);
-#endif
- /*
- ** internal support words
- */
- pExitParen =
- dictAppendWord(dp, "(exit)", exitParen, FW_COMPILE);
- pSemiParen =
- dictAppendWord(dp, "(;)", semiParen, FW_COMPILE);
- pLitParen =
- dictAppendWord(dp, "(literal)", literalParen, FW_COMPILE);
- pStringLit =
- dictAppendWord(dp, "(.\")", stringLit, FW_COMPILE);
- pIfParen =
- dictAppendWord(dp, "(if)", ifParen, FW_COMPILE);
- pBranchParen =
- dictAppendWord(dp, "(branch)", branchParen, FW_COMPILE);
- pDoParen =
- dictAppendWord(dp, "(do)", doParen, FW_COMPILE);
- pDoesParen =
- dictAppendWord(dp, "(does>)", doesParen, FW_COMPILE);
- pQDoParen =
- dictAppendWord(dp, "(?do)", qDoParen, FW_COMPILE);
- pLoopParen =
- dictAppendWord(dp, "(loop)", loopParen, FW_COMPILE);
- pPLoopParen =
- dictAppendWord(dp, "(+loop)", plusLoopParen, FW_COMPILE);
- pInterpret =
- dictAppendWord(dp, "interpret", interpret, FW_DEFAULT);
- dictAppendWord(dp, "(variable)",variableParen, FW_COMPILE);
- dictAppendWord(dp, "(constant)",constantParen, FW_COMPILE);
-
- return;
-}
-
diff --git a/sys/boot/i386/boot0/Makefile b/sys/boot/i386/boot0/Makefile
index 4e890da32565..d6c407a0cc47 100644
--- a/sys/boot/i386/boot0/Makefile
+++ b/sys/boot/i386/boot0/Makefile
@@ -1,16 +1,12 @@
-# $Id: Makefile,v 1.5 1998/10/17 14:20:25 rnordier Exp $
+# $Id: Makefile,v 1.3 1998/10/09 17:19:51 rnordier Exp $
PROG= boot0
NOMAN=
STRIP=
BINDIR?= /boot
-BINMODE= 444
M4?= m4
-B0FLAGS=0x0
-B0TICKS=0xb6
-
ORG= 0x600
boot0: boot0.o
@@ -23,8 +19,8 @@ boot0: boot0.o
.endif
boot0.o: boot0.m4 boot0.s
- (cd ${.CURDIR}; ${M4} -DFLAGS=${B0FLAGS} -DTICKS=${B0TICKS} \
- boot0.m4 boot0.s) | ${AS} ${AFLAGS} -o ${.TARGET}
+ (cd ${.CURDIR}; ${M4} boot0.m4 boot0.s) | \
+ ${AS} ${AFLAGS} -o ${.TARGET}
CLEANFILES+= boot0.out boot0.o
diff --git a/sys/boot/i386/boot0/boot0.m4 b/sys/boot/i386/boot0/boot0.m4
index f0912a888243..c0a38b76911e 100644
--- a/sys/boot/i386/boot0/boot0.m4
+++ b/sys/boot/i386/boot0/boot0.m4
@@ -13,7 +13,7 @@
# purpose.
#
-# $Id: boot0.m4,v 1.2 1998/10/19 19:13:53 rnordier Exp $
+# $Id:$
define(_al,0x0)dnl
define(_cl,0x1)dnl
@@ -52,22 +52,25 @@ define(_bx_,0x7)dnl
define(o16,`.byte 0x66')dnl
define(addwia,`.byte 0x5; .word $1')dnl
-define(btwr1,`.word 0xa30f; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
-define(btswr1,`.word 0xab0f; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
-define(cmpbmr,`.byte 0x3a; .byte 0x6 | ($2 << 0x3); .word $1')dnl
-define(cmpw1r,`.byte 0x3b; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
+define(btwrm,`.byte 0xf; .byte 0xa3; .byte 0x6 | ($1 << 0x3); .word $2')dnl
+define(btswrm,`.byte 0xf; .byte 0xab; .byte 0x6 | ($1 << 0x3); .word $2')dnl
+define(cmpwmr,`.byte 0x3b; .byte ($2 << 0x3) | 0x6; .word $1')dnl
define(cmpwi2,`.byte 0x81; .byte 0xb8 | $3; .word $2; .word $1')dnl
-define(addwir,`.byte 0x83; .byte 0xc0 | $2; .byte $1')dnl
+define(cmpwir,`.byte 0x81; .byte 0xf8 | $2; .word $1')dnl
define(movbr0,`.byte 0x88; .byte ($1 << 0x3) | $2')dnl
+define(movbrm,`.byte 0x88; .byte 0x6 | ($1 << 0x3); .word $2')dnl
define(movbr1,`.byte 0x88; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
define(movwr1,`.byte 0x89; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
define(movb0r,`.byte 0x8a; .byte ($2 << 0x3) | $1')dnl
+define(movbmr,`.byte 0x8a; .byte 0x6 | ($2 << 0x3); .word $1')dnl
define(movb1r,`.byte 0x8a; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
define(movw1r,`.byte 0x8b; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
define(movws1,`.byte 0x8c; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
+define(leaw1r,`.byte 0x8d; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
+define(movbma,`.byte 0xa0; .word $1')dnl
+define(movbam,`.byte 0xa2; .word $1')dnl
define(movwir,`.byte 0xb8 | $2; .word $1')dnl
define(movbi0,`.byte 0xc6; .byte $2; .byte $1')dnl
define(callwi,`.byte 0xe8; .word $1 - . - 0x2')dnl
define(jmpnwi,`.byte 0xe9; .word $1 - . - 0x2')dnl
-define(tstbi1,`.byte 0xf6; .byte 0x40 | $3; .byte $2; .byte $1')dnl
define(incb1,`.byte 0xfe; .byte 0x40 | $2; .byte $1')dnl
diff --git a/sys/boot/i386/boot0/boot0.s b/sys/boot/i386/boot0/boot0.s
index 08a8d6be21b2..ae7fa5db8893 100644
--- a/sys/boot/i386/boot0/boot0.s
+++ b/sys/boot/i386/boot0/boot0.s
@@ -13,36 +13,19 @@
# purpose.
#
-# $Id: boot0.s,v 1.5 1998/11/29 14:09:00 rnordier Exp $
+# $Id: boot0.s,v 1.2 1998/10/09 17:19:51 rnordier Exp $
# A 512-byte boot manager.
- .set NHRDRV,0x475 # Number of hard drives
- .set ORIGIN,0x600 # Execution address
- .set DSKPKT,0x800 # Disk packet
- .set FAKE,0x810 # Partition entry
.set LOAD,0x7c00 # Load address
-
+ .set ORIGIN,0x600 # Relocation address
.set PRT_OFF,0x1be # Partition table
-
- .set TBL0SZ,0x3 # Table 0 size
- .set TBL1SZ,0xa # Table 1 size
-
- .set MAGIC,0xaa55 # Magic: bootable
-
- .set KEY_ENTER,0x1c # Enter key scan code
- .set KEY_F1,0x3b # F1 key scan code
-
- .set _NXTDRV,-0x47 # Drive number
- .set _OPT,-0x46 # Default option
- .set _FLAGS,-0x45 # Flags
- .set _TICKS,-0x44 # Timeout ticks
- .set _FAKE,0x10 # Fake partition entry
- .set _MNUOPT,0x1c # Menu options
+ .set FAKE,0x810 # Partition entry
+ .set MNUOPT,0x81c # Menu options
.globl start # Entry point
-start: cld # String ops inc
+start: cld # String ops inc
xorl %eax,%eax # Zero
movl %eax,%es # Address
movl %eax,%ds # data
@@ -53,185 +36,183 @@ start: cld # String ops inc
movwir(0x100,_cx) # Word count
rep # Relocate
movsl # code
- movl %edi,%ebp # Address variables
movb $0x10,%cl # Words to clear
rep # Zero
stosl # them
incb1(-0xe,_di_) # Sector number
jmpnwi(main-LOAD+ORIGIN) # To relocated code
-main: movbr1(_dl,_FAKE,_bp_) # Save drive number
+main: movbrm(_dl,FAKE) # Save drive number
callwi(putn) # To new line
movwir(partbl,_bx) # Partition table
xorl %edx,%edx # Item
-main.1: movbr0(_dh,_bx_) # Mark inactive
+main.1: movbr0(_dh,_bx_) # Mark inactive
movb1r(0x4,_bx_,_al) # Load type
- movwir(tables,_di) # Lookup tables
- movb $TBL0SZ,%cl # Entries
+ movwir(table0,_di) # Exclusion table
+ movb $0x3,%cl # Entries
repne # Exclude
scasb # partition?
je main.3 # Yes
- movb $TBL1SZ,%cl # Entries
+ movb $0xa,%cl # Entries
repne # Known
scasb # type?
jne main.2 # No
- addwir(TBL1SZ,_di) # Adjust
-main.2: movb0r(_di_,_cl) # Partition
- addl %ecx,%edi # description
- callwi(putx) # Display it
-main.3: addwir(0x10,_bx) # Next entry
+ leaw1r(0xa,_di_,_di) # Name table
+main.2: movwir(item,_si) # Display start
+ callwi(putkey) # of menu item
+ movl %edi,%esi # Set pointer
+ lodsb # to
+ cwde # partition
+ add %eax,%esi # description
+ callwi(puts) # Display it
+ btswrm(_dx,MNUOPT) # Flag option enabled
+main.3: addb $0x10,%bl # Next entry
incl %edx # Next item
cmpb $0x4,%dl # Done?
jb main.1 # No
- movb1r(_FAKE,_bp_,_al) # Drive number
- subb $0x80-0x1,%al # Does next
- cmpbmr(NHRDRV,_al) # drive exist?
- jb main.4 # Yes
- decb %al # Already drive 0?
- jz main.5 # Yes
- xorb %al,%al # Drive 0
-main.4: addb $'0'|0x80,%al # Save
- movbr1(_al,_NXTDRV,_bp_) # it
- movwir(drive,_di) # Display
- callwi(putx) # item
-main.5: movwir(prompt,_si) # Display
+ movwir(prompt,_si) # Display
callwi(putstr) # prompt
- movb1r(_OPT,_bp_,_dl) # Display
+ movbmr(opt,_dl) # Display
decl %esi # default
callwi(putkey) # key
xorb %ah,%ah # BIOS: Get
int $0x1a # system time
- movl %edx,%edi # Save ticks
-main.6: movb $0x1,%ah # BIOS: Check
+ movl %edx,%edi # Save
+main.4: movb $0x1,%ah # BIOS: Check
int $0x16 # for keypress
- jnz main.9 # Have one
+ jnz main.6 # Have one
xorb %ah,%ah # BIOS: Get
int $0x1a # system time
subl %edi,%edx # Elapsed time
- cmpw1r(_TICKS,_bp_,_dx) # Timeout?
- jb main.6 # No
-main.7: movb1r(_OPT,_bp_,_al) # Load default
- jmp main.10 # Join common code
-main.8: movb $0x7,%al # Signal
+ cmpwmr(ticks,_dx) # Timeout?
+ jb main.4 # No
+ jmp main.7 # Join common code
+main.5: movb $0x7,%al # Signal
callwi(putchr) # error
-main.9: xorb %ah,%ah # BIOS: Get
+main.6: xorb %ah,%ah # BIOS: Get
int $0x16 # keypress
movb %ah,%al # Scan code
- cmpb $KEY_ENTER,%al # Enter pressed?
- je main.7 # No
- subb $KEY_F1,%al # Less F1 scan code
- cmpb $0x4,%al # F1..F5?
- ja main.8 # No
-main.10: cwtl # Option
- btwr1(_ax,_MNUOPT,_bp_) # enabled?
- jnc main.8 # No
+ cmpb $0x1c,%al # Enter pressed?
+ jne main.8 # No
+main.7: movbma(opt) # Load
+ jmp main.9 # default
+main.8: subb $0x3b,%al # Less F1 scan code
+ jb main.5 # Not a function key
+main.9: cmpb $0x4,%al # F1..F5?
+ ja main.5 # No
movwir(FAKE,_si) # Partition entry
- movb1r(_NXTDRV,_bp_,_dl) # Next drive
- subb $'0',%dl # number
- cmpb $0x4,%al # F5 pressed?
- je main.11 # Yes
- movb0r(_si_,_dl) # Drive number
- movbr1(_al,_OPT,_bp_) # Save option
+ movb0r(_si_,_dl) # Load drive number
+ jne main.10 # If not F5
+ xorb $0x1,%dl # Toggle drive
+ jmp main.11 # number
+main.10: cwtl # Option
+ btwrm(_ax,MNUOPT) # enabled?
+ jnc main.5 # No
+ movbam(opt) # Save option
shlb $0x4,%al # Point to
addwia(partbl) # partition
- xchgl %esi,%eax # entry
- tstbi1(0x40,_FLAGS,_bp_) # No updates?
- jnz main.11 # Yes
+ xchgl %esi,%eax # entry
movbi0(0x80,_si_) # Flag active
pushl %esi # Save
- xchgl %esi,%eax # Fake partition entry
+ movl %eax,%esi # Fake partition entry
movwir(start,_bx) # Data to write
movwir(0x301,_ax) # Write sector
callwi(intx13) # to disk
popl %esi # Restore
+ jc main.5 # If error
main.11: movwir(LOAD,_bx) # Address for read
movwir(0x201,_ax) # Read sector
callwi(intx13) # from disk
- jc main.8 # If error
- cmpwi2(MAGIC,0x1fe,_bx_) # Bootable?
- jne main.8 # No
+ jc main.5 # If error
+ cmpwi2(0xaa55,0x1fe,_bx_) # Bootable?
+ jne main.5 # No
movwir(crlf,_si) # Leave some
callwi(puts) # space
jmp *%ebx # Invoke bootstrap
# Display routines
-putkey: movb $'F',%al # Display
+putkey: movb $'F',%al # Display
callwi(putchr) # 'F'
movb $'1',%al # Prepare
addb %dl,%al # digit
jmp putstr.1 # Display the rest
-putx: btswr1(_dx,_MNUOPT,_bp_) # Enable menu option
- movwir(item,_si) # Display
- callwi(putkey) # key
- movl %edi,%esi # Display the rest
-
puts: callwi(putstr) # Display string
putn: movwir(crlf,_si) # To next line
-putstr: lodsb # Get byte
- testb $0x80,%al # End of string?
+putstr: lodsb # Get byte
+ testb $0x80,%al # End of string?
jnz putstr.2 # Yes
putstr.1: callwi(putchr) # Display char
jmp putstr # Continue
-putstr.2: andb $~0x80,%al # Clear MSB
+putstr.2: andb $~0x80,%al # Clear MSB
-putchr: pushl %ebx # Save
- movwir(0x7,_bx) # Page:attribute
+putchr: pushl %ebx # Save
+ movwir(0x7,_bx) # Page:attribute
movb $0xe,%ah # BIOS: Display
int $0x10 # character
popl %ebx # Restore
ret # To caller
-# Disk I/O routine
+# Disk I/O
-intx13: cli # Disable interrupts
- movb1r(0x1,_si_,_dh) # Load head
+intx13: movb1r(0x1,_si_,_dh) # Load head
movw1r(0x2,_si_,_cx) # Load cylinder:sector
o16 # Load
movw1r(0x8,_si_,_di) # offset
- movwir(DSKPKT,_si) # Packet pointer
+ pushl %ecx # Save
+ pushl %ebx # caller's
+ movwir(0x55aa,_bx) # Magic
+ pushl %eax # Save
+ movb $0x41,%ah # BIOS: EDD extensions
+ int $0x13 # present?
+ popl %eax # Restore
+ jc intx13.1 # No
+ cmpwir(0xaa55,_bx) # Magic?
+ jne intx13.1 # No
+ testb $0x1,%cl # Use packet?
+ jz intx13.1 # No
+ orb $0x40,%ah # Use EDD
+intx13.1: popl %ebx # Restore
+ popl %ecx # caller's
+ testb $0x40,%ah # Use EDD?
+ jz intx13.2 # No
+ movwir(break,_si) # Packet pointer
movbi0(0x10,_si_) # Packet size
movbr1(_al,0x2,_si_) # Block count
movwr1(_bx,0x4,_si_) # Transfer
movws1(_es,0x6,_si_) # buffer
o16 # LBA
movwr1(_di,0x8,_si_) # address
- sti # Enable interrupts
- tstbi1(0x80,_FLAGS,_bp_) # Use packet interface?
- jz intx13.1 # No
- orb $0x40,%ah # Use disk packet
- decl %eax # Verify off
-intx13.1: int $0x13 # BIOS: Disk I/O
+ xorb %al,%al # Verify off
+intx13.2: int $0x13 # BIOS: Disk I/O
ret # To caller
# Menu strings
-item: .ascii " "; .byte ' '|0x80
+crlf: .ascii "\r"; .byte '\n'|0x80
+item: .ascii " "; .byte ' '|0x80
prompt: .ascii "\nDefault:"; .byte ' '|0x80
-crlf: .ascii "\r"; .byte '\n'|0x80
# Partition type tables
-tables:
- .byte 0x0, 0x5, 0xf
-
- .byte 0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x63, 0x83
+table0: .byte 0x0, 0x5, 0xf
+table1: .byte 0x1, 0x4, 0x6, 0xb, 0xc, 0xe, 0x63, 0x83
.byte 0xa5, 0xa6
- .byte os_misc-. # Unknown
- .byte os_dos-. # DOS
- .byte os_dos-. # DOS
- .byte os_dos-. # DOS
- .byte os_dos-. # Windows
- .byte os_dos-. # Windows
- .byte os_dos-. # Windows
- .byte os_unix-. # UNIX
- .byte os_linux-. # Linux
- .byte os_freebsd-. # FreeBSD
- .byte os_bsd-. # OpenBSD
+ .byte os_misc-.-1 # Unknown
+ .byte os_dos-.-1 # DOS
+ .byte os_dos-.-1 # DOS
+ .byte os_dos-.-1 # DOS
+ .byte os_dos-.-1 # Windows
+ .byte os_dos-.-1 # Windows
+ .byte os_dos-.-1 # Windows
+ .byte os_unix-.-1 # UNIX
+ .byte os_linux-.-1 # Linux
+ .byte os_freebsd-.-1 # FreeBSD
+ .byte os_bsd-.-1 # OpenBSD
os_misc: .ascii "?"; .byte '?'|0x80
os_dos: .ascii "DO"; .byte 'S'|0x80
@@ -240,13 +221,12 @@ os_linux: .ascii "Linu"; .byte 'x'|0x80
os_freebsd: .ascii "Free"
os_bsd: .ascii "BS"; .byte 'D'|0x80
- .org PRT_OFF-0xb,0x90
+ .org PRT_OFF-0x3,0x90
+
+opt: .byte 0x1 # Option
+ticks: .word 0xb6 # Delay
-drive: .ascii "Drive "
-nxtdrv: .byte 0x0 # Next drive number
-opt: .byte 0x0 # Option
-flags: .byte FLAGS # Flags
-ticks: .word TICKS # Delay
+partbl: .fill 0x40,0x1,0x0 # Partition table
+ .word 0xaa55 # Magic number
-partbl: .fill 0x40,0x1,0x0 # Partition table
- .word MAGIC # Magic number
+break: # Uninitialized data
diff --git a/sys/boot/i386/boot2/Makefile b/sys/boot/i386/boot2/Makefile
index 2b581ec521cd..e36df60f2a9b 100644
--- a/sys/boot/i386/boot2/Makefile
+++ b/sys/boot/i386/boot2/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.10 1998/11/08 15:36:34 rnordier Exp $
+# $Id: Makefile,v 1.6 1998/10/15 20:04:21 rnordier Exp $
PROG= boot2
NOMAN=
@@ -11,10 +11,6 @@ CLEANFILES+= boot1 boot1.out boot1.o \
M4?= m4
-BOOT_COMCONSOLE_PORT?= 0x3f8
-BOOT_COMCONSOLE_SPEED?= 9600
-B2SIOFMT?= 0x3
-
.if exists(${.OBJDIR}/../btx)
BTX= ${.OBJDIR}/../btx
.else
@@ -62,10 +58,7 @@ boot2.out: boot2.o sio.o
${BTX}/lib/crt0.o boot2.o sio.o
sio.o: sio.s
- (cd ${.CURDIR}; ${M4} -DSIOPRT=${BOOT_COMCONSOLE_PORT} \
- -DSIOFMT=${B2SIOFMT} \
- -DSIOSPD=${BOOT_COMCONSOLE_SPEED} sio.s) | \
- ${AS} ${AFLAGS} -o ${.TARGET}
+ ${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
install:
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
diff --git a/sys/boot/i386/boot2/boot1.m4 b/sys/boot/i386/boot2/boot1.m4
index 06bdc9789331..fc221a1854c1 100644
--- a/sys/boot/i386/boot2/boot1.m4
+++ b/sys/boot/i386/boot2/boot1.m4
@@ -13,7 +13,7 @@
# purpose.
#
-# $Id: boot1.m4,v 1.2 1998/11/05 20:52:25 rnordier Exp $
+# $Id:$
define(_al,0x0)dnl
define(_cl,0x1)dnl
@@ -60,5 +60,3 @@ define(movbi1,`.byte 0xc6; .byte 0x40 | $3; .byte $2; .byte $1')dnl
define(callwi,`.byte 0xe8; .word $1 - . - 0x2')dnl
define(jmpnwi,`.byte 0xe9; .word $1 - . - 0x2')dnl
define(tstbi0,`.byte 0xf6; .byte $2; .byte $1')dnl
-define(tstbim,`.byte 0xf6; .byte 0x6; .word $2; .byte $1')dnl
-define(incw1,`.byte 0xff; .byte 0x40 | $2; .byte $1')dnl
diff --git a/sys/boot/i386/boot2/boot1.s b/sys/boot/i386/boot2/boot1.s
index 3161b748b8e9..8b408cebeff4 100644
--- a/sys/boot/i386/boot2/boot1.s
+++ b/sys/boot/i386/boot2/boot1.s
@@ -13,10 +13,11 @@
# purpose.
#
-# $Id: boot1.s,v 1.7 1999/01/10 13:29:51 peter Exp $
+# $Id: boot1.s,v 1.1.1.1 1998/10/12 21:16:26 rnordier Exp $
- .set MEM_REL,0x700 # Relocation address
- .set MEM_ARG,0x900 # Arguments
+ .set MEM_REL,0x600 # Relocation address
+ .set MEM_ARG,0x800 # Arguments
+ .set MEM_PKT,0x810 # Disk packet
.set MEM_ORG,0x7c00 # Origin
.set MEM_BUF,0x8c00 # Load area
.set MEM_BTX,0x9000 # BTX start
@@ -37,58 +38,59 @@ start: jmp main # Start recognizably
.org 0x4,0x90
-# External read from disk
-
-xread: pushl %ecx # Set
- pushl %eax # LBA
- pushl %es # Set transfer
- pushl %ebx # buffer
- pushl %edx # Set count:drive
+xread: pushl %cs # Address
+ popl %ds # data
+xread.1: movwir(MEM_PKT,_si) # Packet
+ movbr1(_al,0x2,_si_) # Blocks to read
+ o16 # Transfer
+ movwr1(_bx,0x4,_si_) # buffer
+ o16 # LBA
+ movwr1(_cx,0x8,_si_) # address
callwi(read) # Read from disk
- popl %edx # Pop all
- popl %ebx # registers
- popl %es # pushed, but
- popl %ecx # preserve
- popl %ecx # AX
- lret # To far caller
-
-# Bootstrap
+ lret # To caller
main: cld # String ops inc
- xorl %ecx,%ecx # Zero
- movl %cx,%es # Address
- movl %cx,%ds # data
- movl %cx,%ss # Set up
+ xorl %eax,%eax # Zero
+ movl %ax,%es # Address
+ movl %ax,%ds # data
+ movl %ax,%ss # Set up
movwir(start,_sp) # stack
movl %esp,%esi # Source
movwir(MEM_REL,_di) # Destination
- incb %ch # Word count
+ movwir(0x100,_cx) # Word count
rep # Copy
movsl # code
- movwir(part4,_si) # Partition
+ movb $0x10,%cl # Words to clear
+ rep # Zero
+ stosl # them
+ movbi1(0x10,-0x10,_di_) # Set packet size
cmpb $0x80,%dl # Hard drive?
jb main.4 # No
- movb $0x1,%dh # Block count
- callwi(nread) # Read MBR
- movwir(0x1,_cx) # Two passes
+ movwir(part4,_si) # Read master
+ movb $0x1,%al # boot
+ callwi(nread) # record
+ xorl %eax,%eax # Pass number
main.1: movwir(MEM_BUF+PRT_OFF,_si) # Partition table
movb $0x1,%dh # Partition
main.2: cmpbi1(PRT_BSD,0x4,_si_) # Our partition type?
jne main.3 # No
- jecxz main.5 # If second pass
tstbi0(0x80,_si_) # Active?
jnz main.5 # Yes
+ testb %al,%al # Second pass?
+ jnz main.5 # Yes
main.3: addl $0x10,%esi # Next entry
incb %dh # Partition
- cmpb $0x1+PRT_NUM,%dh # In table?
- jb main.2 # Yes
- decl %ecx # Do two
- jecxz main.1 # passes
+ cmpb $0x1+PRT_NUM,%dh # Done?
+ jb main.2 # No
+ incl %eax # Pass
+ cmpb $0x2,%al # Done?
+ jb main.1 # No
movwir(msg_part,_si) # Message
jmp error # Error
main.4: xorl %edx,%edx # Partition:drive
+ movwir(part4,_si) # Partition pointer
main.5: movwrm(_dx,MEM_ARG) # Save args
- movb $0x10,%dh # Sector count
+ movb $0x10,%al # Sector count
callwi(nread) # Read disk
movwir(MEM_BTX,_bx) # BTX
movw1r(0xa,_bx_,_si) # Point past
@@ -107,34 +109,33 @@ main.5: movwrm(_dx,MEM_ARG) # Save args
# Enable A20
-seta20: cli # Disable interrupts
-seta20.1: inb $0x64,%al # Get status
+seta20: inb $0x64,%al # Get status
testb $0x2,%al # Busy?
- jnz seta20.1 # Yes
+ jnz seta20 # Yes
movb $0xd1,%al # Command: Write
outb %al,$0x64 # output port
-seta20.2: inb $0x64,%al # Get status
+seta20.1: inb $0x64,%al # Get status
testb $0x2,%al # Busy?
- jnz seta20.2 # Yes
+ jnz seta20.1 # Yes
movb $0xdf,%al # Enable
outb %al,$0x60 # A20
- sti # Enable interrupts
ret # To caller
-# Local read from disk
+# Read from disk
-nread: movwir(MEM_BUF,_bx) # Transfer buffer
- movw1r(0x8,_si_,_ax) # Get
- movw1r(0xa,_si_,_cx) # LBA
+nread: xorw %bx,%bx # Transfer
+ movb $MEM_BUF>>0x8,%bh # buffer
+ o16 # LBA
+ movw1r(0x8,_si_,_cx) # address
pushl %cs # Read from
- callwi(xread) # disk
+ callwi(xread.1) # disk
jnc return # If success
movwir(msg_read,_si) # Message
# Error exit
error: callwi(putstr) # Display message
- movwir(prompt,_si) # Display
+ movwir(msg_boot,_si) # Display
callwi(putstr) # prompt
xorb %ah,%ah # BIOS: Get
int $0x16 # keypress
@@ -149,24 +150,40 @@ putstr: lodsb # Get char
testb %al,%al # End of string?
jne putstr.0 # No
-ereturn: movb $0x1,%ah # Invalid
- stc # argument
-return: ret # To caller
+return: ret # Generic return
# Read from disk
-read: movl %esp,%ebp # Address stack frame
+read: testb %dh,%dh # Try for extensions?
+ jz read.3 # No
+ movwir(0x55aa,_bx) # Magic
pushl %edx # Save
+ movb $0x41,%ah # BIOS: Check
+ int $0x13 # extensions present
+ popl %edx # Restore
+ jc read.3 # If error
+ cmpwir(0xaa55,_bx) # Magic?
+ jne read.3 # No
+ testb $0x1,%cl # Packet interface?
+ jz read.3 # No
+ movb $0x42,%ah # BIOS: Extended
+ int $0x13 # read
+ ret # To caller
+
+read.1: movb $0x1,%ah # Invalid
+ stc # parameter
+read.2: ret # To caller
+
+read.3: pushl %edx # Save
movb $0x8,%ah # BIOS: Get drive
int $0x13 # parameters
movb %dh,%ch # Max head number
popl %edx # Restore
- jc return # If error
+ jc read.2 # If error
andb $0x3f,%cl # Sectors per track
- jz ereturn # If zero
- cli # Disable interrupts
+ jz read.1 # If zero
o16 # Get
- movw1r(0x8,_bp_,_ax) # LBA
+ movw1r(0x8,_si_,_ax) # LBA
pushl %edx # Save
movzbw %cl,%bx # Divide by
xorw %dx,%dx # sectors
@@ -174,14 +191,13 @@ read: movl %esp,%ebp # Address stack frame
movb %ch,%bl # Max head number
movb %dl,%ch # Sector number
incl %ebx # Divide by
- xorb %dl,%dl # number
- divw %bx,%ax # of heads
+ xorb %dl,%dl # number of
+ divw %bx,%ax # heads
movb %dl,%bh # Head number
popl %edx # Restore
o16 # Cylinder number
cmpl $0x3ff,%eax # supportable?
- sti # Enable interrupts
- ja ereturn # No
+ ja read.1 # No
xchgb %al,%ah # Set up cylinder
rorb $0x2,%al # number
orb %ch,%al # Merge
@@ -189,39 +205,37 @@ read: movl %esp,%ebp # Address stack frame
xchgl %eax,%ecx # number
movb %bh,%dh # Head number
subb %ah,%al # Sectors this track
- movb1r(0x3,_bp_,_ah) # Blocks to read
+ movb1r(0x2,_si_,_ah) # Blocks to read
cmpb %ah,%al # To read
- jb read.1 # this
+ jb read.4 # this
movb %ah,%al # track
-read.1: movwir(0x5,_di) # Try count
-read.2: lesw1r(0x4,_bp_,_bx) # Transfer buffer
+read.4: movwir(0x5,_bp) # Try count
+read.5: lesw1r(0x4,_si_,_bx) # Transfer buffer
pushl %eax # Save
- movb $0x2,%ah # BIOS: Read
- int $0x13 # from disk
+ movb $0x2,%ah # BIOS: Conventional
+ int $0x13 # read
popl %ebx # Restore
- jnc read.3 # If success
- decl %edi # Retry?
- jz read.5 # No
+ jnc read.6 # If success
+ decl %ebp # Retry?
+ jz read.7 # No
xorb %ah,%ah # BIOS: Reset
int $0x13 # disk system
- xchgl %ebx,%eax # Block count
- jmp read.2 # Continue
-read.3: movzbl %bl,%eax # Sectors read
- addwr1(_ax,0x8,_bp_) # Adjust
- jnc read.4 # LBA,
- incw1(0xa,_bp_) # transfer
-read.4: shlb %bl # buffer
- addbr1(_bl,0x5,_bp_) # pointer,
- subbr1(_al,0x3,_bp_) # block count
- ja read # If not done
-read.5: ret # To caller
+ movl %ebx,%eax # Block count
+ jmp read.5 # Continue
+read.6: movzbw %bl,%ax # Sectors read
+ o16 # Adjust
+ addwr1(_ax,0x8,_si_) # LBA,
+ shlb %bl # buffer
+ addbr1(_bl,0x5,_si_) # pointer,
+ subbr1(_al,0x2,_si_) # block count
+ ja read.3 # If not done
+read.7: ret # To caller
# Messages
-msg_read: .asciz "Read"
-msg_part: .asciz "Boot"
-
-prompt: .asciz " error\r\n"
+msg_read: .asciz "Read error"
+msg_part: .asciz "No bootable partition"
+msg_boot: .asciz "\r\nHit return to reboot: "
.org PRT_OFF,0x90
diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c
index fa6058bcccb7..bf9ed8c61f54 100644
--- a/sys/boot/i386/boot2/boot2.c
+++ b/sys/boot/i386/boot2/boot2.c
@@ -14,7 +14,7 @@
*/
/*
- * $Id: boot2.c,v 1.17 1999/01/10 13:29:52 peter Exp $
+ * $Id: boot2.c,v 1.6 1998/10/13 23:43:38 rnordier Exp $
*/
#include <sys/param.h>
@@ -53,9 +53,11 @@
#define PATH_CONFIG "/boot.config"
#define PATH_BOOT3 "/boot/loader"
#define PATH_KERNEL "/kernel"
+#define PATH_HELP "boot.help"
-#define ARGS 0x900
+#define ARGS 0x800
#define NOPT 11
+#define XOPT 2
#define BSIZEMAX 8192
#define NDEV 5
#define MEM_BASE 0x12
@@ -102,6 +104,7 @@ static struct dsk {
} dsk;
static char cmd[512];
static char kname[1024];
+static char help[2048];
static uint32_t opts;
static struct bootinfo bootinfo;
static int ls;
@@ -136,7 +139,7 @@ static int getc(int);
int
main(void)
{
- int autoboot, i;
+ int autoboot, helpon, i;
v86.ctl = V86_FLAGS;
dsk.drive = *(uint8_t *)PTOV(ARGS);
@@ -151,14 +154,11 @@ main(void)
for (i = 0; i < N_BIOS_GEOM; i++)
bootinfo.bi_bios_geom[i] = drvinfo(i);
autoboot = 2;
+ helpon = 1;
readfile(PATH_CONFIG, cmd, sizeof(cmd));
- if (*cmd) {
- printf("%s: %s", PATH_CONFIG, cmd);
- if (parse(cmd))
- autoboot = 0;
- *cmd = 0;
- }
- if (autoboot && !*kname) {
+ if (parse(cmd))
+ autoboot = 0;
+ else if (!*kname) {
if (autoboot == 2) {
memcpy(kname, PATH_BOOT3, sizeof(PATH_BOOT3));
if (!keyhit(0x37)) {
@@ -169,21 +169,21 @@ main(void)
if (autoboot == 1)
memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL));
}
+ readfile(PATH_HELP, help, sizeof(help));
for (;;) {
printf(" \n>> FreeBSD/i386 BOOT\n"
"Default: %u:%s(%u,%c)%s\n"
+ "%s"
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
- 'a' + dsk.part, kname);
+ 'a' + dsk.part, kname, helpon ? help : "");
if (ioctrl & 0x2)
sio_flush();
if (!autoboot || keyhit(0x5a))
getstr(cmd, sizeof(cmd));
- else
- putchar('\n');
- autoboot = 0;
+ autoboot = helpon = 0;
if (parse(cmd))
- putchar('\a');
+ helpon = 1;
else
load(kname);
}
@@ -226,16 +226,22 @@ load(const char *fname)
if (fmt == 0) {
addr = hdr.ex.a_entry & 0xffffff;
p = PTOV(addr);
+ printf("%s=0x%x ", "text", (unsigned)hdr.ex.a_text);
fs_off = PAGE_SIZE;
if (xfsread(ino, p, hdr.ex.a_text))
return;
p += roundup2(hdr.ex.a_text, PAGE_SIZE);
+ printf("%s=0x%x ", "data", (unsigned)hdr.ex.a_data);
if (xfsread(ino, p, hdr.ex.a_data))
return;
- p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
+ p += hdr.ex.a_data;
+ printf("%s=0x%x ", "bss", (unsigned)hdr.ex.a_bss);
+ p += roundup2(hdr.ex.a_bss, PAGE_SIZE);
bootinfo.bi_symtab = VTOP(p);
memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms));
p += sizeof(hdr.ex.a_syms);
+ printf("symbols=[");
+ printf("+0x%x", (unsigned)hdr.ex.a_syms);
if (hdr.ex.a_syms) {
if (xfsread(ino, p, hdr.ex.a_syms))
return;
@@ -245,6 +251,7 @@ load(const char *fname)
x = *(uint32_t *)p;
p += sizeof(int);
x -= sizeof(int);
+ printf("+0x%x", x);
if (xfsread(ino, p, x))
return;
p += x;
@@ -259,12 +266,15 @@ load(const char *fname)
}
for (i = 0; i < 2; i++) {
p = PTOV(ep[i].p_paddr & 0xffffff);
+ printf("%s=0x%x ", !i ? "text" : "data", ep[i].p_filesz);
fs_off = ep[i].p_offset;
if (xfsread(ino, p, ep[i].p_filesz))
return;
}
+ printf("%s=0x%x ", "bss", ep[1].p_memsz - ep[1].p_filesz);
p += roundup2(ep[1].p_memsz, PAGE_SIZE);
bootinfo.bi_symtab = VTOP(p);
+ printf("symbols=[");
if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
(hdr.eh.e_shstrndx + 1);
@@ -273,6 +283,7 @@ load(const char *fname)
for (i = 0; i < 2; i++) {
memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size));
p += sizeof(es[i].sh_size);
+ printf("+0x%x", es[i].sh_size);
fs_off = es[i].sh_offset;
if (xfsread(ino, p, es[i].sh_size))
return;
@@ -282,6 +293,7 @@ load(const char *fname)
addr = hdr.eh.e_entry & 0xffffff;
}
bootinfo.bi_esymtab = VTOP(p);
+ printf("]\nentry=0x%x\n", addr);
bootinfo.bi_kernelname = VTOP(fname);
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dsk.type, 0, dsk.slice, dsk.unit, dsk.part),
@@ -305,14 +317,16 @@ parse(char *arg)
for (i = 0; c != optstr[i]; i++)
if (i == NOPT - 1)
return -1;
- opts ^= 1 << flags[i];
+ if (i < XOPT)
+ opts ^= 1 << flags[i];
+ else
+ opts |= 1 << flags[i];
}
if (opts & 1 << RBX_PROBEKBD) {
i = *(uint8_t *)PTOV(0x496) & 0x10;
printf("Keyboard: %s\n", i ? "yes" : "no");
if (!i)
opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL;
- opts &= ~(1 << RBX_PROBEKBD);
}
ioctrl = opts & 1 << RBX_DUAL ? 0x3 :
opts & 1 << RBX_SERIAL ? 0x2 : 0x1;
@@ -469,7 +483,7 @@ fsread(ino_t inode, void *buf, size_t nbyte)
return -1;
}
fsblks = fs.fs_bsize >> DEV_BSHIFT;
- dsk.meta++;
+ dsk.meta = 1;
}
if (!inode)
return 0;
@@ -630,15 +644,9 @@ getstr(char *str, int size)
s = str;
do {
switch (c = getchar()) {
- case 0:
- break;
case '\b':
- if (s > str) {
+ if (s > str)
s--;
- putchar(c);
- putchar(' ');
- } else
- c = 0;
break;
case '\n':
*s = 0;
@@ -647,8 +655,7 @@ getstr(char *str, int size)
if (s - str < size - 1)
*s++ = c;
}
- if (c)
- putchar(c);
+ putchar(c);
} while (c != '\n');
}
@@ -731,12 +738,11 @@ drvread(void *buf, unsigned lba, unsigned nblk)
printf("%c\b", c = c << 8 | c >> 24);
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
- v86.addr = 0x704; /* call to xread in boot1 */
- v86.es = VTOPSEG(buf);
- v86.eax = lba;
- v86.ebx = VTOPOFF(buf);
- v86.ecx = lba >> 16;
- v86.edx = nblk << 8 | dsk.drive;
+ v86.addr = 0x604;
+ v86.eax = nblk;
+ v86.ebx = VTOPSEG(buf) << 16 | VTOPOFF(buf);
+ v86.ecx = lba;
+ v86.edx = 0x100 | dsk.drive;
v86int();
v86.ctl = V86_FLAGS;
if (V86_CY(v86.efl)) {
diff --git a/sys/boot/i386/boot2/sio.s b/sys/boot/i386/boot2/sio.s
index 92237b852b72..985ac04ef469 100644
--- a/sys/boot/i386/boot2/sio.s
+++ b/sys/boot/i386/boot2/sio.s
@@ -13,11 +13,11 @@
# purpose.
#
-# $Id: sio.s,v 1.2 1998/10/20 20:20:48 rnordier Exp $
+# $Id:$
- .set SIO_PRT,SIOPRT # Base port
- .set SIO_FMT,SIOFMT # 8N1
- .set SIO_DIV,(115200/SIOSPD) # 115200 / SPD
+ .set SIO_PRT,0x3f8 # Base port
+ .set SIO_FMT,0x3 # 8N1
+ .set SIO_DIV,0xc # 115200 / 9600
.globl sio_init
.globl sio_flush
diff --git a/sys/boot/i386/btx/btx/btx.s b/sys/boot/i386/btx/btx/btx.s
index 92842626d00f..d94fa2c11a27 100644
--- a/sys/boot/i386/btx/btx/btx.s
+++ b/sys/boot/i386/btx/btx/btx.s
@@ -13,7 +13,7 @@
# purpose.
#
-# $Id: btx.s,v 1.7 1998/11/01 13:52:52 rnordier Exp $
+# $Id: btx.s,v 1.5 1998/10/03 18:05:12 rnordier Exp $
#
# Memory layout.
@@ -340,7 +340,7 @@ intx00: pushb $0x0 # Int 0x0: #DE
intx10: pushb $0x10 # Int 0x10: #MF
jmp ex_noc # Floating-point error
#
-# Handle #GP exception.
+#
#
ex_v86: testb $0x2,0x12(%esp,1) # V86 mode?
jz except # No
@@ -459,7 +459,7 @@ v86mon.1: lodsb # Get opcode
v86mon.2: cmpb $0xf4,%al # HLT?
jne v86mon.3 # No
cmpl $inthlt+0x1,%esi # Is inthlt?
- jne v86mon.6 # No (ignore)
+ jne v86mon.4 # No
jmp intrtn # Return to user mode
v86mon.3: cmpb $0xfa,%al # CLI?
je v86cli # Yes
@@ -479,13 +479,13 @@ v86mon.3: cmpb $0xfa,%al # CLI?
cmpb $0xcf,%al # IRET/IRETD?
je v86iret # Yes
popl %ebx # Restore
- popa # Restore
+v86mon.4: popa # Restore
jmp except # Handle exception
-v86mon.4: movl %edx,0x30(%ebp) # Save V86 flags
-v86mon.5: popl %edx # V86 SS adjustment
+v86mon.5: movl %edx,0x30(%ebp) # Save V86 flags
+v86mon.6: popl %edx # V86 SS adjustment
subl %edx,%ebx # Save V86
movl %ebx,0x34(%ebp) # SP
-v86mon.6: subl %edi,%esi # From linear
+v86mon.7: subl %edi,%esi # From linear
movl %esi,0x28(%ebp) # Save V86 IP
popa # Restore
leal 0x8(%esp,1),%esp # Discard int no, error
@@ -494,12 +494,12 @@ v86mon.6: subl %edi,%esi # From linear
# Emulate CLI.
#
v86cli: andb $~0x2,0x31(%ebp) # Clear IF
- jmp v86mon.6 # Finish up
+ jmp v86mon.7 # Finish up
#
# Emulate STI.
#
v86sti: orb $0x2,0x31(%ebp) # Set IF
- jmp v86mon.6 # Finish up
+ jmp v86mon.7 # Finish up
#
# Emulate PUSHF/PUSHFD.
#
@@ -508,7 +508,7 @@ v86pushf: subl %ecx,%ebx # Adjust SP
je v86pushf.1 # Yes
o16 # 16-bit
v86pushf.1: movl %edx,(%ebx) # Save flags
- jmp v86mon.5 # Finish up
+ jmp v86mon.6 # Finish up
#
# Emulate IRET/IRETD.
#
@@ -529,7 +529,7 @@ v86popf.1: movl (%ebx),%eax # Load flags
andl $V86_FLG,%eax # Merge
andl $~V86_FLG,%edx # the
orl %eax,%edx # flags
- jmp v86mon.4 # Finish up
+ jmp v86mon.5 # Finish up
#
# Emulate INT imm8.
#
@@ -546,7 +546,7 @@ v86intn: lodsb # Get int no
movl %edi,0x2c(%ebp) # Save CS
xorl %edi,%edi # No ESI adjustment
andb $~0x3,%dh # Clear IF and TF
- jmp v86mon.4 # Finish up
+ jmp v86mon.5 # Finish up
#
# Hardware interrupt jump table.
#
@@ -693,12 +693,12 @@ intusr.4: shrl $0x4,%eax # Gives segment
xchgl %eax,%ebp # Get int no/address
testb $0x1,%dl # Address?
jnz intusr.5 # Yes
- shll $0x2,%eax # Scale
+ shll $0x2,%eax # XXX Scale
movl (%eax),%eax # Load int vector
-intusr.5: movl %eax,%ecx # Save
+intusr.5: movl %eax,%ecx # XXX Save
shrl $0x10,%eax # Gives segment
stosl # Set CS
- movw %cx,%ax # Restore
+ movw %cx,%ax # XXX Restore
stosl # Set EIP
leal 0x10(%esp,1),%esp # Discard seg regs
popa # Restore
@@ -755,7 +755,7 @@ dump.1: testb $DMP_X32,%ch # Dump long?
dump.2: testb $DMP_MEM,%ch # Dump memory?
jz dump.8 # No
pushl %ds # Save
- testb $0x2,0x52(%ebx) # V86 mode?
+ testb $0x2,0x52(%ebx) # XXX V86 mode?
jnz dump.3 # Yes
verrl 0x4(%esi) # Readable selector?
jnz dump.3 # No
diff --git a/sys/boot/i386/btx/btxldr/Makefile b/sys/boot/i386/btx/btxldr/Makefile
index 32cb4adb0b8e..9df9681867ec 100644
--- a/sys/boot/i386/btx/btxldr/Makefile
+++ b/sys/boot/i386/btx/btxldr/Makefile
@@ -1,7 +1,6 @@
-# $Id: Makefile,v 1.5 1998/10/13 18:29:18 rnordier Exp $
+# $Id: Makefile,v 1.4 1998/09/25 17:14:15 peter Exp $
ORG=0x100000
-AFLAGS+= --assembler-with-cpp
all: btxldr
@@ -15,7 +14,7 @@ btxldr: btxldr.o
.endif
btxldr.o: btxldr.s
- ${CC} ${AFLAGS} -c -o ${.TARGET} ${.CURDIR}/btxldr.s
+ ${AS} ${AFLAGS} -o ${.TARGET} ${.CURDIR}/btxldr.s
CLEANFILES+= btxldr btxldr.out btxldr.o
diff --git a/sys/boot/i386/btx/btxldr/btxldr.s b/sys/boot/i386/btx/btxldr/btxldr.s
index a3172e3e3cb5..7a6bd50b1a15 100644
--- a/sys/boot/i386/btx/btxldr/btxldr.s
+++ b/sys/boot/i386/btx/btxldr/btxldr.s
@@ -13,7 +13,7 @@
# purpose.
#
-# $Id: btxldr.s,v 1.3 1998/10/06 07:15:35 rnordier Exp $
+# $Id: btxldr.s,v 1.2 1998/10/06 06:13:36 msmith Exp $
#
# Prototype BTX loader program, written in a couple of hours. The
@@ -70,24 +70,24 @@ start: cld # String ops inc
shll $0xa,%eax # in bytes
movl %eax,%ebp # Base of user stack
movl $m_mem,%esi # Display
- call dhexout # amount of
- call dputstr # base memory
+ call hexout # amount of
+ call putstr # base memory
lgdt gdtdesc # Load new GDT
#
# Relocate caller's arguments.
#
movl $m_esp,%esi # Display
movl %esp,%eax # caller's
- call dhexout # stack
- call dputstr # pointer
+ call hexout # stack
+ call putstr # pointer
movl $m_args,%esi # Format string
leal 0x4(%esp,1),%ebx # First argument
movl $0x6,%ecx # Count
start.1: movl (%ebx),%eax # Get argument and
addl $0x4,%ebx # bump pointer
- call dhexout # Display it
+ call hexout # Display it
loop start.1 # Till done
- call dputstr # End message
+ call putstr # End message
movl $0x48,%ecx # Allocate space
subl %ecx,%ebp # for bootinfo
movl 0x18(%esp,1),%esi # Source
@@ -97,8 +97,8 @@ start.1: movl (%ebx),%eax # Get argument and
movl %ebp,0x18(%esp,1) # Update pointer
movl $m_rel_bi,%esi # Display
movl %ebp,%eax # bootinfo
- call dhexout # relocation
- call dputstr # message
+ call hexout # relocation
+ call putstr # message
movl $0x18,%ecx # Allocate space
subl %ecx,%ebp # for arguments
leal 0x4(%esp,1),%esi # Source
@@ -107,8 +107,8 @@ start.1: movl (%ebx),%eax # Get argument and
movsb # them
movl $m_rel_args,%esi # Display
movl %ebp,%eax # argument
- call dhexout # relocation
- call dputstr # message
+ call hexout # relocation
+ call putstr # message
#
# Set up BTX kernel.
#
@@ -145,16 +145,16 @@ start.1: movl (%ebx),%eax # Get argument and
movl %esi,%ebx # Keep place
movl $m_rel_btx,%esi # Restore
popl %eax # parameters
- call dhexout # and
+ call hexout # and
popl %ebp # display
movl %ebp,%eax # the
- call dhexout # relocation
- call dputstr # message
+ call hexout # relocation
+ call putstr # message
addl $PAG_SIZ,%ebp # Display
movl $m_base,%esi # the
movl %ebp,%eax # user
- call dhexout # base
- call dputstr # address
+ call hexout # base
+ call putstr # address
#
# Set up ELF-format client program.
#
@@ -164,7 +164,7 @@ start.1: movl (%ebx),%eax # Get argument and
call putstr # message
start.2: jmp start.2 # Hang
start.3: movl $m_elf,%esi # Display ELF
- call dputstr # message
+ call putstr # message
movl $m_segs,%esi # Format string
movl $0x2,%edi # Segment count
movl 0x1c(%ebx),%edx # Get e_phoff
@@ -173,14 +173,14 @@ start.3: movl $m_elf,%esi # Display ELF
start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
jne start.6 # No
movl 0x4(%edx),%eax # Display
- call dhexout # p_offset
+ call hexout # p_offset
movl 0x8(%edx),%eax # Display
- call dhexout # p_vaddr
+ call hexout # p_vaddr
movl 0x10(%edx),%eax # Display
- call dhexout # p_filesz
+ call hexout # p_filesz
movl 0x14(%edx),%eax # Display
- call dhexout # p_memsz
- call dputstr # End message
+ call hexout # p_memsz
+ call putstr # End message
pushl %esi # Save
pushl %edi # working
pushl %ecx # registers
@@ -205,7 +205,7 @@ start.5: popl %ecx # Restore
start.6: addl $0x20,%edx # To next entry
loop start.4 # Till done
start.7: movl $m_done,%esi # Display done
- call dputstr # message
+ call putstr # message
movl $start.8,%esi # Real mode stub
movl $MEM_STUB,%edi # Destination
movl $SIZ_STUB,%ecx # Size
@@ -229,10 +229,6 @@ start.9:
#
# Output message [ESI] followed by EAX in hex.
#
-dhexout:
-#ifndef BTXLDR_VERBOSE
- ret
-#endif
hexout: pushl %eax # Save
call putstr # Display message
popl %eax # Restore
@@ -258,12 +254,6 @@ hexout.2: decl %esi # Adjust for inc
#
# Output zero-terminated string [ESI] to the console.
#
-dputstr:
-#ifndef BTXLDR_VERBOSE
- ret
-#else
- jmp putstr
-#endif
putstr.0: call putchr # Output char
putstr: lodsb # Load char
testb %al,%al # End of string?
@@ -272,10 +262,6 @@ putstr: lodsb # Load char
#
# Output character AL to the console.
#
-dputchr:
-#ifndef BTXLDR_VERBOSE
- ret
-#endif
putchr: pusha # Save
xorl %ecx,%ecx # Zero for loops
movb $SCR_MAT,%ah # Mode/attribute
@@ -351,10 +337,7 @@ gdtdesc: .word gdt.1-gdt-1 # Limit
#
# Messages.
#
-m_logo: .asciz "\nBTX loader 0.01 "
-m_vers: .asciz "BTX version is \0\n"
-e_fmt: .asciz "Error: Client format not supported\n"
-#ifdef BTXLDR_VERBOSE
+m_logo: .asciz "\nBTX loader 0.01\n"
m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
m_esp: .asciz "Arguments passed (esp=\0):\n"
m_args: .asciz"<howto="
@@ -365,8 +348,10 @@ m_args: .asciz"<howto="
.asciz" bootinfo=\0>\n"
m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
+m_vers: .asciz "BTX version is \0\n"
m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
m_base: .asciz "Client base address is \0\n"
+e_fmt: .asciz "Error: Client format not supported\n"
m_elf: .asciz "Client format is ELF\n"
m_segs: .asciz "text segment: offset="
.asciz " vaddr="
@@ -377,7 +362,6 @@ m_segs: .asciz "text segment: offset="
.asciz " filesz="
.asciz " memsz=\0\n"
m_done: .asciz "Loading complete\n"
-#endif
#
# Uninitialized data area.
#
diff --git a/sys/boot/i386/btx/lib/btxv86.s b/sys/boot/i386/btx/lib/btxv86.s
index 46709a39540c..b67e873510e5 100644
--- a/sys/boot/i386/btx/lib/btxv86.s
+++ b/sys/boot/i386/btx/lib/btxv86.s
@@ -13,7 +13,7 @@
# purpose.
#
-# $Id: btxv86.s,v 1.1 1998/09/14 10:37:00 rnordier Exp $
+# $Id:$
#
# BTX V86 interface.
@@ -48,13 +48,11 @@
#
# V86 interface function.
#
-__v86int: popl __v86ret # Save return address
- pushl $__v86 # Push pointer
+__v86int: pushl $__v86 # Push pointer
call __v86_swap # Load V86 registers
int $INT_V86 # To BTX
call __v86_swap # Load user registers
addl $0x4,%esp # Discard pointer
- pushl __v86ret # Restore return address
ret # To user
#
# Swap V86 and user registers.
@@ -82,4 +80,3 @@ __v86_swap: xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
# V86 interface structure.
#
.comm __v86,SIZ_V86
- .comm __v86ret,4
diff --git a/sys/boot/i386/libi386/Makefile b/sys/boot/i386/libi386/Makefile
index 2cfd2e345956..ec22662921de 100644
--- a/sys/boot/i386/libi386/Makefile
+++ b/sys/boot/i386/libi386/Makefile
@@ -1,39 +1,26 @@
-# $Id: Makefile,v 1.12 1998/12/22 11:51:25 abial Exp $
+# $Id: Makefile,v 1.7 1998/09/30 22:36:45 peter Exp $
#
-LIB= i386
+LIB= i386
NOPIC=
NOPROFILE=
-INTERNALLIB= true
+INTERNALLIB= true
INTERNALSTATICLIB= true
-SRCS= aout_freebsd.c biosdisk.c biosmem.c biospnp.c biospci.c \
- bootinfo.c comconsole.c devicename.c elf_freebsd.c gatea20.c \
- i386_copy.c i386_module.c time.c vidconsole.c
+SRCS= aout_freebsd.c biosdisk.c biosmem.c bootinfo.c comconsole.c \
+ devicename.c elf_freebsd.c gatea20.c i386_copy.c i386_module.c time.c vidconsole.c
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
-I${.CURDIR}/../../.. -I.
-BOOT_COMCONSOLE_PORT?= 0x3f8
-CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT}
-
-BOOT_COMCONSOLE_SPEED?= 9600
-CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
-
# Make the disk code more talkative
#CFLAGS+= -DDISK_DEBUG
-# Include simple terminal emulation (cons25-compatible)
-CFLAGS+= -DTERM_EMU
-
-# If it's not there, don't consider it a target
-.if exists(${.CURDIR}/../../../i386/include)
-beforedepend ${OBJS}: machine
machine:
ln -sf ${.CURDIR}/../../../i386/include machine
-.endif
-
CLEANFILES+= machine
.include <bsd.lib.mk>
+
+beforedepend ${OBJS}: machine
diff --git a/sys/boot/i386/libi386/biosdisk.c b/sys/boot/i386/libi386/biosdisk.c
index 8b102aefbd5d..1337a92ac0d9 100644
--- a/sys/boot/i386/libi386/biosdisk.c
+++ b/sys/boot/i386/libi386/biosdisk.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: biosdisk.c,v 1.19 1999/01/09 02:36:19 msmith Exp $
+ * $Id: biosdisk.c,v 1.13 1998/10/11 10:01:55 peter Exp $
*/
/*
@@ -101,14 +101,10 @@ static int bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest);
static int bd_int13probe(struct bdinfo *bd);
-static void bd_printslice(struct open_disk *od, int offset, char *prefix);
-
static int bd_init(void);
static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
-static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
static int bd_open(struct open_file *f, ...);
static int bd_close(struct open_file *f);
-static void bd_print(int verbose);
struct devsw biosdisk = {
"disk",
@@ -117,8 +113,7 @@ struct devsw biosdisk = {
bd_strategy,
bd_open,
bd_close,
- noioctl,
- bd_print
+ noioctl
};
static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev);
@@ -174,6 +169,7 @@ bd_init(void)
/* XXX we need "disk aliases" to make this simpler */
printf("BIOS drive %c: is disk%d\n",
(unit < 0x80) ? ('A' + unit) : ('C' + unit - 0x80), nbdinfo);
+ bdinfo[nbdinfo].bd_unit = unit;
nbdinfo++;
}
}
@@ -204,91 +200,6 @@ bd_int13probe(struct bdinfo *bd)
}
/*
- * Print information about disks
- */
-static void
-bd_print(int verbose)
-{
- int i, j;
- char line[80];
- struct i386_devdesc dev;
- struct open_disk *od;
- struct dos_partition *dptr;
-
- for (i = 0; i < nbdinfo; i++) {
- sprintf(line, " disk%d: BIOS drive %c:\n", i,
- (bdinfo[i].bd_unit < 0x80) ? ('A' + bdinfo[i].bd_unit) : ('C' + bdinfo[i].bd_unit - 0x80));
- pager_output(line);
-
- /* try to open the whole disk */
- dev.d_kind.biosdisk.unit = i;
- dev.d_kind.biosdisk.slice = -1;
- dev.d_kind.biosdisk.partition = -1;
-
- if (!bd_opendisk(&od, &dev)) {
-
- /* Do we have a partition table? */
- if (od->od_flags & BD_PARTTABOK) {
- dptr = &od->od_parttab[0];
-
- /* Check for a "truly dedicated" disk */
- if ((dptr[3].dp_typ == DOSPTYP_386BSD) &&
- (dptr[3].dp_start == 0) &&
- (dptr[3].dp_size == 50000)) {
- sprintf(line, " disk%d", i);
- bd_printslice(od, 0, line);
- } else {
- for (j = 0; j < NDOSPART; j++) {
- switch(dptr[j].dp_typ) {
- case DOSPTYP_386BSD:
- sprintf(line, " disk%ds%d", i, j + 1);
- bd_printslice(od, dptr[j].dp_start, line);
- break;
- default:
- }
- }
-
- }
- }
- bd_closedisk(od);
- }
- }
-}
-
-static void
-bd_printslice(struct open_disk *od, int offset, char *prefix)
-{
- char line[80];
- u_char buf[BIOSDISK_SECSIZE];
- struct disklabel *lp;
- int i;
-
- /* read disklabel */
- if (bd_read(od, offset + LABELSECTOR, 1, buf))
- return;
- lp =(struct disklabel *)(&buf[0]);
- if (lp->d_magic != DISKMAGIC) {
- sprintf(line, "%s: bad disklabel\n");
- pager_output(line);
- return;
- }
-
- /* Print partitions */
- for (i = 0; i < lp->d_npartitions; i++) {
- if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) || (lp->d_partitions[i].p_fstype == FS_SWAP) ||
- ((lp->d_partitions[i].p_fstype == FS_UNUSED) &&
- (od->od_flags & BD_FLOPPY) && (i == 0))) { /* Floppies often have bogus fstype, print 'a' */
- sprintf(line, " %s%c: %s %.6dMB (%d - %d)\n", prefix, 'a' + i,
- (lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" : "FFS",
- lp->d_partitions[i].p_size / 2048, /* 512-byte sector assumption */
- lp->d_partitions[i].p_offset, lp->d_partitions[i].p_offset + lp->d_partitions[i].p_size);
- pager_output(line);
- }
- }
-}
-
-
-/*
* Attempt to open the disk described by (dev) for use by (f).
*
* Note that the philosophy here is "give them exactly what
@@ -391,14 +302,8 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
dptr = &od->od_parttab[0];
od->od_flags |= BD_PARTTABOK;
- /* Is this a request for the whole disk? */
- if (dev->d_kind.biosdisk.slice == -1) {
- sector == 0;
- goto unsliced;
- }
-
/* Try to auto-detect the best slice; this should always give a slice number */
- if (dev->d_kind.biosdisk.slice == 0)
+ if (dev->d_kind.biosdisk.slice < 1)
dev->d_kind.biosdisk.slice = bd_bestslice(dptr);
switch (dev->d_kind.biosdisk.slice) {
@@ -406,7 +311,6 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
error = ENOENT;
goto out;
case 0:
- sector = 0;
goto unsliced;
default:
break;
@@ -570,16 +474,6 @@ bd_closedisk(struct open_disk *od)
static int
bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
{
- struct bcache_devdata bcd;
-
- bcd.dv_strategy = bd_realstrategy;
- bcd.dv_devdata = devdata;
- return(bcache_strategy(&bcd, rw, dblk, size, buf, rsize));
-}
-
-static int
-bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
-{
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data);
int blks;
#ifdef BD_SUPPORT_FRAGS
@@ -747,10 +641,7 @@ bd_getgeom(struct open_disk *od)
}
/*
- * Return a suitable dev_t value for (dev).
- *
- * In the case where it looks like (dev) is a SCSI disk, we allow the number of
- * IDE disks to be specified in $num_ide_disks. There should be a Better Way.
+ * Return a suitable dev_t value for (dev)
*/
int
bd_getdev(struct i386_devdesc *dev)
@@ -759,8 +650,6 @@ bd_getdev(struct i386_devdesc *dev)
int biosdev;
int major;
int rootdev;
- char *nip, *cp;
- int unitofs = 0;
biosdev = bd_unit2bios(dev->d_kind.biosdisk.unit);
DEBUG("unit %d BIOS device %d", dev->d_kind.biosdisk.unit, biosdev);
@@ -783,13 +672,6 @@ bd_getdev(struct i386_devdesc *dev)
if ((od->od_flags & BD_LABELOK) && (od->od_disklabel.d_type == DTYPE_SCSI)) {
/* label OK, disk labelled as SCSI */
major = DAMAJOR;
- /* check for unit number correction hint */
- if ((nip = getenv("num_ide_disks")) != NULL) {
- unitofs = strtol(nip, &cp, 0);
- /* check for parse error */
- if ((cp == nip) || (*cp != 0))
- unitofs = 0;
- }
} else {
/* assume an IDE disk */
major = WDMAJOR;
@@ -798,7 +680,7 @@ bd_getdev(struct i386_devdesc *dev)
rootdev = MAKEBOOTDEV(major,
(dev->d_kind.biosdisk.slice + 1) >> 4, /* XXX slices may be wrong here */
(dev->d_kind.biosdisk.slice + 1) & 0xf,
- (biosdev & 0x7f) - unitofs, /* allow for #wd compenstation in da case */
+ biosdev & 0x7f, /* XXX allow/compute shift for da when wd present */
dev->d_kind.biosdisk.partition);
DEBUG("dev is 0x%x\n", rootdev);
return(rootdev);
diff --git a/sys/boot/i386/libi386/biospci.c b/sys/boot/i386/libi386/biospci.c
deleted file mode 100644
index 92f4fd28c297..000000000000
--- a/sys/boot/i386/libi386/biospci.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*-
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-/*
- * PnP enumerator using the PCI BIOS.
- */
-
-#include <stand.h>
-#include <string.h>
-#include <machine/stdarg.h>
-#include <bootstrap.h>
-#include <isapnp.h>
-#include <btxv86.h>
-
-/*
- * Stupid PCI BIOS interface doesn't let you simply enumerate everything
- * that's there, instead you have to ask it if it has something.
- *
- * So we have to scan by class code, subclass code and sometimes programming
- * interface.
- */
-
-struct pci_progif
-{
- int pi_code;
- char *pi_name;
-};
-
-static struct pci_progif progif_null[] = {
- {0x0, NULL},
- {-1, NULL}
-};
-
-static struct pci_progif progif_display[] = {
- {0x0, "VGA"},
- {0x1, "8514"},
- {-1, NULL}
-};
-
-static struct pci_progif progif_ide[] = {
- {0x00, NULL},
- {0x01, NULL},
- {0x02, NULL},
- {0x03, NULL},
- {0x04, NULL},
- {0x05, NULL},
- {0x06, NULL},
- {0x07, NULL},
- {0x08, NULL},
- {0x09, NULL},
- {0x0a, NULL},
- {0x0b, NULL},
- {0x0c, NULL},
- {0x0d, NULL},
- {0x0e, NULL},
- {0x0f, NULL},
- {0x80, NULL},
- {0x81, NULL},
- {0x82, NULL},
- {0x83, NULL},
- {0x84, NULL},
- {0x85, NULL},
- {0x86, NULL},
- {0x87, NULL},
- {0x88, NULL},
- {0x89, NULL},
- {0x8a, NULL},
- {0x8b, NULL},
- {0x8c, NULL},
- {0x8d, NULL},
- {0x8e, NULL},
- {0x8f, NULL},
- {-1, NULL}
-};
-
-static struct pci_progif progif_serial[] = {
- {0x0, "8250"},
- {0x1, "16450"},
- {0x2, "16550"},
- {-1, NULL}
-};
-
-static struct pci_progif progif_parallel[] = {
- {0x0, "Standard"},
- {0x1, "Bidirectional"},
- {0x2, "ECP"},
- {-1, NULL}
-};
-
-
-struct pci_subclass
-{
- int ps_subclass;
- char *ps_name;
- struct pci_progif *ps_progif; /* if set, use for programming interface value(s) */
-};
-
-static struct pci_subclass subclass_old[] = {
- {0x0, "Old non-VGA", progif_null},
- {0x1, "Old VGA", progif_null},
- {-1, NULL, NULL}
-};
-
-static struct pci_subclass subclass_mass[] = {
- {0x0, "SCSI", progif_null},
- {0x1, "IDE", progif_ide},
- {0x2, "Floppy disk", progif_null},
- {0x3, "IPI", progif_null},
- {0x4, "RAID", progif_null},
- {0x80, "mass storage", progif_null},
- {-1, NULL, NULL}
-};
-
-static struct pci_subclass subclass_net[] = {
- {0x0, "Ethernet", progif_null},
- {0x1, "Token ring", progif_null},
- {0x2, "FDDI", progif_null},
- {0x3, "ATM", progif_null},
- {0x80, "network", progif_null},
- {-1, NULL, NULL}
-};
-
-static struct pci_subclass subclass_display[] = {
- {0x0, NULL, progif_display},
- {0x1, "XGA", progif_null},
- {0x80, "other", progif_null},
- {-1, NULL, NULL}
-};
-
-static struct pci_subclass subclass_comms[] = {
- {0x0, "serial", progif_serial},
- {0x1, "parallel", progif_parallel},
- {0x80, "communications", progif_null},
- {-1, NULL, NULL}
-};
-
-static struct pci_subclass subclass_serial[] = {
- {0x0, "Firewire", progif_null},
- {0x1, "ACCESS.bus", progif_null},
- {0x2, "SSA", progif_null},
- {0x3, "USB", progif_null},
- {0x4, "Fibrechannel", progif_null},
- {-1, NULL, NULL}
-};
-
-static struct pci_class
-{
- int pc_class;
- char *pc_name;
- struct pci_subclass *pc_subclass;
-} pci_classes[] = {
- {0x0, "device", subclass_old},
- {0x1, "controller", subclass_mass},
- {0x2, "controller", subclass_net},
- {0x3, "display", subclass_display},
- {0x7, "controller", subclass_comms},
- {0xc, "controller", subclass_serial},
- {-1, NULL, NULL}
-};
-
-
-static void biospci_enumerate(void);
-static void biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi);
-
-static int biospci_version;
-static int biospci_hwcap;
-
-struct pnphandler biospcihandler =
-{
- "PCI BIOS",
- biospci_enumerate
-};
-
-static void
-biospci_enumerate(void)
-{
- int index, locator, devid;
- struct pci_class *pc;
- struct pci_subclass *psc;
- struct pci_progif *ppi;
-
- /* Find the PCI BIOS */
- v86.ctl = V86_FLAGS;
- v86.addr = 0x1a;
- v86.eax = 0xb101;
- v86.edi = 0x0;
- v86int();
-
- /* Check for OK response */
- if ((v86.efl & 1) || ((v86.eax & 0xff00) != 0) || (v86.edx != 0x20494350))
- return;
-
- biospci_version = v86.ebx & 0xffff;
- biospci_hwcap = v86.eax & 0xff;
-#if 0
- printf("PCI BIOS %d.%d%s%s\n",
- bcd2bin((biospci_version >> 8) & 0xf), bcd2bin(biospci_version & 0xf),
- (biospci_hwcap & 1) ? " config1" : "", (biospci_hwcap & 2) ? " config2" : "");
-#endif
- /* Iterate over known classes */
- for (pc = pci_classes; pc->pc_class >= 0; pc++) {
- /* Iterate over subclasses */
- for (psc = pc->pc_subclass; psc->ps_subclass >= 0; psc++) {
- /* Iterate over programming interfaces */
- for (ppi = psc->ps_progif; ppi->pi_code >= 0; ppi++) {
-
- /* Scan for matches */
- for (index = 0; ; index++) {
-
- /* Look for a match */
- v86.ctl = V86_FLAGS;
- v86.addr = 0x1a;
- v86.eax = 0xb103;
- v86.ecx = (pc->pc_class << 16) + (psc->ps_subclass << 8) + ppi->pi_code;
- v86.esi = index;
- v86int();
- /* error/end of matches */
- if ((v86.efl & 1) || (v86.eax & 0xff00))
- break;
-
- /* Got something */
- locator = v86.ebx;
-
- /* Read the device identifier from the nominated device */
- v86.ctl = V86_FLAGS;
- v86.addr = 0x1a;
- v86.eax = 0xb10a;
- v86.ebx = locator;
- v86.edi = 0x0;
- v86int();
- /* error */
- if ((v86.efl & 1) || (v86.eax & 0xff00))
- break;
-
- /* We have the device ID, create a PnP object and save everything */
- devid = v86.ecx;
- biospci_addinfo(devid, pc, psc, ppi);
- }
- }
- }
- }
-}
-
-static void
-biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi)
-{
- struct pnpinfo *pi;
- char desc[80];
-
-
- /* build the description */
- desc[0] = 0;
- if (ppi->pi_name != NULL) {
- strcat(desc, ppi->pi_name);
- strcat(desc, " ");
- }
- if (psc->ps_name != NULL) {
- strcat(desc, psc->ps_name);
- strcat(desc, " ");
- }
- if (pc->pc_name != NULL)
- strcat(desc, pc->pc_name);
-
- pi = pnp_allocinfo();
- pi->pi_desc = strdup(desc);
- sprintf(desc,"0x%08x", devid);
- pnp_addident(pi, desc);
- pnp_addinfo(pi);
-}
diff --git a/sys/boot/i386/libi386/biospnp.c b/sys/boot/i386/libi386/biospnp.c
deleted file mode 100644
index a6064ba27462..000000000000
--- a/sys/boot/i386/libi386/biospnp.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*-
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: biospnp.c,v 1.2 1998/10/23 22:29:08 msmith Exp $
- */
-
-/*
- * PnP BIOS enumerator.
- */
-
-#include <stand.h>
-#include <string.h>
-#include <machine/stdarg.h>
-#include <bootstrap.h>
-#include <isapnp.h>
-#include <btxv86.h>
-
-
-static int biospnp_init(void);
-static void biospnp_enumerate(void);
-
-struct pnphandler biospnphandler =
-{
- "PnP BIOS",
- biospnp_enumerate
-};
-
-struct pnp_ICstructure
-{
- u_int8_t pnp_signature[4] __attribute__ ((packed));
- u_int8_t pnp_version __attribute__ ((packed));
- u_int8_t pnp_length __attribute__ ((packed));
- u_int16_t pnp_BIOScontrol __attribute__ ((packed));
- u_int8_t pnp_checksum __attribute__ ((packed));
- u_int32_t pnp_eventflag __attribute__ ((packed));
- u_int16_t pnp_rmip __attribute__ ((packed));
- u_int16_t pnp_rmcs __attribute__ ((packed));
- u_int16_t pnp_pmip __attribute__ ((packed));
- u_int32_t pnp_pmcs __attribute__ ((packed));
- u_int8_t pnp_OEMdev[4] __attribute__ ((packed));
- u_int16_t pnp_rmds __attribute__ ((packed));
- u_int32_t pnp_pmds __attribute__ ((packed));
-};
-
-struct pnp_devNode
-{
- u_int16_t dn_size __attribute__ ((packed));
- u_int8_t dn_handle __attribute__ ((packed));
- u_int8_t dn_id[4] __attribute__ ((packed));
- u_int8_t dn_type[3] __attribute__ ((packed));
- u_int16_t dn_attrib __attribute__ ((packed));
- u_int8_t dn_data[0] __attribute__ ((packed));
-};
-
-struct pnp_isaConfiguration
-{
- u_int8_t ic_revision __attribute__ ((packed));
- u_int8_t ic_nCSN __attribute__ ((packed));
- u_int16_t ic_rdport __attribute__ ((packed));
- u_int16_t ic_reserved __attribute__ ((packed));
-};
-
-static struct pnp_ICstructure *pnp_Icheck = NULL;
-static u_int16_t pnp_NumNodes;
-static u_int16_t pnp_NodeSize;
-
-static void biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn);
-static int biospnp_call(int func, char *fmt, ...);
-
-#define vsegofs(vptr) (((u_int32_t)VTOPSEG(vptr) << 16) + VTOPOFF(vptr))
-void (* v86bios)(u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) = (void *)v86int;
-
-#define biospnp_f00(NumNodes, NodeSize) biospnp_call(0x00, "ll", NumNodes, NodeSize)
-#define biospnp_f01(Node, devNodeBuffer, Control) biospnp_call(0x01, "llw", Node, devNodeBuffer, Control)
-#define biospnp_f40(Configuration) biospnp_call(0x40, "l", Configuration)
-
-/* PnP BIOS return codes */
-#define PNP_SUCCESS 0x00
-#define PNP_FUNCTION_NOT_SUPPORTED 0x80
-
-/*
- * Initialisation: locate the PnP BIOS, test that we can call it.
- * Returns nonzero if the PnP BIOS is not usable on this system.
- */
-static int
-biospnp_init(void)
-{
- struct pnp_isaConfiguration icfg;
- char *sigptr;
- int result;
-
- /* Search for the $PnP signature */
- pnp_Icheck = NULL;
- for (sigptr = PTOV(0xf0000); sigptr < PTOV(0xfffff); sigptr += 16)
- if (!bcmp(sigptr, "$PnP", 4)) {
- pnp_Icheck = (struct pnp_ICstructure *)sigptr;
- break;
- }
-
- /* No signature, no BIOS */
- if (pnp_Icheck == NULL)
- return(1);
-
- /*
- * Fetch the system table parameters as a test of the BIOS
- */
- result = biospnp_f00(vsegofs(&pnp_NumNodes), vsegofs(&pnp_NodeSize));
- if (result != PNP_SUCCESS) {
- return(1);
- }
-
- /*
- * Look for the PnP ISA configuration table
- */
- result = biospnp_f40(vsegofs(&icfg));
- switch (result) {
- case PNP_SUCCESS:
- /* If the BIOS found some PnP devices, take its hint for the read port */
- if ((icfg.ic_revision == 1) && (icfg.ic_nCSN > 0))
- isapnp_readport = icfg.ic_rdport;
- break;
- case PNP_FUNCTION_NOT_SUPPORTED:
- /* The BIOS says there is no ISA bus (should we trust that this works?) */
- printf("PnP BIOS claims no ISA bus\n");
- isapnp_readport = -1;
- break;
- }
- return(0);
-}
-
-static void
-biospnp_enumerate(void)
-{
- u_int8_t Node;
- struct pnp_devNode *devNodeBuffer;
- int result;
- struct pnpinfo *pi;
- int count;
-
- /* Init/check state */
- if (biospnp_init())
- return;
-
- devNodeBuffer = (struct pnp_devNode *)malloc(pnp_NodeSize);
- Node = 0;
- count = 1000;
- while((Node != 0xff) && (count-- > 0)) {
- result = biospnp_f01(vsegofs(&Node), vsegofs(devNodeBuffer), 0x1);
- if (result != PNP_SUCCESS) {
- printf("PnP BIOS node %d: error 0x%x\n", Node, result);
- } else {
- pi = pnp_allocinfo();
- pnp_addident(pi, pnp_eisaformat(devNodeBuffer->dn_id));
- biospnp_scanresdata(pi, devNodeBuffer);
- pnp_addinfo(pi);
- }
- }
-}
-
-/*
- * Scan the resource data in the node's data area for compatible device IDs
- * and descriptions.
- */
-static void
-biospnp_scanresdata(struct pnpinfo *pi, struct pnp_devNode *dn)
-{
- int tag, i, rlen, dlen;
- u_int8_t *p;
- char *str;
-
- p = dn->dn_data; /* point to resource data */
- dlen = dn->dn_size - (p - (u_int8_t *)dn); /* length of resource data */
-
- for (i = 0; i < dlen; i+= rlen) {
- tag = p[i];
- i++;
- if (PNP_RES_TYPE(tag) == 0) {
- rlen = PNP_SRES_LEN(tag);
- /* small resource */
- switch (PNP_SRES_NUM(tag)) {
-
- case COMP_DEVICE_ID:
- /* got a compatible device ID */
- pnp_addident(pi, pnp_eisaformat(p + i));
- break;
-
- case END_TAG:
- return;
- }
- } else {
- /* large resource */
- rlen = *(u_int16_t *)(p + i);
- i += sizeof(u_int16_t);
-
- switch(PNP_LRES_NUM(tag)) {
-
- case ID_STRING_ANSI:
- str = malloc(rlen + 1);
- bcopy(p + i, str, rlen);
- str[rlen] = 0;
- if (pi->pi_desc == NULL) {
- pi->pi_desc = str;
- } else {
- free(str);
- }
- break;
- }
- }
- }
-}
-
-
-/*
- * Make a 16-bit realmode PnP BIOS call.
- *
- * The first argument passed is the function number, the last is the
- * BIOS data segment selector. Intermediate arguments may be 16 or
- * 32 bytes in length, and are described by the format string.
- *
- * Arguments to the BIOS functions must be packed on the stack, hence
- * this evil.
- */
-static int
-biospnp_call(int func, char *fmt, ...)
-{
- va_list ap;
- char *p;
- u_int8_t *argp;
- u_int32_t args[4];
- u_int32_t i;
-
- /* function number first */
- argp = (u_int8_t *)args;
- *(u_int16_t *)argp = func;
- argp += sizeof(u_int16_t);
-
- /* take args according to format */
- va_start(ap, fmt);
- for (p = fmt; *p != 0; p++) {
- switch(*p) {
-
- case 'w':
- i = va_arg(ap, u_int16_t);
- *(u_int16_t *)argp = i;
- argp += sizeof(u_int16_t);
- break;
-
- case 'l':
- i = va_arg(ap, u_int32_t);
- *(u_int32_t *)argp = i;
- argp += sizeof(u_int32_t);
- break;
- }
- }
-
- /* BIOS segment last */
- *(u_int16_t *)argp = pnp_Icheck->pnp_rmds;
- argp += sizeof(u_int16_t);
-
- /* prepare for call */
- v86.ctl = V86_ADDR | V86_CALLF;
- v86.addr = ((u_int32_t)pnp_Icheck->pnp_rmcs << 16) + pnp_Icheck->pnp_rmip;
-
- /* call with packed stack and return */
- v86bios(args[0], args[1], args[2], args[3]);
- return(v86.eax & 0xffff);
-}
diff --git a/sys/boot/i386/libi386/bootinfo.c b/sys/boot/i386/libi386/bootinfo.c
index 77ba8b75a83a..5b479cd3446e 100644
--- a/sys/boot/i386/libi386/bootinfo.c
+++ b/sys/boot/i386/libi386/bootinfo.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bootinfo.c,v 1.14 1998/10/15 17:06:36 peter Exp $
+ * $Id: bootinfo.c,v 1.13 1998/10/14 05:07:23 peter Exp $
*/
#include <stand.h>
@@ -249,7 +249,9 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
printf("can't determine root device\n");
return(EINVAL);
}
-
+
+ /* Boot from whatever the current device is */
+ i386_getdev((void **)(&rootdev), NULL, NULL);
switch(rootdev->d_type) {
case DEVT_DISK:
/* pass in the BIOS device number of the current disk */
diff --git a/sys/boot/i386/libi386/comconsole.c b/sys/boot/i386/libi386/comconsole.c
index 7b35d1dce8c9..261e909d225b 100644
--- a/sys/boot/i386/libi386/comconsole.c
+++ b/sys/boot/i386/libi386/comconsole.c
@@ -22,45 +22,16 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: comconsole.c,v 1.5 1998/11/22 07:59:16 rnordier Exp $
+ * From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
+ *
+ * $Id: comconsole.c,v 1.3 1998/10/02 16:32:45 msmith Exp $
*/
#include <stand.h>
#include <bootstrap.h>
-#include <machine/cpufunc.h>
+#include <btxv86.h>
#include "libi386.h"
-/* selected defines from ns16550.h */
-#define com_data 0 /* data register (R/W) */
-#define com_dlbl 0 /* divisor latch low (W) */
-#define com_dlbh 1 /* divisor latch high (W) */
-#define com_ier 1 /* interrupt enable (W) */
-#define com_iir 2 /* interrupt identification (R) */
-#define com_fifo 2 /* FIFO control (W) */
-#define com_lctl 3 /* line control register (R/W) */
-#define com_cfcr 3 /* line control register (R/W) */
-#define com_mcr 4 /* modem control register (R/W) */
-#define com_lsr 5 /* line status register (R/W) */
-#define com_msr 6 /* modem status register (R/W) */
-
-/* selected defines from sioreg.h */
-#define CFCR_DLAB 0x80
-#define MCR_RTS 0x02
-#define MCR_DTR 0x01
-#define LSR_TXRDY 0x20
-#define LSR_RXRDY 0x01
-
-#define COMC_FMT 0x3 /* 8N1 */
-#define COMC_TXWAIT 0x40000 /* transmit timeout */
-#define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */
-
-#ifndef COMPORT
-#define COMPORT 0x3f8
-#endif
-#ifndef COMSPEED
-#define COMSPEED 9600
-#endif
-
static void comc_probe(struct console *cp);
static int comc_init(int arg);
static void comc_putchar(int c);
@@ -71,7 +42,7 @@ static int comc_started;
struct console comconsole = {
"comconsole",
- "serial port",
+ "BIOS serial port",
0,
comc_probe,
comc_init,
@@ -80,6 +51,8 @@ struct console comconsole = {
comc_ischar
};
+#define BIOS_COMPORT 0
+
static void
comc_probe(struct console *cp)
{
@@ -90,19 +63,19 @@ comc_probe(struct console *cp)
static int
comc_init(int arg)
{
+ int i;
+
if (comc_started && arg == 0)
return 0;
comc_started = 1;
+ v86.ctl = 0;
+ v86.addr = 0x14;
+ v86.eax = 0xe3; /* 9600N81 */
+ v86.edx = BIOS_COMPORT; /* XXX take as arg, or use env var? */
+ v86int();
- outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT);
- outb(COMPORT + com_dlbl, COMC_BPS(COMSPEED) & 0xff);
- outb(COMPORT + com_dlbh, COMC_BPS(COMSPEED) >> 8);
- outb(COMPORT + com_cfcr, COMC_FMT);
- outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR);
-
- do
- inb(COMPORT + com_data);
- while (inb(COMPORT + com_lsr) & LSR_RXRDY);
+ for(i = 0; i < 10 && comc_ischar(); i++)
+ (void)comc_getchar();
return(0);
}
@@ -110,23 +83,35 @@ comc_init(int arg)
static void
comc_putchar(int c)
{
- int wait;
-
- for (wait = COMC_TXWAIT; wait > 0; wait--)
- if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
- outb(COMPORT + com_data, c);
- break;
- }
+ v86.ctl = 0;
+ v86.addr = 0x14;
+ v86.eax = 0x100 | c; /* Function 1 = write */
+ v86.edx = BIOS_COMPORT; /* XXX take as arg, or use env var? */
+ v86int();
}
static int
comc_getchar(void)
{
- return(comc_ischar() ? inb(COMPORT + com_data) : -1);
+ if (comc_ischar()) {
+ v86.ctl = 0;
+ v86.addr = 0x14;
+ v86.eax = 0x200; /* Function 2 = read */
+ v86.edx = BIOS_COMPORT; /* XXX take as arg, or use env var? */
+ v86int();
+ return(v86.eax & 0xff);
+ } else {
+ return(-1);
+ }
}
static int
comc_ischar(void)
{
- return(inb(COMPORT + com_lsr) & LSR_RXRDY);
+ v86.ctl = 0;
+ v86.addr = 0x14;
+ v86.eax = 0x300; /* Function 3 = status */
+ v86.edx = BIOS_COMPORT; /* XXX take as arg, or use env var? */
+ v86int();
+ return(v86.eax & 0x100); /* AH bit 1 is "receive data ready" */
}
diff --git a/sys/boot/i386/libi386/vidconsole.c b/sys/boot/i386/libi386/vidconsole.c
index 05e77110c2ef..c67cd72061b5 100644
--- a/sys/boot/i386/libi386/vidconsole.c
+++ b/sys/boot/i386/libi386/vidconsole.c
@@ -26,7 +26,7 @@
*
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
*
- * $Id: vidconsole.c,v 1.10 1998/12/31 13:44:04 abial Exp $
+ * $Id: vidconsole.c,v 1.5 1998/10/07 07:34:31 msmith Exp $
*/
#include <stand.h>
@@ -48,28 +48,6 @@ static int vidc_ischar(void);
static int vidc_started;
-#ifdef TERM_EMU
-void end_term();
-void bail_out(int c);
-void vidc_term_emu(int c);
-void get_pos(void);
-void curs_move(int x, int y);
-void write_char(int c, int fg, int bg);
-void scroll_up(int rows, int fg, int bg);
-void AB(void);
-void AF(void);
-void CD(void);
-void CM(void);
-void HO(void);
-void ME(void);
-
-static int args[2],argc,br;
-static int fg,bg,dig;
-static int fg_c,bg_c,curx,cury;
-static int esc;
-#endif
-
-
struct console vidconsole = {
"vidconsole",
"internal video/keyboard",
@@ -106,390 +84,21 @@ vidc_init(int arg)
if (vidc_started && arg == 0)
return;
vidc_started = 1;
-#ifdef TERM_EMU
- /* Init terminal emulator */
- end_term();
- get_pos();
- curs_move(curx,cury);
- fg_c=7;
- bg_c=0;
-#endif
for(i = 0; i < 10 && vidc_ischar(); i++)
(void)vidc_getchar();
return(0); /* XXX reinit? */
}
static void
-vidc_biosputchar(int c)
+vidc_putchar(int c)
{
v86.ctl = 0;
v86.addr = 0x10;
- v86.eax = 0xe00 | (c & 0xff);
+ v86.eax = 0xe00 | c;
v86.ebx = 0x7;
v86int();
}
-static void
-vidc_rawputchar(int c)
-{
- int i;
-
- if(c == '\t')
- /* lame tab expansion */
- for (i = 0; i < 8; i++)
- vidc_rawputchar(' ');
- else {
-#ifndef TERM_EMU
- vidc_biosputchar(c);
-#else
- /* Emulate AH=0eh (teletype output) */
- switch(c) {
- case '\a':
- vidc_biosputchar(c);
- return;
- case '\r':
- curx=0;
- curs_move(curx,cury);
- return;
- case '\n':
- cury++;
- if(cury>24) {
- scroll_up(1,fg_c,bg_c);
- cury--;
- } else {
- curs_move(curx,cury);
- }
- return;
- case '\b':
- if(curx>0) {
- curx--;
- curs_move(curx,cury);
- /* write_char(' ',fg_c,bg_c); XXX destructive(!) */
- return;
- }
- return;
- default:
- write_char(c,fg_c,bg_c);
- curx++;
- if(curx>79) {
- curx=0;
- cury++;
- }
- if(cury>24) {
- curx=0;
- scroll_up(1,fg_c,bg_c);
- cury--;
- }
- }
- curs_move(curx,cury);
-#endif
- }
-}
-
-#ifdef TERM_EMU
-
-/* Get cursor position on the screen. Result is in edx. Sets
- * curx and cury appropriately.
- */
-void
-get_pos(void)
-{
- v86.ctl = 0;
- v86.addr = 0x10;
- v86.eax = 0x0300;
- v86.ebx = 0x0;
- v86int();
- curx=v86.edx & 0x00ff;
- cury=(v86.edx & 0xff00)>>8;
-}
-
-/* Move cursor to x rows and y cols (0-based). */
-void
-curs_move(int x, int y)
-{
- v86.ctl = 0;
- v86.addr = 0x10;
- v86.eax = 0x0200;
- v86.ebx = 0x0;
- v86.edx = ((0x00ff & y)<<8)+(0x00ff & x);
- v86int();
- curx=x;
- cury=y;
- /* If there is ctrl char at this position, cursor would be invisible.
- * Make it a space instead.
- */
- v86.ctl=0;
- v86.addr = 0x10;
- v86.eax = 0x0800;
- v86.ebx= 0x0;
- v86int();
-#define isvisible(c) (((c)>32) && ((c)<255))
- if(!isvisible(v86.eax & 0x00ff)) {
- write_char(' ',fg_c,bg_c);
- }
-}
-
-/* Scroll up the whole window by a number of rows. If rows==0,
- * clear the window. fg and bg are attributes for the new lines
- * inserted in the window.
- */
-void
-scroll_up(int rows, int fg, int bg)
-{
- if(rows==0) rows=25;
- v86.ctl = 0;
- v86.addr = 0x10;
- v86.eax = 0x0600+(0x00ff & rows);
- v86.ebx = (bg<<12)+(fg<<8);
- v86.ecx = 0x0;
- v86.edx = 0x184f;
- v86int();
-}
-
-/* Write character and attribute at cursor position. */
-void
-write_char(int c, int fg, int bg)
-{
- v86.ctl=0;
- v86.addr = 0x10;
- v86.eax = 0x0900+(0x00ff & c);
- v86.ebx = (bg<<4)+fg;
- v86.ecx = 0x1;
- v86int();
-}
-
-/* Calculate power of 10 */
-int
-pow10(int i)
-{
- int res=1;
-
- while(i-->0) {
- res*=10;
- }
- return res;
-}
-
-/**************************************************************/
-/*
- * Screen manipulation functions. They use accumulated data in
- * args[] and argc variables.
- *
- */
-
-/* Set background color */
-void
-AB(void){
- bg_c=args[0];
- end_term();
-}
-
-/* Set foreground color */
-void
-AF(void)
-{
- fg_c=args[0];
- end_term();
-}
-
-/* Clear display from current position to end of screen */
-void
-CD(void)
-{
- get_pos();
- v86.ctl = 0;
- v86.addr = 0x10;
- v86.eax = 0x0600;
- v86.ebx = (bg_c<<4)+fg_c;
- v86.ecx = v86.edx;
- v86.edx = 0x184f;
- v86int();
- curx=0;
- curs_move(curx,cury);
- end_term();
-}
-
-/* Absolute cursor move to args[0] rows and args[1] columns
- * (the coordinates are 1-based).
- */
-void
-CM(void)
-{
- if(args[0]>0) args[0]--;
- if(args[1]>0) args[1]--;
- curs_move(args[1],args[0]);
- end_term();
-}
-
-/* Home cursor (left top corner) */
-void
-HO(void)
-{
- argc=1;
- args[0]=args[1]=1;
- CM();
-}
-
-/* Exit attribute mode (reset fore/back-ground colors to defaults) */
-void
-ME(void)
-{
- fg_c=7;
- bg_c=0;
- end_term();
-}
-
-/* Clear internal state of the terminal emulation code */
-void
-end_term(void)
-{
- esc=0;
- argc=-1;
- fg=bg=br=0;
- args[0]=args[1]=0;
- dig=0;
-}
-
-/* Gracefully exit ESC-sequence processing in case of misunderstanding */
-void
-bail_out(int c)
-{
- char buf[6],*ch;
-
- if(esc) vidc_rawputchar('\033');
- if(br) vidc_rawputchar('[');
- if(argc>-1) {
- sprintf(buf,"%d",args[0]);
- ch=buf;
- while(*ch) vidc_rawputchar(*ch++);
-
- if(argc>0) {
- vidc_rawputchar(';');
- sprintf(buf,"%d",args[1]);
- ch=buf;
- while(*ch) vidc_rawputchar(*ch++);
- }
- }
- vidc_rawputchar(c);
- end_term();
-}
-
-/* Emulate basic capabilities of cons25 terminal */
-void
-vidc_term_emu(int c)
-{
-
- if(!esc) {
- if(c=='\033') {
- esc=1;
- } else {
- vidc_rawputchar(c);
- }
- return;
- }
-
- /* Do ESC sequences processing */
- switch(c) {
- case '\033':
- /* ESC in ESC sequence - error */
- bail_out(c);
- break;
- case '[':
- /* Check if it's first char after ESC */
- if(argc<0) {
- br=1;
- } else {
- bail_out(c);
- }
- break;
- case 'H':
- /* Emulate \E[H (cursor home) and
- * \E%d;%dH (cursor absolute move) */
- if(br) {
- switch(argc) {
- case -1:
- HO();
- break;
- case 1:
- if(fg) args[0]+=pow10(dig)*3;
- if(bg) args[0]+=pow10(dig)*4;
- CM();
- break;
- default:
- bail_out(c);
- }
- } else bail_out(c);
- break;
- case 'J':
- /* Emulate \EJ (clear to end of screen) */
- if(br && argc<0) {
- CD();
- } else bail_out(c);
- break;
- case ';':
- /* perhaps args separator */
- if(br && (argc>-1)) {
- argc++;
- } else bail_out(c);
- break;
- case 'm':
- /* Change char attributes */
- if(br) {
- switch(argc) {
- case -1:
- ME();
- break;
- case 0:
- if(fg) AF();
- else AB();
- break;
- default:
- bail_out(c);
- }
- } else bail_out(c);
- break;
- default:
- if(isdigit(c)) {
- /* Carefully collect numeric arguments */
- /* XXX this is ugly. */
- if(br) {
- if(argc==-1) {
- argc=0;
- args[argc]=0;
- dig=0;
- /* in case we're in error... */
- if(c=='3') {
- fg=1;
- return;
- }
- if(c=='4') {
- bg=1;
- return;
- }
- args[argc]=(int)(c-'0');
- dig=1;
- args[argc+1]=0;
- } else {
- args[argc]=args[argc]*10+(int)(c-'0');
- if(argc==0) dig++;
- }
- } else bail_out(c);
- } else bail_out(c);
- break;
- }
-}
-#endif
-
-static void
-vidc_putchar(int c)
-{
-#ifdef TERM_EMU
- vidc_term_emu(c);
-#else
- vidc_rawputchar(c);
-#endif
-}
-
static int
vidc_getchar(void)
{
@@ -511,7 +120,9 @@ vidc_ischar(void)
v86.addr = 0x16;
v86.eax = 0x100;
v86int();
- return(!(v86.efl & PSL_Z));
+ if (!(v86.efl & PSL_Z))
+ return(v86.eax & 0xff);
+ return(0);
}
#if KEYBOARD_PROBE
@@ -537,7 +148,7 @@ static void
delay7(void)
{
/*
- * I know this is broken, but no timer is available yet at this stage...
+ * I know this is broken, but no timer is avaiable yet at this stage...
* See also comments in `delay1ms()'.
*/
inb(IO_DUMMY); inb(IO_DUMMY);
diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile
index 053fbd348862..02fd2d005a1a 100644
--- a/sys/boot/i386/loader/Makefile
+++ b/sys/boot/i386/loader/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.27 1999/01/11 05:52:28 msmith Exp $
+# $Id: Makefile,v 1.11 1998/10/12 01:03:00 rnordier Exp $
BASE= loader
PROG= ${BASE}
@@ -11,17 +11,8 @@ BINDIR?= /boot
SRCS= main.c conf.c
# Enable PnP and ISA-PnP code.
-HAVE_PNP= yes
-HAVE_ISABUS= yes
-
-# Enable BootForth
-BOOT_FORTH= yes
-CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
-.if exists(${.OBJDIR}/../../ficl/libficl.a)
-LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
-.else
-LIBFICL= ${.CURDIR}/../../ficl/libficl.a
-.endif
+#HAVE_PNP= yes
+#HAVE_ISABUS= yes
# Always add MI sources
.PATH: ${.CURDIR}/../../common
@@ -29,7 +20,8 @@ LIBFICL= ${.CURDIR}/../../ficl/libficl.a
CFLAGS+= -I${.CURDIR}/../../common
CFLAGS+= -I${.CURDIR}/../../.. -I.
-CLEANFILES+= vers.c vers.o ${BASE}.list ${BASE}.bin ${BASE}.sym ${BASE}.help
+CLEANFILES+= vers.c vers.o ${BASE}.list setdef0.o setdef1.o setdefs.h \
+ gensetdefs.o gensetdefs ${BASE}.bin
CFLAGS+= -Wall
LDFLAGS= -nostdlib -static -Ttext 0x1000
@@ -57,9 +49,6 @@ CFLAGS+= -I${.CURDIR}/../btx/lib
# BTX is expecting ELF components
CFLAGS+= -elf
-# New linker set code
-CFLAGS+= -DNEW_LINKER_SET
-
# Debug me!
#CFLAGS+= -g
#LDFLAGS+= -g
@@ -68,47 +57,34 @@ vers.o:
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
${CC} -c vers.c
-${BASE}: ${BASE}.bin ${BTXLDR} ${BTXKERN} ${BTXCRT} ${BASE}.help
+${BASE}: ${BASE}.bin ${BTXLDR} ${BTXKERN}
btxld -v -f aout -e 0x100000 -o ${.TARGET} -l ${BTXLDR} -b ${BTXKERN} \
${BASE}.bin
-# /usr/bin/kzip ${.TARGET}
-# mv ${.TARGET}.kz ${.TARGET}
-
-${BASE}.bin: ${BASE}.sym
- cp ${.ALLSRC} ${.TARGET}
- strip ${.TARGET}
-
-${BASE}.help: help.common help.i386
- cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
-
-beforeinstall:
-.if exists(${DESTDIR}/boot/loader)
- mv ${DESTDIR}/boot/loader ${DESTDIR}/boot/loader.old
-.endif
-.if exists(${.OBJDIR}/loader.help)
- ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
- ${.OBJDIR}/${BASE}.help ${DESTDIR}/boot
-.else
- ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
- ${.CURDIR}/${BASE}.help ${DESTDIR}/boot
-.endif
-# Cannot use ${OBJS} above this line
-.include <bsd.prog.mk>
+${BASE}.bin: ${OBJS} ${LIBI386} vers.o setdef0.o setdef1.o
+ ${CC} ${LDFLAGS} -o ${.TARGET} ${BTXCRT} setdef0.o ${OBJS} vers.o setdef1.o \
+ ${LIBSTAND} ${LIBI386} ${LIBSTAND}
-${BASE}.sym: ${OBJS} ${LIBI386} ${LIBSTAND} ${LIBFICL} vers.o
- ${CC} ${LDFLAGS} -o ${.TARGET} ${BTXCRT} ${OBJS} vers.o \
- ${LIBFICL} ${LIBSTAND} ${LIBI386} ${LIBSTAND}
+setdef0.o: setdefs.h
-# If it's not there, don't consider it a target
-.if exists(${.CURDIR}/../../../i386/include)
-beforedepend ${OBJS}: machine
+setdef1.o: setdefs.h
machine:
ln -sf ${.CURDIR}/../../../i386/include machine
-.endif
-
CLEANFILES+= machine
+.include <bsd.prog.mk>
+# Linker set gymnastics
+setdefs.h: gensetdefs ${OBJS}
+ @echo Generating linker sets
+ @./gensetdefs ${OBJS} >setdefs.h
+
+gensetdefs: gensetdefs.o
+ ${CC} -static gensetdefs.o -o $@
+
+gensetdefs.o: gensetdefs.c
+ ${CC} -c $<
+
+beforedepend ${OBJS}: machine
diff --git a/sys/boot/i386/loader/conf.c b/sys/boot/i386/loader/conf.c
index 9b4d554bc1a0..d39d67f33873 100644
--- a/sys/boot/i386/loader/conf.c
+++ b/sys/boot/i386/loader/conf.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: conf.c,v 1.9 1998/10/22 20:23:58 msmith Exp $
+ * $Id: conf.c,v 1.6 1998/09/30 19:48:42 peter Exp $
*/
#include <stand.h>
@@ -85,12 +85,10 @@ struct console *consoles[] = {
};
extern struct pnphandler isapnphandler;
-extern struct pnphandler biospnphandler;
-extern struct pnphandler biospcihandler;
+/* extern struct pnphandler pcipnphandler;*/
struct pnphandler *pnphandlers[] = {
- &biospnphandler, /* should go first, as it may set isapnp_readport */
- &isapnphandler,
- &biospcihandler,
+/* &isapnphandler, */
+/* &pcipnphandler, */
NULL
};
diff --git a/sys/boot/i386/loader/help.i386 b/sys/boot/i386/loader/help.i386
deleted file mode 100644
index 81288250ade0..000000000000
--- a/sys/boot/i386/loader/help.i386
+++ /dev/null
@@ -1,34 +0,0 @@
-################################################################################
-# Treboot DReboot the system
-
- reboot
-
- Causes the system to immediately reboot.
-
-################################################################################
-# Theap DDisplay memory management statistics
-
- heap
-
- Requests debugging output from the heap manager. For debugging use
- only.
-
-################################################################################
-# Tset Snum_ide_disks DSet the number of IDE disks
-
- set num_ide_disks=<value>
-
- When booting from a SCSI disk on a system with one or more IDE disks,
- and where the IDE disks are the default boot device, it is necessary
- to tell the kernel how many IDE disks there are in order to have it
- correctly locate the SCSI disk you are booting from.
-
-################################################################################
-# Tset Sboot_userconfig DStart Userconfig
-
- set boot_userconfig
-
- Requests that the kernel's interactive device configuration program
- be run when the kernel is booted.
-
-################################################################################
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c
index dfd1bfffbb98..b9e93f49b357 100644
--- a/sys/boot/i386/loader/main.c
+++ b/sys/boot/i386/loader/main.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: main.c,v 1.13 1998/10/22 20:23:58 msmith Exp $
+ * $Id: main.c,v 1.10 1998/10/03 18:27:50 rnordier Exp $
*/
/*
@@ -58,8 +58,6 @@ static struct bootinfo *initial_bootinfo;
struct arch_switch archsw; /* MI/MD interface boundary */
static void extract_currdev(void);
-static int isa_inb(int port);
-static void isa_outb(int port, int value);
/* from vers.c */
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
@@ -98,11 +96,6 @@ main(void)
cons_probe();
/*
- * Initialise the block cache
- */
- bcache_init(32, 512); /* 16k cache XXX tune this */
-
- /*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
@@ -112,6 +105,10 @@ main(void)
printf("\n");
printf("%s, Revision %s %d/%dkB\n", bootprog_name, bootprog_rev, getbasemem(), getextmem());
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
+#if 0
+ printf("recovered args howto = 0x%x bootdev = 0x%x bootinfo = %p\n",
+ initial_howto, initial_bootdev, initial_bootinfo);
+#endif
extract_currdev(); /* set $currdev and $loaddev */
setenv("LINES", "24", 1); /* optional */
@@ -121,8 +118,6 @@ main(void)
archsw.arch_copyin = i386_copyin;
archsw.arch_copyout = i386_copyout;
archsw.arch_readin = i386_readin;
- archsw.arch_isainb = isa_inb;
- archsw.arch_isaoutb = isa_outb;
interact(); /* doesn't return */
}
@@ -200,34 +195,3 @@ command_heap(int argc, char *argv[])
printf("heap base at %p, top at %p\n", end, sbrk(0));
return(CMD_OK);
}
-
-/* ISA bus access functions for PnP, derived from <machine/cpufunc.h> */
-static int
-isa_inb(int port)
-{
- u_char data;
-
- if (__builtin_constant_p(port) &&
- (((port) & 0xffff) < 0x100) &&
- ((port) < 0x10000)) {
- __asm __volatile("inb %1,%0" : "=a" (data) : "id" ((u_short)(port)));
- } else {
- __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
- }
- return(data);
-}
-
-static void
-isa_outb(int port, int value)
-{
- u_char al = value;
-
- if (__builtin_constant_p(port) &&
- (((port) & 0xffff) < 0x100) &&
- ((port) < 0x10000)) {
- __asm __volatile("outb %0,%1" : : "a" (al), "id" ((u_short)(port)));
- } else {
- __asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
- }
-}
-
diff --git a/sys/boot/i386/loader/newvers.sh b/sys/boot/i386/loader/newvers.sh
index 476913be37a0..34b0e7e674d9 100755
--- a/sys/boot/i386/loader/newvers.sh
+++ b/sys/boot/i386/loader/newvers.sh
@@ -35,7 +35,6 @@
#
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
-LC_TIME=C; export LC_TIME
u=${USER-root} h=`hostname` t=`date`
#r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
r=`awk -F: ' /^[0-9]\.[0-9]+:/ { print $1; exit }' $1`
diff --git a/sys/boot/i386/loader/setdef0.c b/sys/boot/i386/loader/setdef0.c
new file mode 100644
index 000000000000..e2af74e84393
--- /dev/null
+++ b/sys/boot/i386/loader/setdef0.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1997 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: setdef0.c,v 1.2 1997/05/21 23:21:30 jdp Exp $
+ */
+
+#ifdef __ELF__
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+
+/*
+ * DEFINE_SET creates the section and label for a set, and emits the
+ * count word at the front of it.
+ */
+#define DEFINE_SET(set, count) \
+ __asm__(".section .set." #set ",\"aw\""); \
+ __asm__(".globl " #set); \
+ __asm__(".type " #set ",@object"); \
+ __asm__(".p2align 2"); \
+ __asm__(#set ":"); \
+ __asm__(".long " #count); \
+ __asm__(".previous")
+
+#include "setdefs.h" /* Contains a `DEFINE_SET' for each set */
+
+#endif /* __ELF__ */
diff --git a/sys/boot/i386/loader/setdef1.c b/sys/boot/i386/loader/setdef1.c
new file mode 100644
index 000000000000..3f2011920526
--- /dev/null
+++ b/sys/boot/i386/loader/setdef1.c
@@ -0,0 +1,41 @@
+/*-
+ * Copyright (c) 1997 John D. Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: setdef1.c,v 1.2 1997/05/21 23:21:30 jdp Exp $
+ */
+
+#ifdef __ELF__
+
+/*
+ * DEFINE_SET emits the NULL terminator for a set.
+ */
+#define DEFINE_SET(set, count) \
+ __asm__(".section .set." #set ",\"aw\""); \
+ __asm__(".long 0"); \
+ __asm__(".previous")
+
+#include "setdefs.h" /* Contains a `DEFINE_SET' for each set */
+
+#endif /* __ELF__ */