summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2010-10-23 17:32:23 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:50 +0200
commitdddc44a59e3e393d5440a06e2b0535aeb1304f77 (patch)
treecfc2b774571f7cd6513a7e2f01a04518016e4995
parent62c27c1c5cb6257b13dfc9be0394e0d2e86f2735 (diff)
downloaddev86-dddc44a59e3e393d5440a06e2b0535aeb1304f77.tar.gz
Import Dev86src-0.16.18.tar.gzv0.16.18
-rw-r--r--GNUmakefile4
-rw-r--r--Makefile16
-rw-r--r--README17
-rw-r--r--bcc/const.h4
-rw-r--r--bcc/preproc.c2
-rw-r--r--bin86/Makefile4
-rw-r--r--bootblocks/Makefile76
-rw-r--r--bootblocks/README13
-rw-r--r--bootblocks/bb_init1.s2
-rw-r--r--bootblocks/freedos.h72
-rw-r--r--bootblocks/freedosboot.zipbin0 -> 14135 bytes
-rw-r--r--bootblocks/makeboot.c713
-rw-r--r--bootblocks/mbr.s891
-rw-r--r--bootblocks/mbr_dm.s313
-rw-r--r--bootblocks/minix.c2
-rw-r--r--bootblocks/msdos.s2
-rw-r--r--bootblocks/nombr.s23
-rw-r--r--bootblocks/sysboot.s3
-rw-r--r--bootblocks/sysboot16.s82
-rw-r--r--bootblocks/sysmbr.s76
-rw-r--r--bootblocks/sysmbrtail.s13
-rw-r--r--elksemu/elks.c3
-rw-r--r--ifdef.c4
-rw-r--r--libc/gtermcap/Makefile.old25
-rw-r--r--libc/i386sys/Makefile2
-rw-r--r--libc/msdos/msdos.c13
-rw-r--r--libc/syscall/syscall.dev86.old160
-rw-r--r--makefile.in33
-rw-r--r--tests/Makefile14
-rwxr-xr-xtests/a.outbin0 -> 12541 bytes
-rw-r--r--tests/hello_world.s18
-rw-r--r--unproto/Makefile.old123
-rw-r--r--unproto/unproto.c.old999
33 files changed, 1522 insertions, 2200 deletions
diff --git a/GNUmakefile b/GNUmakefile
index ab2c284..1e8bbb9 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -3,10 +3,10 @@
#
all: phony
- @$(MAKE) -f Makefile IFDEFFLAGS=-DGNUMAKE $@
+ @$(MAKE) -f Makefile IFDEFFLAGS=-DGNUMAKE IFDEFNAME=ifdefg $@
%: phony
- @$(MAKE) -f Makefile IFDEFFLAGS=-DGNUMAKE $@
+ @$(MAKE) -f Makefile IFDEFFLAGS=-DGNUMAKE IFDEFNAME=ifdefg $@
phony: ;
diff --git a/Makefile b/Makefile
index b34dd33..5e53dc8 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
# This file is part of the Linux-8086 Development environment and is
# distributed under the GNU General Public License.
-VERSION=0.16.17
+VERSION=0.16.18
TARGETS=install clean other \
bcc86 unproto copt as86 ld86 elksemu \
@@ -19,6 +19,7 @@ INCLDIR= $(PREFIX)/lib/bcc
ASLDDIR= $(BINDIR)
MANDIR= $(PREFIX)/man
CFLAGS= -O
+IFDEFNAME= ifdef
# Some makes take the last of a list as the default ...
all: make.fil
@@ -34,10 +35,10 @@ as: as86
realclean:
-[ ! -f make.fil ] || $(MAKE) -f make.fil VERSION=$(VERSION) TOPDIR=`pwd` $@
- -rm -f make.fil ifdef ifdef.o
+ -rm -f make.fil ifdef ifdefg
-make.fil: ifdef makefile.in
- ./ifdef -MU makefile.in >tmp.mak
+make.fil: $(IFDEFNAME) makefile.in
+ ./$(IFDEFNAME) -MU makefile.in >tmp.mak
echo > tmp.sed
[ "$(BINDIR)" != "//bin" ] || echo >> tmp.sed "s:%BINDIR%:/bin:"
[ "$(LIBDIR)" != "//lib/bcc" ] || echo >> tmp.sed "s:%LIBDIR%:/lib:"
@@ -58,11 +59,8 @@ make.fil: ifdef makefile.in
mv -f make.tmp make.fil
@rm -f tmp.mak tmp.sed
-ifdef: ifdef.o
- $(CC) $(IFDEFARCH) $(LDFLAGS) -o ifdef ifdef.o
-
-ifdef.o: ifdef.c
- $(CC) $(IFDEFARCH) $(CFLAGS) $(IFDEFFLAGS) -c ifdef.c
+$(IFDEFNAME): ifdef.c
+ $(CC) $(IFDEFARCH) $(CFLAGS) $(IFDEFFLAGS) $(LDFLAGS) -o $(IFDEFNAME) ifdef.c
uninstall:
@echo 'Sorry, no go; it was just wrong.'
diff --git a/README b/README
index f3d184e..3304cd7 100644
--- a/README
+++ b/README
@@ -10,6 +10,10 @@ Use 'make install' to install them.
Some other bits can be built by 'make other' and installed with
'make install-other'.
+Note the the make files for the libraries can only be run using
+GNU-make but version 3.82 has a bug (No. 30612) that prevents this
+working properly.
+
If you want it to install under /usr/local instead you can specify
the prefix on the first make ie: 'make PREFIX=/usr/local' this is
remembered until 'make.fil' is rebuilt.
@@ -90,9 +94,9 @@ The as86 and ld86 with this are _different_ from the minimum version
needed for the linux-i386 kernel and can replace them, versions before
0.12.0 will not work with this version of bcc.
-I _strongly_ suggest you install the kernel patch or load the module
-to allow transparent execution of elks executables. If you're using
-a post 2.1.43 or 2.0.36 kernel the only module you need is the binfmt_misc
+I suggest you install the kernel patch or load the module to allow
+transparent execution of elks executables. If you're using a post
+2.1.43 or 2.0.36 kernel the only module you need is the binfmt_misc
driver configured like this:
echo ':i86-elks:M::\x01\x03\x20\x00:\xff\xff\xff\x83:/usr/bin/elksemu:' \
@@ -101,8 +105,9 @@ echo ':i86-elks:M::\x01\x03\x20\x00:\xff\xff\xff\x83:/usr/bin/elksemu:' \
The elksemu executable must be stored in /usr/bin/elksemu or the above
line adjusted.
-Previous versions need a special module or patch described in elksemu/README
-(All the options need the elksemu executable installed correctly)
+Previous kernel versions need a special module or patch described in
+elksemu/README (All the options need the elksemu executable installed
+correctly)
Copyrights
----------
@@ -126,4 +131,4 @@ See the COPYING file in this directory for the GPL and the COPYING file
in the libc directory for the LGPL.
--
-Rob. (Robert de Bath <rdebath@poboxes.com>)
+Rob. (Robert de Bath <robert$@debath.co.uk>)
diff --git a/bcc/const.h b/bcc/const.h
index c06aca0..91f8a90 100644
--- a/bcc/const.h
+++ b/bcc/const.h
@@ -25,8 +25,10 @@
#ifndef VERY_SMALL_MEMORY
#define SELFTYPECHECK /* check calculated type = runtime type */
-#define DBNODE /* generate compiler node debugging code */
#define OPTIMISE /* include optimisation code */
+#ifndef MSDOS
+#define DBNODE /* generate compiler node debugging code */
+#endif
#endif
#ifndef __BCC__
diff --git a/bcc/preproc.c b/bcc/preproc.c
index 97e2a96..e5f20a5 100644
--- a/bcc/preproc.c
+++ b/bcc/preproc.c
@@ -947,7 +947,7 @@ PUBLIC void leavemac()
{
mpptr->symptr->name.namea[0] &= 0x7F;/* UnSMUDGE macro definition */
ch = *++lineptr; /* gch1() would mess up next param == EOL-1 */
- if (ch != 0)
+ if (ch != 0 && mpptr->paramlist)
{
mpptr->paramspot = lineptr;
lineptr = mpptr->paramlist[ch - 1];
diff --git a/bin86/Makefile b/bin86/Makefile
index 3d8aa6f..df1c3ec 100644
--- a/bin86/Makefile
+++ b/bin86/Makefile
@@ -6,7 +6,11 @@ DIRS=ld as
PREFIX=/usr/local
BINDIR=$(PREFIX)/bin
LIBDIR=$(PREFIX)/lib
+ifeq ($(PREFIX),/usr)
+MANDIR=$(PREFIX)/share/man/man1
+else
MANDIR=$(PREFIX)/man/man1
+endif
SUF=86
INSTALL_OPT=-m 755
diff --git a/bootblocks/Makefile b/bootblocks/Makefile
index 60d8b8f..d954ea1 100644
--- a/bootblocks/Makefile
+++ b/bootblocks/Makefile
@@ -11,7 +11,7 @@ LDFLAGS=-s -i -H0x10000
ASFLAGS=-0 -w
MINIXDEFS=-DDOTS
# CFLAGS=-ansi -Ms $(DEFS)
-# LST=-l $*.lst
+LST=-l $*.lst
default: makeboot makeboot.com monitor.sys minix_elks.bin lsys.com
@@ -20,11 +20,12 @@ all: bootbin bootsys default tgz
bootsys: bootfile.sys boottar.sys bootminix.sys monitor.sys boot_win.sys
CSRC=minix.c
-SSRC=sysboot.s tarboot.s skip.s mbr.s msdos.s noboot.s \
+SSRC=tarboot.s skip.s mbr.s mbr_dm.s msdos.s noboot.s nombr.s \
boot_fpy.s killhd.s bb_linux.s bb_init1.s bb_init2.s
+SINC=sysboot16.s sysboot.s sysmbr.s sysmbrtail.s
-encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v msdos16.v
-bootbin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin msdos16.bin minix_elks.bin
+encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v mbr_chs.v mbr_lin.v mbr_lba.v pbr.v msdos16.v
+bootbin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin mbr_chs.bin mbr_lin.bin mbr_lba.bin pbr.bin msdos16.bin minix_elks.bin
MOBJ=monitor.o commands.o i86_funcs.o relocate.o help.o bzimage.o \
buffer.o unix.o fs.o fs_tar.o fs_min.o fs_dos.o
@@ -33,9 +34,12 @@ MSRC=monitor.c commands.c i86_funcs.c relocate.c help.c bzimage.c \
MINC=i86_funcs.h readfs.h monitor.h
BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v msdos16.v \
- tarboot.v minix.v minixhd.v mbr.v killhd.v
+ tarboot.v minix.v minixhd.v mbr.v killhd.v \
+ sysboot16.v nombr.v mbr_dm.v mbr_chs.v mbr_lin.v mbr_lba.v \
+ pbr.v
-EXTRAS=minix.h zimage.s minix_elks.c lsys.c boot_win.c
+EXTRAS=minix.h zimage.s minix_elks.c lsys.c boot_win.c \
+ freedosboot.zip freedos.h
install: makeboot
install -m 755 -s makeboot $(DIST)$(PREFIX)/bin/makeboot
@@ -90,23 +94,63 @@ minix_elks.s: minix_elks.c Makefile minix.v
minixhd.s: minix.c Makefile
$(CC) -Mf -O -DHARDDISK $(MINIXDEFS) -S minix.c -o minixhd.s
-msdos16.s: msdos.s
+msdos16.s: msdos.s Makefile
sed 's/^fatbits=12/fatbits=16/' < msdos.s > msdos16.s
-mbr_dm.s: mbr.s
- sed -e 's/^diskman=0/diskman=1/' \
+mbr_chs.s: mbr.s Makefile
+ sed -e 's/^linear=1/linear=0/' \
+ -e 's/^useCHS=0/useCHS=1/' \
+ -e 's/^linCHS=1/linCHS=0/' \
+ -e 's/^mbrkey=1/mbrkey=0/' \
+ -e 's/^preboot=1/preboot=0/' \
+ -e 's/^pbr=1/pbr=0/' \
+ -e 's/^direct=1/direct=0/' \
-e 's/^message=1/message=0/' \
+ < mbr.s > mbr_chs.s
+
+mbr_lin.s: mbr.s Makefile
+ sed -e 's/^linear=1/linear=0/' \
+ -e 's/^useCHS=0/useCHS=1/' \
+ -e 's/^linCHS=0/linCHS=1/' \
-e 's/^mbrkey=1/mbrkey=0/' \
-e 's/^preboot=1/preboot=0/' \
- < mbr.s > mbr_dm.s
+ -e 's/^pbr=1/pbr=0/' \
+ -e 's/^direct=1/direct=0/' \
+ -e 's/^message=1/message=0/' \
+ < mbr.s > mbr_lin.s
+
+pbr.s: mbr.s Makefile
+ sed -e 's/^linear=0/linear=1/' \
+ -e 's/^useCHS=1/useCHS=0/' \
+ -e 's/^linCHS=1/linCHS=0/' \
+ -e 's/^mbrkey=1/mbrkey=0/' \
+ -e 's/^preboot=1/preboot=0/' \
+ -e 's/^pbr=0/pbr=1/' \
+ -e 's/^direct=1/direct=0/' \
+ -e 's/^message=1/message=0/' \
+ < mbr.s > pbr.s
+
+mbr_lba.s: mbr.s Makefile
+ sed -e 's/^linear=0/linear=1/' \
+ -e 's/^useCHS=1/useCHS=0/' \
+ -e 's/^linCHS=1/linCHS=0/' \
+ -e 's/^mbrkey=1/mbrkey=0/' \
+ -e 's/^preboot=1/preboot=0/' \
+ -e 's/^pbr=1/pbr=0/' \
+ -e 's/^direct=1/direct=0/' \
+ -e 's/^message=1/message=0/' \
+ < mbr.s > mbr_lba.s
boot_win.sys: boot_win.c
$(CC) -Ms -H0x6000 -s boot_win.c -o boot_win.sys
-makeboot: makeboot.c $(BOOTBLOCKS)
+makeboot: makeboot.c $(BOOTBLOCKS) freedos.h
$(HOSTCC) $(HOSTCCFLAGS) -o makeboot makeboot.c
-makeboot.com: makeboot.c $(BOOTBLOCKS)
+ldboot: ldboot.c
+ $(HOSTCC) $(HOSTCCFLAGS) -o ldboot ldboot.c
+
+makeboot.com: makeboot.c $(BOOTBLOCKS) freedos.h
$(CC) -Md -O -o makeboot.com makeboot.c
lsys.com: lsys.c msdos.v msdos16.v
@@ -115,7 +159,7 @@ lsys.com: lsys.c msdos.v msdos16.v
clean realclean:
rm -f bootfile.sys boottar.sys bootminix.sys monitor.sys boot_win.sys
rm -f monitor makeboot bootblocks.tar.gz
- rm -f minix.s minixhd.s minix_elks.s msdos16.s mbr_dm.s
+ rm -f minix.s minixhd.s minix_elks.s msdos16.s mbr_chs.s mbr_lin.s mbr_lba.s pbr.s
rm -f *.com *.o *.bin *.out *.lst *.sym *.v *.tmp
tgz: minix.bin monitor.sys makeboot.com makeboot
@@ -123,8 +167,8 @@ tgz: minix.bin monitor.sys makeboot.com makeboot
README Makefile \
$(MSRC) \
$(MINC) \
- makeboot.c $(CSRC) \
- $(SSRC) \
+ makeboot.c $(CSRC) freedos.h \
+ $(SSRC) $(SINC) \
makeboot.com minix.bin \
$(EXTRAS)
makeboot tar bootblocks.tar
@@ -132,7 +176,7 @@ tgz: minix.bin monitor.sys makeboot.com makeboot
distribution:
tar czf /tmp/bootblocks.tar.gz \
- README Makefile $(MSRC) $(MINC) makeboot.c $(CSRC) $(SSRC) $(EXTRAS)
+ README Makefile $(MSRC) $(MINC) makeboot.c $(CSRC) $(SSRC) $(SINC) $(EXTRAS)
.SUFFIXES: .bin .v
diff --git a/bootblocks/README b/bootblocks/README
index 21b60b2..f8211b9 100644
--- a/bootblocks/README
+++ b/bootblocks/README
@@ -34,8 +34,8 @@ Contents
This MBR is a very simple one with no frills by default.
The actual code is less that 254 bytes long so it can be used as
- an MBR for a disk with old style 'Disk manager' partitions. All 16
- partitions are bootable.
+ an MBR for a disk with old style 'Disk manager' partitions.
+ The code now only boots one of the last four partitions.
Option 2 is a boot message that displayed as soon as the MBR loads.
@@ -52,11 +52,6 @@ Contents
can be configured to load another boot sector, for example LILO can
be succesfully used in this way.
- In fact LILO can be succesfully used in this way on a 2M disk, but
- you must create the floppy with the real dos 2M package as superformat
- does not create correct bootable 2M disks. Also beware that mounting
- a 2M floppy can ... be interesting ...
-
Note this boot sector loads the executable 1 sector at a time, as far
as my testing has gone this is only significant on 8086 machines, all
others (286 8Mhz +) are fast enough to keep up at a 1-1 interleve.
@@ -81,7 +76,7 @@ Contents
There is also support for a helper boot which mean this is the only
boot sector able to load an ELKS image (almost) directly.
-1.4 ) Tar boot sector -- Cool Man!!
+1.4 ) Tar boot sector
This boot sector converts a tar file with a GNU Volume label into a
bootable floppy image. The boot sector loads and executes the first
@@ -165,4 +160,4 @@ Contents
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-Robert de Bath <robert@mayday.cix.co.uk>
+Robert de Bath <robert$@debath.co.uk>
diff --git a/bootblocks/bb_init1.s b/bootblocks/bb_init1.s
index 41c39cb..8b85e54 100644
--- a/bootblocks/bb_init1.s
+++ b/bootblocks/bb_init1.s
@@ -1,4 +1,4 @@
-ORGADDR=0x0600
+ORGADDR=0x0600 ! $0500..0600 stack or move ORGADDR down.
.org ORGADDR
entry start
diff --git a/bootblocks/freedos.h b/bootblocks/freedos.h
new file mode 100644
index 0000000..5d6e1b9
--- /dev/null
+++ b/bootblocks/freedos.h
@@ -0,0 +1,72 @@
+/* Binaries taken from freedos */
+
+char freedos_fat32lba[512] = {
+0xeb,0x58,0x90,0x46,0x72,0x65,0x65,0x44,0x4f,0x53,0x20,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfa,0x29,0xc0,0x8e,0xd8,
+0xbd,0x00,0x7c,0xb8,0xe0,0x1f,0x8e,0xc0,0x89,0xee,0x89,0xef,0xb9,0x00,0x01,0xf3,
+0xa5,0xea,0x7a,0x7c,0xe0,0x1f,0x00,0x00,0x60,0x00,0x8e,0xd8,0x8e,0xd0,0x8d,0x66,
+0xe0,0xfb,0x88,0x56,0x40,0xbe,0xc1,0x7d,0xe8,0xf4,0x00,0x66,0x31,0xc0,0x66,0x89,
+0x46,0x44,0x8b,0x46,0x0e,0x66,0x03,0x46,0x1c,0x66,0x89,0x46,0x48,0x66,0x89,0x46,
+0x4c,0x66,0x8b,0x46,0x10,0x66,0xf7,0x6e,0x24,0x66,0x01,0x46,0x4c,0xb8,0x00,0x02,
+0x3b,0x46,0x0b,0x74,0x08,0x01,0xc0,0xff,0x06,0x34,0x7d,0xeb,0xf3,0x66,0x8b,0x46,
+0x2c,0x66,0x50,0xe8,0x94,0x00,0x72,0x4d,0xc4,0x5e,0x76,0xe8,0xb7,0x00,0x31,0xff,
+0xb9,0x0b,0x00,0xbe,0xf1,0x7d,0xf3,0xa6,0x74,0x15,0x83,0xc7,0x20,0x83,0xe7,0xe0,
+0x3b,0x7e,0x0b,0x75,0xeb,0x4a,0x75,0xe0,0x66,0x58,0xe8,0x34,0x00,0xeb,0xd2,0x26,
+0xff,0x75,0x09,0x26,0xff,0x75,0x0f,0x66,0x58,0x29,0xdb,0x66,0x50,0xe8,0x5a,0x00,
+0x72,0x0d,0xe8,0x80,0x00,0x4a,0x75,0xfa,0x66,0x58,0xe8,0x14,0x00,0xeb,0xec,0x8a,
+0x5e,0x40,0xff,0x6e,0x76,0xbe,0xee,0x7d,0xe8,0x64,0x00,0x30,0xe4,0xcd,0x16,0xcd,
+0x19,0x06,0x57,0x53,0x89,0xc7,0xc1,0xe7,0x02,0x50,0x8b,0x46,0x0b,0x48,0x21,0xc7,
+0x58,0x66,0xc1,0xe8,0x07,0x66,0x03,0x46,0x48,0xbb,0x00,0x20,0x8e,0xc3,0x29,0xdb,
+0x66,0x3b,0x46,0x44,0x74,0x07,0x66,0x89,0x46,0x44,0xe8,0x38,0x00,0x26,0x80,0x65,
+0x03,0x0f,0x26,0x66,0x8b,0x05,0x5b,0x5f,0x07,0xc3,0x66,0x3d,0xf8,0xff,0xff,0x0f,
+0x73,0x15,0x66,0x48,0x66,0x48,0x66,0x0f,0xb6,0x56,0x0d,0x66,0x52,0x66,0xf7,0xe2,
+0x66,0x5a,0x66,0x03,0x46,0x4c,0xc3,0xf9,0xc3,0x31,0xdb,0xb4,0x0e,0xcd,0x10,0xac,
+0x3c,0x00,0x75,0xf5,0xc3,0x52,0x56,0x57,0x66,0x50,0x89,0xe7,0x6a,0x00,0x6a,0x00,
+0x66,0x50,0x06,0x53,0x6a,0x01,0x6a,0x10,0x89,0xe6,0x8a,0x56,0x40,0xb4,0x42,0xcd,
+0x13,0x89,0xfc,0x66,0x58,0x73,0x08,0x50,0x30,0xe4,0xcd,0x13,0x58,0xeb,0xd9,0x66,
+0x40,0x03,0x5e,0x0b,0x73,0x07,0x8c,0xc2,0x80,0xc6,0x10,0x8e,0xc2,0x5f,0x5e,0x5a,
+0xc3,0x4c,0x6f,0x61,0x64,0x69,0x6e,0x67,0x20,0x46,0x72,0x65,0x65,0x44,0x4f,0x53,
+0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x6f,
+0x20,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x20,0x20,0x53,0x59,0x53,0x00,0x00,0x55,0xaa
+};
+
+
+char freedos_fat32chs[512] = {
+0xeb,0x58,0x90,0x46,0x72,0x65,0x65,0x44,0x4f,0x53,0x20,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0xfa,0x29,0xc0,0x8e,0xd8,
+0xbd,0x00,0x7c,0xb8,0xe0,0x1f,0x8e,0xc0,0x89,0xee,0x89,0xef,0xb9,0x00,0x01,0xf3,
+0xa5,0xea,0x7a,0x7c,0xe0,0x1f,0x00,0x00,0x60,0x00,0x8e,0xd8,0x8e,0xd0,0x8d,0x66,
+0xe0,0xfb,0x88,0x56,0x40,0x8b,0x76,0x1c,0x8b,0x7e,0x1e,0x03,0x76,0x0e,0x83,0xd7,
+0x00,0x89,0x76,0x5e,0x89,0x7e,0x60,0x8a,0x46,0x10,0x98,0x50,0xf7,0x66,0x26,0x01,
+0xc7,0x58,0xf7,0x66,0x24,0x01,0xf0,0x11,0xfa,0x89,0x46,0x62,0x89,0x56,0x64,0x8b,
+0x46,0x0b,0xd1,0xe8,0xd1,0xe8,0x48,0x89,0x46,0x66,0x91,0x41,0x40,0xd1,0xe9,0x81,
+0xf9,0x01,0x00,0x75,0xf7,0x88,0x46,0x68,0x49,0x89,0x4e,0x48,0x89,0x4e,0x4a,0x8b,
+0x46,0x2c,0x8b,0x56,0x2e,0x52,0x50,0xe8,0x9d,0x00,0x72,0x50,0x53,0xc4,0x5e,0x76,
+0xe8,0xcb,0x00,0x52,0x50,0x8b,0x46,0x0b,0xb9,0x0b,0x00,0xbe,0xf1,0x7d,0x89,0xc7,
+0x81,0xef,0x20,0x00,0xf3,0xa6,0x74,0x12,0x2d,0x20,0x00,0x75,0xeb,0x58,0x5a,0x5b,
+0x4b,0x75,0xd9,0x58,0x5a,0xe8,0x2a,0x00,0xeb,0xcb,0x26,0x8b,0x45,0x0f,0x26,0x8b,
+0x55,0x09,0x29,0xdb,0x52,0x50,0x53,0xe8,0x5d,0x00,0x72,0x55,0x89,0xdf,0x5b,0xe8,
+0x8c,0x00,0x4f,0x75,0xfa,0x58,0x5a,0xe8,0x08,0x00,0xeb,0xe8,0x30,0xe4,0xcd,0x16,
+0xcd,0x19,0x06,0x89,0xc7,0x23,0x7e,0x66,0x8b,0x4e,0x68,0xd1,0xea,0xd1,0xd8,0x49,
+0x75,0xf9,0xd1,0xe7,0xd1,0xe7,0x03,0x46,0x5e,0x13,0x56,0x60,0x53,0xbb,0x00,0x20,
+0x8e,0xc3,0x29,0xdb,0x3b,0x46,0x48,0x75,0x05,0x3b,0x56,0x4a,0x74,0x09,0x89,0x46,
+0x48,0x89,0x56,0x4a,0xe8,0x47,0x00,0x5b,0x26,0x8b,0x05,0x26,0x8b,0x55,0x02,0x07,
+0xc3,0x8a,0x5e,0x40,0xff,0x6e,0x76,0x81,0xfa,0xff,0x0f,0x75,0x07,0x3d,0xf8,0xff,
+0x72,0x02,0xf9,0xc3,0x89,0xd1,0x2d,0x02,0x00,0x83,0xd9,0x00,0x8a,0x5e,0x0d,0x28,
+0xff,0x91,0xf7,0xe3,0x91,0xf7,0xe3,0x01,0xca,0x03,0x46,0x62,0x13,0x56,0x64,0xc3,
+0x31,0xdb,0xb4,0x0e,0xcd,0x10,0x5e,0xac,0x56,0x3c,0x00,0x75,0xf3,0xc3,0x52,0x50,
+0x91,0x8a,0x46,0x18,0xf6,0x66,0x1a,0x91,0xf7,0xf1,0x92,0xf6,0x76,0x18,0x89,0xd1,
+0x88,0xc6,0x86,0xe9,0xd0,0xc9,0xd0,0xc9,0xfe,0xc4,0x08,0xe1,0xb8,0x01,0x02,0x8a,
+0x56,0x40,0xcd,0x13,0x58,0x5a,0x73,0x06,0x30,0xe4,0xcd,0x13,0xeb,0xd0,0x03,0x5e,
+0x0b,0x73,0x07,0x8c,0xc1,0x80,0xc5,0x10,0x8e,0xc1,0x83,0xc0,0x01,0x83,0xd2,0x00,
+0xc3,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x20,0x20,0x53,0x59,0x53,0x00,0x00,0x55,0xaa
+};
diff --git a/bootblocks/freedosboot.zip b/bootblocks/freedosboot.zip
new file mode 100644
index 0000000..1fbb636
--- /dev/null
+++ b/bootblocks/freedosboot.zip
Binary files differ
diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c
index fa3773f..9ee0c44 100644
--- a/bootblocks/makeboot.c
+++ b/bootblocks/makeboot.c
@@ -3,8 +3,12 @@
#include <ctype.h>
#include <time.h>
#include <string.h>
+#ifndef __MSDOS__
+#include <stdlib.h>
+#endif
#include "sysboot.v"
+#include "sysboot16.v"
#include "noboot.v"
#include "msdos.v"
#include "msdos16.v"
@@ -14,6 +18,17 @@
#include "minix.v"
#include "minixhd.v"
#include "mbr.v"
+#include "mbr_chs.v"
+#include "mbr_lin.v"
+#include "mbr_lba.v"
+#include "pbr.v"
+#include "nombr.v"
+
+/* Binary bootblocks */
+#include "freedos.h"
+#ifdef USE_WIN95BB
+#include "win95.h"
+#endif
unsigned char buffer[1024];
@@ -39,32 +54,23 @@ struct bblist {
int fstype;
int fsmod;
} bblocks[] = {
-{ "tar", "Bootable GNU tar volume lable",
- tarboot_data, tarboot_size, 0, 0, FS_TAR},
-{ "dos12","Boot file BOOTFILE.SYS from dos floppy",
- msdos_data, msdos_size,
- 1, msdos_boot_name-msdos_start, FS_DOS, 12},
-{ "dos16","Boot file BOOTFILE.SYS from FAT16 hard disk or floppy",
- msdos16_data, msdos16_size,
- 1, msdos16_boot_name-msdos16_start, FS_DOS, 16},
+/* Default */
+{ "stat", "Display dosfs superblock",
+ 0, 0, 0, 0, FS_STAT},
+{ "copy", "Copy boot block to makeboot.sav or named file",
+ 0, 0, 0, 0, FS_STAT},
+{ "Zap", "Clear boot block to NULs",
+ 0, 1024, 0, 0, FS_NONE},
+
{ "none", "No OS bootblock, just display message",
noboot_data, noboot_size,
2, noboot_boot_message-noboot_start, FS_ADOS},
{ "skip", "Bypasses floppy boot with message",
skip_data, skip_size,
2, skip_mesg-skip_start, FS_ADOS},
-{ "minix","Minix floppy FS booter",
- minix_data, minix_size,
- 2, minix_bootfile-minix_start, FS_ZERO},
-{ "hdmin","Minix Hard disk FS booter",
- minixhd_data, minixhd_size,
- 2, minixhd_bootfile-minixhd_start, FS_ZERO},
-{ "killhd", "Deletes MBR from hard disk when booted",
- killhd_data, killhd_size,
- 2, killhd_boot_message-killhd_start, FS_ADOS},
#if __STDC__
{ "mbr", "Master boot record for HD"
-#if defined(mbr_Banner) || mbr_diskman || mbr_linear || mbr_mbrkey || mbr_preboot
+#if defined(mbr_Banner) || mbr_diskman || mbr_linear || mbr_mbrkey || mbr_preboot || mbr_direct || mbr_pbr
", Options:"
#ifdef mbr_Banner
" Banner"
@@ -78,12 +84,21 @@ struct bblist {
"-Only"
#endif
#endif
+#if mbr_useCHS && mbr_linCHS
+ " linCHS"
+#endif
#if mbr_mbrkey
" BootKeys"
#endif
#if mbr_preboot
" PreBoot"
#endif
+#if mbr_direct
+ " Direct"
+#endif
+#if mbr_pbr
+ " PBR"
+#endif
#endif
,
mbr_data,mbr_size,
@@ -92,16 +107,53 @@ struct bblist {
#else
0, 0, FS_MBR},
#endif
+
#else
{ "mbr", "Master boot record for HD",
mbr_data,mbr_size, 0, 0, FS_MBR},
#endif
-{ "stat", "Display dosfs superblock",
- 0, 0, 0, 0, FS_STAT},
-{ "copy", "Copy boot block to makeboot.sav or named file",
- 0, 0, 0, 0, FS_STAT},
-{ "Zap", "Clear boot block to NULs",
- 0, 1024, 0, 0, FS_NONE},
+
+{ "pbr", "LBA-Only Partition boot record",
+ pbr_data,pbr_size, 0, 0, FS_MBR},
+{ "mbrchs","MBR using CHS addressing and BIOS",
+ mbr_chs_data,mbr_chs_size, 0, 0, FS_MBR},
+{ "mbrlin","MBR using Linear addressing and CHS BIOS",
+ mbr_lin_data,mbr_lin_size, 0, 0, FS_MBR},
+{ "mbrlba","MBR using Linear addressing and LBA BIOS",
+ mbr_lba_data,mbr_lba_size, 0, 0, FS_MBR},
+{ "nombr", "Boot failure message for MBR",
+ nombr_data,nombr_size,
+ 2, nombr_message-nombr_start, FS_MBR},
+
+
+{ "minix","Minix floppy FS booter",
+ minix_data, minix_size,
+ 2, minix_bootfile-minix_start, FS_ZERO},
+{ "hdmin","Minix Hard disk FS booter",
+ minixhd_data, minixhd_size,
+ 2, minixhd_bootfile-minixhd_start, FS_ZERO},
+{ "tar", "Bootable GNU tar volume label",
+ tarboot_data, tarboot_size, 0, 0, FS_TAR},
+{ "dos12","Boot file BOOTFILE.SYS from dos floppy",
+ msdos_data, msdos_size,
+ 1, msdos_boot_name-msdos_start, FS_DOS, 12},
+{ "dos16","Boot file BOOTFILE.SYS from FAT16 hard disk or floppy",
+ msdos16_data, msdos16_size,
+ 1, msdos16_boot_name-msdos16_start, FS_DOS, 16},
+{ "fd32l","Freedos FAT32 LBA Bootblock",
+ freedos_fat32lba, 512,
+ 0, 0, FS_DOS, 32},
+{ "fd32c","Freedos FAT32 CHS Bootblock",
+ freedos_fat32chs, 512,
+ 0, 0, FS_DOS, 32},
+#ifdef USE_WIN95BB
+{ "win95","The Windows 95 bootblock, (C) Microsoft.",
+ win95_bootblock, 512,
+ 0, 0, FS_DOS, 12},
+#endif
+{ "killhd", "Deletes MBR from hard disk when booted",
+ killhd_data, killhd_size,
+ 2, killhd_boot_message-killhd_start, FS_ADOS},
0
};
@@ -110,43 +162,85 @@ char * progname = "";
int disktype = 0;
FILE * diskfd;
-int disk_sect = 63; /* These are initilised to the maximums */
+int disk_sect = 63; /* These are initialised to the maximums */
int disk_head = 256; /* Set to the correct values when an MSDOS disk is */
int disk_trck = 256; /* successfully identified */
int force = 0;
int write_zero = 1; /* Write sector 0 */
int write_one = 0; /* Write sector 1 */
-int bs_offset = 0; /* Offset of _real_ bootsector for 2m floppies */
+int copy_zero = 0; /* Copy of sector zero */
char * boot_id = 0;
+/* Overrides for bpb in dos bootblocks. */
+unsigned char bpb_buffer[100];
+unsigned char bpb_flags[100];
+int has_bpb_overrides = 0;
+
main(argc, argv)
int argc;
char ** argv;
{
FILE * fd;
- struct bblist *ptr;
+ struct bblist *ptr = bblocks;
int i;
+ int ar, opton=1;
+ char *p;
+ char * bbname = 0;
+ char * devname = 0;
progname = argv[0];
- if( argc == 4 && strcmp(argv[1], "-f") == 0 )
- {
- argv++; argc--; force++;
- }
- if( argc != 3 ) Usage();
+ /* Traditional option processing. */
+ for(ar=1; ar<argc; ar++)
+ if(opton && argv[ar][0] == '-' && argv[ar][1] != 0)
+ for(p=argv[ar]+1;*p;p++)
+ switch(*p) {
+ char ch, * ap;
+ case '-': opton = 0; break;
+ case 'f': force++; break;
+ case 'H': set_superfield("drive=0x80");
+ case 'g': set_superfield("spt=63");
+ set_superfield("heads=255");
+ break;
+ default:
+ ch = *p;
+ if (p[1]) { ap = p+1; p=" "; }
+ else {
+ if (ar+1>=argc) Usage();
+ ap = argv[++ar];
+ }
+ switch(ch) {
+ case 'S': set_superfield(ap); break;
+ default: Usage();
+ }
+ break;
+ }
+ else {
+ if (bbname) Usage();
+ bbname = devname;
+ devname = argv[ar];
+ }
+
+ if( devname == 0 ) Usage();
+ /* First bootblock is default */
+ if( bbname == 0 ) bbname = bblocks->name;
- boot_id = strchr(argv[1], '=');
+ boot_id = strchr(bbname, '=');
if( boot_id )
*boot_id++ = '\0';
- if( (i=strlen(argv[1])) < 2 ) Usage();
+ if( (i=strlen(bbname)) < 2 ) Usage();
for(ptr = bblocks; ptr->name; ptr++)
- if( strncmp(argv[1], ptr->name, i) == 0 ) break;
+ if( strncmp(bbname, ptr->name, i) == 0 ) break;
if( ptr->name == 0 ) Usage();
- open_disk(argv[2]);
+ if (has_bpb_overrides && ptr != bblocks &&
+ ptr->fstype != FS_DOS && ptr->fstype != FS_ADOS)
+ Usage();
+
+ open_disk(devname);
if( read_sector(0, buffer) != 0 )
exit(1);
read_sector(1, buffer+512);
@@ -159,6 +253,8 @@ char ** argv;
case FS_NONE: /* override */
case FS_STAT:
case FS_ADOS:
+ if ( has_bpb_overrides )
+ check_msdos();
break;
case FS_DOS:
check_msdos();
@@ -181,19 +277,22 @@ char ** argv;
switch(ptr->fstype)
{
- case FS_STAT:
- if( strcmp(ptr->name, "copy") == 0 )
- save_super(buffer);
- else
- print_super(buffer);
- close_disk();
- exit(0);
case FS_DOS:
case FS_ADOS:
- for(i=0; i<sysboot_dosfs_stat; i++)
- buffer[i] = ptr->data[i];
- for(i=sysboot_codestart; i<512; i++)
- buffer[i] = ptr->data[i];
+ if (ptr->fsmod == 12 || ptr->fsmod == 16)
+ {
+ for(i=0; i<sysboot16_dosfs_stat; i++)
+ buffer[i] = ptr->data[i];
+ for(i=sysboot16_codestart; i<512; i++)
+ buffer[i] = ptr->data[i];
+ }
+ else
+ {
+ for(i=0; i<sysboot_dosfs_stat; i++)
+ buffer[i] = ptr->data[i];
+ for(i=sysboot_codestart; i<512; i++)
+ buffer[i] = ptr->data[i];
+ }
break;
case FS_TAR:
@@ -216,6 +315,28 @@ char ** argv;
break;
}
+ if ( has_bpb_overrides )
+ {
+ copy_superfields(buffer);
+ write_zero = 1;
+ }
+
+ switch(ptr->fstype)
+ {
+ case FS_STAT:
+ if( strcmp(ptr->name, "copy") == 0 )
+ save_super(buffer);
+ else
+ print_super(buffer);
+
+ if ( !has_bpb_overrides )
+ {
+ close_disk();
+ exit(0);
+ }
+ break;
+ }
+
if( boot_id ) switch(ptr->name_type)
{
case 1:
@@ -229,16 +350,13 @@ char ** argv;
exit(1);
}
- if( bs_offset )
- {
- if( write_zero ) do_2m_write();
- /* Don't write 1 ever! */
- }
- else
- {
- if( write_zero ) write_sector(0, buffer);
- if( write_one ) write_sector(1, buffer+512);
+ if( write_zero ) {
+ write_sector(0, buffer);
+ if (copy_zero)
+ write_sector(copy_zero, buffer); /* FAT32 backup */
}
+ if( write_one ) write_sector(1, buffer+512);
+
close_disk();
exit(0);
}
@@ -251,11 +369,12 @@ Usage()
progname = "makeboot";
#ifdef __MSDOS__
- fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n\n", progname);
+ fprintf(stderr, "Usage: %s [-f] [-S var=val] bootblock[=bootname] a:\n\n", progname);
fprintf(stderr, "The 'a:' can be any drive or file or @: for the MBR.\n");
#else
- fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n\n", progname);
+ fprintf(stderr, "Usage: %s [-f] [-S var=val] bootblock[=bootname] /dev/fd0\n\n", progname);
#endif
+ fprintf(stderr, "-S sets BPB fields in the msdos filesystem superblock.\n");
fprintf(stderr, "The bootname is a filename or message to use with the block,\n");
fprintf(stderr, "the blocks are:\n");
for(;ptr->name; ptr++)
@@ -753,49 +872,51 @@ copy_tarblock()
#define DOS7_BOOT2 23
struct bootfields {
+ char * label;
int offset;
int length;
unsigned value;
long lvalue;
+ char * new_value;
}
dosflds[] =
{
- { 0x03, 8, 0},
- { 0x0B, 2, 0},
- { 0x0D, 1, 0},
- { 0x0E, 2, 0},
- { 0x10, 1, 0},
- { 0x11, 2, 0},
- { 0x13, 2, 0},
- { 0x15, 1, 0},
- { 0x16, 2, 0},
- { 0x18, 2, 0},
- { 0x1A, 2, 0},
- { 0x1C, 4, 0},
-
- { 0x20, 4, 0}, /* DOS4+ */
- { 0x24, 1, 0},
- { 0x27, 4, 0},
- { 0x2B, 11, 0},
- { 0x36, 8, 0},
-
- { 0x20, 4, 0}, /* DOS7 FAT32 */
- { 0x24, 4, 0},
- { 0x28, 2, 0},
- { 0x2A, 2, 0},
- { 0x2C, 4, 0},
- { 0x30, 2, 0},
- { 0x32, 2, 0},
-
- { 0x40, 1, 0},
- { 0x43, 4, 0},
- { 0x47, 11, 0},
- { 0x52, 8, 0},
-
- { 0x3e8, 4, 0},
- { 0x3ec, 4, 0},
-
- { -1,0,0}
+ { "sysid", 0x03, 8, 0},
+ { "ssize", 0x0B, 2, 0},
+ { "csize", 0x0D, 1, 0},
+ { "resvs", 0x0E, 2, 0},
+ { "nofats", 0x10, 1, 0},
+ { "noroot", 0x11, 2, 0},
+ { "sects", 0x13, 2, 0},
+ { "media", 0x15, 1, 0},
+ { "fatlen", 0x16, 2, 0},
+ { "spt", 0x18, 2, 0},
+ { "heads", 0x1A, 2, 0},
+ { "hidden", 0x1C, 4, 0},
+
+ { "lsects", 0x20, 4, 0}, /* DOS4+ */
+ { "drive", 0x24, 1, 0},
+ { "serial", 0x27, 4, 0},
+ { "label", 0x2B, 11, 0},
+ { "fatid", 0x36, 8, 0},
+
+ { "lsects", 0x20, 4, 0}, /* DOS7 FAT32 */
+ { "fatlen", 0x24, 4, 0},
+ { "flags", 0x28, 2, 0},
+ { "version",0x2A, 2, 0},
+ { "root", 0x2C, 4, 0},
+ { "info", 0x30, 2, 0},
+ { "boot", 0x32, 2, 0},
+
+ { "drive", 0x40, 1, 0},
+ { "serial", 0x43, 4, 0},
+ { "label", 0x47, 11, 0},
+ { "fatid", 0x52, 8, 0},
+
+ { 0, 0x3e8, 4, 0},
+ { 0, 0x3ec, 4, 0},
+
+ { 0, -1,0,0}
};
print_super(bootsect)
@@ -815,13 +936,13 @@ static char * fieldnames[] = {
"Heads",
"Hidden sectors (Partition offset)",
- "Large Filesystem sector count",
- "Phys drive",
- "Serial number",
- "Disk Label (DOS 4+)",
- "FAT type",
+ "DOS4 Large Filesystem sector count",
+ "DOS4 Phys drive",
+ "DOS4 Serial number",
+ "DOS4 Disk Label (DOS 4+)",
+ "DOS4 FAT type",
- "Large Filesystem sector count",
+ "FAT32 Filesystem sector count",
"FAT32 FAT length",
"FAT32 Flags",
"FAT32 version",
@@ -911,6 +1032,11 @@ char * bootsect;
else
dosflds[i].lvalue = dosflds[i].value = 0;
}
+
+ if (dosflds[DOS_FATLEN].value == 0)
+ copy_zero = dosflds[DOS7_BOOT2].value;
+ else
+ copy_zero = 0;
}
save_super(bootsect)
@@ -926,6 +1052,61 @@ char * bootsect;
fclose(fd);
}
+set_superfield(setstr)
+char * setstr;
+{
+ int i, l;
+ char * av;
+ has_bpb_overrides = 1;
+
+ av = strchr(setstr, '=');
+ if (av == 0) Usage();
+ l = av++ - setstr;
+
+ for(i=0; dosflds[i].offset >= 0; i++)
+ {
+ if ( dosflds[i].label &&
+ l == strlen(dosflds[i].label) &&
+ strncmp(dosflds[i].label, setstr, l) == 0)
+ dosflds[i].new_value = av;
+ }
+}
+
+copy_superfields(bootsect)
+char * bootsect;
+{
+ int i, j;
+
+ for(i=0; dosflds[i].offset >= 0; i++)
+ {
+ if (dosflds[i].new_value == 0) continue;
+ if( i>= DOS4_MAXSECT &&
+ (dosflds[DOS_FATLEN].value==0) != (i>=DOS7_MAXSECT) )
+ {
+ continue;
+ }
+
+ if( dosflds[i].length <= 4 )
+ {
+ long v = 0;
+ v = strtol(dosflds[i].new_value, 0, 0);
+ for(j=0; j<dosflds[i].length; j++)
+ {
+ bootsect[dosflds[i].offset+j] = (v & 0xFF);
+ v >>= 8;
+ }
+ }
+ else
+ {
+ char * p = dosflds[i].new_value;
+ for(j=0; j<dosflds[i].length && *p; j++)
+ {
+ bootsect[dosflds[i].offset+j] = *p++;
+ }
+ }
+ }
+}
+
/**************************************************************************/
check_msdos()
@@ -949,35 +1130,6 @@ check_msdos()
if( disk_sect > 0 && disk_head > 0 )
disk_trck = dosflds[DOS_MAXSECT].value/disk_head/disk_sect;
-#ifndef __MSDOS__
- if( bs_offset == 0 &&
- memcmp(buffer+dosflds[DOS_SYSID].offset, "2M-STV0", 7) == 0)
- {
- printf("Floppy is in 2M format - reading 2nd boot block\n");
- bs_offset = dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value;
- if( read_sector(bs_offset, buffer) != 0 )
- exit(1);
-
- decode_super(buffer);
- if( dosflds[DOS_MEDIA].value < 0xF0 ||
- ( dosflds[DOS_MEDIA].value != (0xFF&buffer[512])
- && dosflds[DOS_RESV].value == 1 ) )
- {
- if( force )
- {
- printf("Bad 2nd boot block - reloading first\n");
- if( read_sector(0, buffer) != 0 )
- exit(1);
- }
- else
- {
- printf("Bad 2nd boot block\n");
- exit(1);
- }
- }
- check_msdos();
- }
-#endif
return;
}
if(!force) exit(2);
@@ -1013,22 +1165,28 @@ int bb_fatbits;
fatbits=12;
else if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT16", 5) == 0 )
fatbits=16;
+ else if(dosflds[DOS_FATLEN].value == 0)
+ fatbits=32;
else
fatbits=12+4*(numclust > 0xFF0) + 16*(numclust > 0xFFF0L);
if( dosflds[DOS_NFAT].value > 2 )
err = "Too many fat copies on disk";
- else if( dosflds[DOS_NROOT].value < 15 )
- err = "Root directory has unreasonable size.";
else if( dosflds[DOS_SECT].value != 512 )
err = "Drive sector size isn't 512 bytes sorry no-go.";
else if( fatbits == 16 && numclust < 0xFF0 )
err = "Weirdness, FAT16 but less than $FF0 clusters";
else if( fatbits != bb_fatbits )
err = "Filesystem has the wrong fat type for this bootblock.";
- else if( numclust * dosflds[DOS_CLUST].lvalue /
+
+ if( !err && (bb_fatbits == 12 || bb_fatbits == 16))
+ {
+ if( dosflds[DOS_NROOT].value < 15 )
+ err = "Root directory has unreasonable size.";
+ else if( numclust * dosflds[DOS_CLUST].lvalue /
dosflds[DOS_SPT].value > 65535 )
- err = "Boot sector untested with more than 65535 tracks";
+ err = "Boot sector untested with more than 65535 tracks";
+ }
if( !err && bb_fatbits == 12 )
{
@@ -1162,292 +1320,3 @@ char * mbr_data;
write_zero = 1;
}
-/**************************************************************************/
-
-#ifdef HAS_2M20
-
-char boot_sector_2m_23_82[] = {
-0xe9,0x7d,0x00,0x32,0x4d,0x2d,0x53,0x54,0x56,0x30,0x34,0x00,0x02,0x01,0x01,0x00,
-0x02,0xe0,0x00,0xbc,0x0e,0xfa,0x0b,0x00,0x17,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x45,0xb8,0x25,0x51,0x4e,0x4f,0x20,0x4e,0x41,
-0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x00,0x3f,
-0x07,0x01,0x00,0x00,0x80,0x00,0x4c,0x00,0x61,0x00,0x79,0x00,0x13,0x46,0x01,0x02,
-0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
-0x13,0x40,0x03,0x07,0x81,0x04,0x04,0x8c,0x01,0x04,0x97,0x05,0x04,0xa2,0x02,0x04,
-0xad,0x06,0x03,0xb3,0x03,0x04,0xbe,0x07,0x02,0x04,0x04,0x04,0x04,0x04,0x03,0x02,
-0xfa,0x33,0xc0,0x8e,0xd0,0xbc,0x00,0x7c,0xb8,0xc0,0x07,0x50,0x05,0x20,0x00,0x50,
-0x07,0x1f,0x33,0xf6,0x33,0xff,0xb9,0x00,0x01,0xfc,0xf3,0xa5,0x8b,0x1e,0x44,0x00,
-0x8d,0x47,0x26,0x06,0x50,0xcb,0xfb,0xbe,0x1a,0x01,0xe8,0xd9,0x00,0xbb,0x78,0x00,
-0x36,0xc5,0x37,0x1e,0x56,0x33,0xff,0x36,0x89,0x3f,0x36,0x8c,0x47,0x02,0xb9,0x0b,
-0x00,0xf3,0xa4,0x06,0x1f,0xa0,0x18,0x00,0x88,0x45,0xf9,0x33,0xc0,0x8e,0xc0,0xbb,
-0x00,0x7c,0x26,0x89,0x87,0xfe,0x01,0xb8,0x01,0x02,0x8b,0x0e,0x16,0x00,0x83,0xc1,
-0x02,0x33,0xd2,0x83,0xf9,0x0a,0x72,0x1f,0x51,0xcd,0x13,0x59,0x36,0x8b,0x1e,0x13,
-0x04,0x83,0xeb,0x05,0xb8,0x40,0x00,0xf7,0xe3,0x8e,0xc0,0x53,0x33,0xdb,0xb8,0x05,
-0x02,0x41,0x33,0xd2,0xcd,0x13,0x5b,0x36,0x8f,0x06,0x78,0x00,0x36,0x8f,0x06,0x7a,
-0x00,0x26,0x81,0x3e,0xfe,0x09,0x55,0xaa,0x75,0x60,0x36,0x89,0x1e,0x13,0x04,0x06,
-0xb4,0x08,0xb3,0x00,0xb2,0x00,0xcd,0x13,0x8a,0xc3,0xb4,0x00,0x80,0xfa,0x02,0x72,
-0x0c,0x50,0xb4,0x08,0xb3,0x00,0xb2,0x01,0xcd,0x13,0x58,0x8a,0xe3,0x07,0x26,0x8c,
-0x06,0xfe,0x09,0x26,0xff,0x1e,0xfc,0x09,0xb8,0x01,0x02,0x33,0xd2,0x8e,0xc2,0xb9,
-0x01,0x00,0xbb,0x00,0x80,0x50,0xcd,0x13,0x58,0xbb,0x00,0x7c,0x06,0x53,0x26,0x81,
-0x7f,0x03,0x32,0x4d,0x75,0x04,0xb2,0x80,0xcd,0x13,0x26,0x81,0x3e,0xfe,0x7d,0x55,
-0xaa,0x75,0x03,0x33,0xd2,0xcb,0x22,0xd2,0x74,0xec,0xbe,0x2f,0x01,0xe8,0x06,0x00,
-0xb4,0x00,0xcd,0x16,0xcd,0x19,0x03,0x36,0x44,0x00,0xfc,0xac,0x22,0xc0,0x74,0x09,
-0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,0xf1,0xc3,0x0d,0x0a,0x32,0x4d,0x20,0x53,
-0x75,0x70,0x65,0x72,0x42,0x4f,0x4f,0x54,0x20,0x32,0x2e,0x30,0x0d,0x0a,0x00,0x0d,
-0x0a,0xad,0x4e,0x6f,0x20,0x62,0x6f,0x74,0x61,0x62,0x6c,0x65,0x21,0x0d,0x0a,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x4d,0x61,0x64,0x65,0x20,0x69,0x6e,0x20,0x53,0x70,0x61,0x69,0x6e,0x00,0x55,0xaa
-};
-
-char boot_sector_2m_22_82[] = {
-0xe9,0x6e,0x00,0x32,0x4d,0x2d,0x53,0x54,0x56,0x30,0x38,0x00,0x02,0x01,0x01,0x00,
-0x02,0xe0,0x00,0x18,0x0e,0xfa,0x0b,0x00,0x16,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x29,0xcc,0x9b,0xe1,0xd4,0x4e,0x4f,0x20,0x4e,0x41,
-0x4d,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x00,0x04,
-0x07,0x00,0x00,0x00,0x71,0x00,0x4c,0x00,0x61,0x00,0x66,0x00,0x13,0x46,0x01,0x02,
-0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
-0x13,0x0b,0x28,0x03,0x01,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,
-0x03,0xfa,0x33,0xc0,0x8e,0xd0,0xbc,0x00,0x7c,0xb8,0xc0,0x07,0x50,0x05,0x20,0x00,
-0x50,0x07,0x1f,0x33,0xf6,0x33,0xff,0xb9,0x00,0x01,0xfc,0xf3,0xa5,0x8b,0x1e,0x44,
-0x00,0x8d,0x47,0x26,0x06,0x50,0xcb,0xfb,0xbe,0x1a,0x01,0xe8,0xd9,0x00,0xbb,0x78,
-0x00,0x36,0xc5,0x37,0x1e,0x56,0x33,0xff,0x36,0x89,0x3f,0x36,0x8c,0x47,0x02,0xb9,
-0x0b,0x00,0xf3,0xa4,0x06,0x1f,0xa0,0x18,0x00,0x88,0x45,0xf9,0x33,0xc0,0x8e,0xc0,
-0xbb,0x00,0x7c,0x26,0x89,0x87,0xfe,0x01,0xb8,0x01,0x02,0x8b,0x0e,0x16,0x00,0x83,
-0xc1,0x02,0x33,0xd2,0x83,0xf9,0x0a,0x72,0x1f,0x51,0xcd,0x13,0x59,0x36,0x8b,0x1e,
-0x13,0x04,0x83,0xeb,0x05,0xb8,0x40,0x00,0xf7,0xe3,0x8e,0xc0,0x53,0x33,0xdb,0xb8,
-0x05,0x02,0x41,0x33,0xd2,0xcd,0x13,0x5b,0x36,0x8f,0x06,0x78,0x00,0x36,0x8f,0x06,
-0x7a,0x00,0x26,0x81,0x3e,0xfe,0x09,0x55,0xaa,0x75,0x60,0x36,0x89,0x1e,0x13,0x04,
-0x06,0xb4,0x08,0xb3,0x00,0xb2,0x00,0xcd,0x13,0x8a,0xc3,0xb4,0x00,0x80,0xfa,0x02,
-0x72,0x0c,0x50,0xb4,0x08,0xb3,0x00,0xb2,0x01,0xcd,0x13,0x58,0x8a,0xe3,0x07,0x26,
-0x8c,0x06,0xfe,0x09,0x26,0xff,0x1e,0xfc,0x09,0xb8,0x01,0x02,0x33,0xd2,0x8e,0xc2,
-0xb9,0x01,0x00,0xbb,0x00,0x80,0x50,0xcd,0x13,0x58,0xbb,0x00,0x7c,0x06,0x53,0x26,
-0x81,0x7f,0x03,0x32,0x4d,0x75,0x04,0xb2,0x80,0xcd,0x13,0x26,0x81,0x3e,0xfe,0x7d,
-0x55,0xaa,0x75,0x03,0x33,0xd2,0xcb,0x22,0xd2,0x74,0xec,0xbe,0x2f,0x01,0xe8,0x06,
-0x00,0xb4,0x00,0xcd,0x16,0xcd,0x19,0x03,0x36,0x44,0x00,0xfc,0xac,0x22,0xc0,0x74,
-0x09,0xb4,0x0e,0xbb,0x07,0x00,0xcd,0x10,0xeb,0xf1,0xc3,0x0d,0x0a,0x32,0x4d,0x20,
-0x53,0x75,0x70,0x65,0x72,0x42,0x4f,0x4f,0x54,0x20,0x32,0x2e,0x30,0x0d,0x0a,0x00,
-0x0d,0x0a,0xad,0x4e,0x6f,0x20,0x62,0x6f,0x74,0x61,0x62,0x6c,0x65,0x21,0x0d,0x0a,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x4d,0x61,0x64,0x65,0x20,0x69,0x6e,0x20,0x53,0x70,0x61,0x69,0x6e,0x00,0x55,0xaa
-};
-
-
-char program_2m_vsn_20[] = {
-0x2b,0x00,0x43,0x00,0x32,0x30,0x32,0x4d,0x2d,0x53,0x54,0x56,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x4a,0x42,0x00,0x00,0x01,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0xfc,0x9c,0x56,0x80,
-0xfa,0x02,0x73,0x3d,0xe8,0x41,0x00,0x2e,0x80,0x3c,0x02,0x74,0x04,0x2e,0x80,0x3c,
-0x04,0x72,0x2e,0x80,0xfc,0x02,0x72,0x29,0x80,0xfc,0x05,0x77,0x24,0x75,0x05,0xe8,
-0x36,0x00,0xeb,0x1d,0xe8,0x85,0x00,0x73,0x09,0x5e,0x9d,0xf9,0xb8,0x00,0x06,0xca,
-0x02,0x00,0x2e,0x80,0x7c,0x01,0x00,0x74,0x08,0x5e,0x9d,0xe8,0x3c,0x02,0xca,0x02,
-0x00,0x5e,0x9d,0x2e,0xff,0x2e,0xfc,0x09,0x9c,0x53,0x8a,0xda,0xb7,0x00,0xd1,0xe3,
-0x2e,0x8b,0xb7,0x00,0x00,0x5b,0x9d,0xc3,0x60,0xe8,0xec,0xff,0xb0,0x01,0x72,0x02,
-0xb0,0x00,0x2e,0x88,0x44,0x01,0x61,0xc3,0x50,0xa0,0x12,0x00,0x0a,0x06,0x11,0x00,
-0x58,0xc3,0x60,0x1e,0x6a,0x40,0x1f,0xb0,0x01,0x8a,0xca,0xd2,0xe0,0x84,0x06,0x3f,
-0x00,0x75,0x04,0xf8,0xe8,0xef,0x05,0x8a,0xe2,0xc0,0xe4,0x04,0x0a,0xe0,0xc0,0xe0,
-0x04,0x0c,0x0c,0x0a,0xc2,0xba,0xf2,0x03,0xfa,0x88,0x26,0x3f,0x00,0xee,0x83,0xc2,
-0x05,0xeb,0x00,0xeb,0x00,0xec,0xfb,0xa8,0x80,0x1f,0x61,0xc3,0x60,0xe8,0x98,0xff,
-0x2e,0x80,0x7c,0x02,0x01,0x2e,0xc6,0x44,0x02,0x00,0x74,0x08,0xe8,0xb3,0xff,0x75,
-0x03,0x61,0xf8,0xc3,0xf8,0xe8,0x90,0xff,0x1e,0x06,0xbb,0x90,0x00,0x02,0xda,0x6a,
-0x40,0x1f,0x80,0x27,0xef,0x0e,0x0e,0x1f,0x07,0x88,0x16,0x0c,0x00,0xf9,0xe8,0x29,
-0x05,0xc6,0x06,0x11,0x00,0x01,0xc6,0x06,0x12,0x00,0x00,0xe8,0xa1,0x05,0xfe,0x0e,
-0x11,0x00,0xe8,0x9a,0x05,0xf8,0xe8,0x7d,0x05,0xe8,0x76,0xff,0x74,0x07,0xc6,0x44,
-0x02,0x01,0xf8,0xeb,0x68,0x1e,0x6a,0x40,0x1f,0xc6,0x06,0x41,0x00,0x06,0x1f,0xc6,
-0x06,0x1b,0x00,0xff,0xc6,0x44,0x08,0x14,0xb9,0x03,0x00,0x51,0x83,0xf9,0x02,0xe8,
-0xe8,0x04,0xc6,0x44,0x06,0x00,0xc6,0x06,0x11,0x00,0x00,0xc6,0x06,0x12,0x00,0x00,
-0xc6,0x06,0x13,0x00,0x01,0xc6,0x06,0x16,0x00,0x00,0xc6,0x06,0x17,0x00,0x01,0xc6,
-0x06,0x27,0x00,0x46,0x8b,0x3e,0x19,0x00,0xe8,0x7f,0x02,0x75,0x0b,0x59,0x8b,0x1e,
-0x19,0x00,0xe8,0x1c,0x00,0xf8,0xeb,0x14,0x8a,0x44,0x06,0x40,0x3c,0x03,0x77,0x05,
-0x88,0x44,0x06,0xeb,0xc1,0xc6,0x44,0x06,0x00,0x59,0xe2,0xaf,0xf9,0x07,0x1f,0x61,
-0xc3,0x60,0xe8,0x88,0x00,0x72,0x5c,0x88,0x44,0x05,0x88,0x4c,0x03,0x8a,0x16,0x0c,
-0x00,0xf9,0xe8,0xd3,0xfe,0x26,0x8a,0x47,0x16,0x88,0x44,0x17,0x26,0x8a,0x4f,0x41,
-0x88,0x4c,0x04,0x26,0x8b,0x47,0x42,0x89,0x44,0x06,0x26,0x8a,0x47,0x18,0x88,0x44,
-0x09,0x26,0x8b,0x7f,0x48,0x26,0x8a,0x41,0x01,0x8a,0xe0,0x22,0xc9,0x74,0x0a,0x80,
-0xc4,0xbe,0xb0,0x0b,0xf6,0xe4,0x2d,0x3e,0x08,0xd0,0xe8,0x88,0x44,0x08,0xb9,0x0d,
-0x00,0x26,0x8b,0x7f,0x4a,0x03,0xfb,0x8d,0x5c,0x0a,0x26,0x8a,0x05,0x88,0x07,0x43,
-0x47,0xe2,0xf7,0x8a,0x44,0x06,0xc0,0xe0,0x06,0x0c,0x17,0x80,0x3c,0x02,0x77,0x0a,
-0x24,0xf8,0x0c,0x05,0xa8,0x40,0x74,0x02,0x34,0x21,0x1e,0xbb,0x90,0x00,0x02,0x1e,
-0x0c,0x00,0x6a,0x40,0x1f,0x80,0x27,0x08,0x08,0x07,0x1f,0x61,0xc3,0x56,0x57,0x8d,
-0x7f,0x03,0xbe,0x06,0x00,0xb9,0x06,0x00,0xf3,0xa6,0xf9,0x75,0x19,0x33,0xc0,0x26,
-0x8a,0x4f,0x40,0x80,0xf9,0x06,0x72,0x0d,0x26,0x8b,0x7f,0x44,0x4f,0x26,0x02,0x01,
-0x83,0xff,0x3f,0x77,0xf7,0xf8,0x5f,0x5e,0xc3,0x50,0x73,0x37,0x80,0x3e,0x1f,0x00,
-0x00,0x75,0x2f,0xa0,0x21,0x00,0xd0,0xe0,0xb4,0x04,0x72,0x22,0xc0,0xe0,0x02,0xb4,
-0x10,0x72,0x1b,0xd0,0xe0,0xb4,0x08,0x72,0x15,0xc0,0xe0,0x02,0xb4,0x04,0x72,0x0e,
-0xd0,0xe0,0xb4,0x03,0x72,0x08,0xd0,0xe0,0xb4,0x02,0x72,0x02,0xb4,0x20,0x08,0x26,
-0x1f,0x00,0xf9,0x58,0xc3,0x9c,0x60,0x06,0x6a,0x40,0x07,0xbf,0x41,0x00,0xbe,0x1f,
-0x00,0xb9,0x04,0x00,0xf3,0xa5,0x07,0x61,0x9d,0xc3,0x1e,0x60,0x0e,0x1f,0x88,0x16,
-0x0c,0x00,0xe8,0xc3,0xfd,0x80,0x7c,0x05,0x00,0x74,0x08,0xc6,0x06,0x1f,0x00,0x40,
-0xe9,0xbb,0x00,0x50,0xb4,0x00,0xa3,0x0d,0x00,0x8a,0xc5,0xd0,0xe0,0x8a,0xd6,0x80,
-0xe6,0x7f,0x02,0xc6,0xf6,0x64,0x09,0x02,0xc1,0x80,0xd4,0x00,0x48,0xa3,0x0f,0x00,
-0x8b,0xfb,0x5b,0x8a,0xdf,0xb7,0x00,0x8a,0x8f,0x26,0x00,0x88,0x0e,0x27,0x00,0xd0,
-0xe2,0x72,0x73,0x23,0xc0,0x75,0x2c,0x80,0x7c,0x03,0x07,0x72,0x19,0x8a,0x44,0x17,
-0x40,0xb9,0x01,0x00,0xe8,0x9b,0x00,0x75,0x6e,0xff,0x0e,0x0d,0x00,0xff,0x06,0x0f,
-0x00,0xa1,0x0f,0x00,0xeb,0x0d,0x80,0x3e,0x27,0x00,0x4a,0x75,0x06,0x81,0xc7,0x00,
-0x02,0xeb,0xe6,0x8a,0x4c,0x17,0xb5,0x00,0x3b,0xc1,0x77,0x0f,0xe8,0x5d,0x00,0xe8,
-0x70,0x00,0x75,0x43,0x83,0x3e,0x0d,0x00,0x00,0x74,0x3c,0xa1,0x0f,0x00,0x8a,0x4c,
-0x17,0xb5,0x00,0xd1,0xe1,0x3b,0xc1,0x77,0x1d,0xe8,0x40,0x00,0x80,0x3e,0x27,0x00,
-0x4a,0x75,0x07,0xc1,0xe1,0x09,0x03,0xf9,0xeb,0x0c,0x8a,0x54,0x17,0xb6,0x00,0x2b,
-0xc2,0xe8,0x3e,0x00,0x75,0x11,0x83,0x3e,0x0d,0x00,0x00,0x74,0x0a,0xa1,0x0f,0x00,
-0x8b,0x0e,0x0d,0x00,0xe8,0x2b,0x00,0xf8,0xe8,0x2b,0x03,0xe8,0x17,0xff,0x61,0x8a,
-0x26,0x1f,0x00,0x1f,0x22,0xe4,0x74,0x03,0xf9,0xb0,0x00,0xc3,0x2b,0xc8,0x41,0x3b,
-0x0e,0x0d,0x00,0x76,0x04,0x8b,0x0e,0x0d,0x00,0x29,0x0e,0x0d,0x00,0x01,0x0e,0x0f,
-0x00,0xc3,0x8b,0xd8,0x88,0x0e,0x17,0x00,0xf6,0x74,0x09,0xfe,0xc4,0x88,0x26,0x13,
-0x00,0xd0,0xe8,0xa2,0x11,0x00,0xd0,0xd0,0x24,0x01,0xa2,0x12,0x00,0xa0,0x13,0x00,
-0x02,0x06,0x17,0x00,0x72,0x06,0x48,0x3a,0x44,0x09,0x76,0x07,0xc6,0x06,0x1f,0x00,
-0x04,0xeb,0x77,0x8a,0xc4,0x98,0xe8,0xbf,0xfc,0x74,0x18,0x8d,0x5c,0x09,0x48,0x43,
-0xfe,0xc4,0x8a,0x0f,0x80,0xe9,0x02,0xb5,0x01,0xd2,0xe5,0x2a,0xc5,0x73,0xf0,0x02,
-0xc5,0x86,0xe0,0xa2,0x13,0x00,0x88,0x26,0x16,0x00,0xe8,0xe8,0x01,0xb4,0x00,0x88,
-0x26,0x15,0x00,0xe8,0x92,0xfc,0x75,0x09,0xa0,0x17,0x00,0x88,0x26,0x17,0x00,0xeb,
-0x28,0x38,0x64,0x04,0x75,0x28,0x38,0x26,0x16,0x00,0x74,0x05,0xe8,0x31,0x00,0x72,
-0x29,0x38,0x26,0x17,0x00,0x74,0x23,0xe8,0x9b,0x01,0x8a,0xc8,0xa0,0x17,0x00,0xf6,
-0xf1,0x22,0xc0,0x74,0x09,0x88,0x26,0x17,0x00,0xe8,0x82,0x00,0x72,0x0c,0x80,0x3e,
-0x17,0x00,0x00,0x74,0x05,0xe8,0x08,0x00,0x73,0xf4,0x80,0x3e,0x1f,0x00,0x00,0xc3,
-0x50,0x80,0x3e,0x27,0x00,0x4a,0x74,0x16,0x80,0x3e,0x27,0x00,0x42,0x74,0x3b,0xe8,
-0xbb,0x00,0x73,0x05,0xe8,0xdb,0x00,0x72,0x48,0xe8,0x6f,0x00,0xeb,0x43,0x80,0x3e,
-0x16,0x00,0x00,0x75,0x09,0xe8,0x4d,0x01,0x38,0x06,0x17,0x00,0x73,0x14,0xe8,0x9c,
-0x00,0x73,0x0f,0xc6,0x06,0x27,0x00,0x46,0xe8,0xb7,0x00,0xc6,0x06,0x27,0x00,0x4a,
-0x72,0x1f,0xe8,0x46,0x00,0xe8,0xaa,0x00,0xeb,0x17,0x53,0x8a,0x1e,0x16,0x00,0xe8,
-0x23,0x01,0xfe,0x0e,0x17,0x00,0x74,0x05,0x43,0x3a,0xd8,0x72,0xf5,0x5b,0xe8,0x91,
-0x00,0x9c,0xfe,0x06,0x13,0x00,0xc6,0x06,0x16,0x00,0x00,0x9d,0x58,0xc3,0x50,0x22,
-0xc0,0x74,0x16,0x8a,0x26,0x13,0x00,0x88,0x26,0x14,0x00,0x02,0xc4,0x48,0xa2,0x15,
-0x00,0xfe,0xc0,0xe8,0x6c,0x00,0xa2,0x13,0x00,0x58,0xc3,0x50,0x53,0x51,0x56,0x8a,
-0x1e,0x16,0x00,0xe8,0xdf,0x00,0x53,0xc1,0xe3,0x09,0x03,0x1e,0x19,0x00,0x8b,0xf3,
-0xb9,0x00,0x01,0xe8,0x16,0x00,0xf3,0xa5,0xe8,0x11,0x00,0x5b,0xfe,0x0e,0x17,0x00,
-0x74,0x05,0x43,0x3a,0xd8,0x72,0xdf,0x5e,0x59,0x5b,0x58,0xc3,0x2e,0x80,0x3e,0x27,
-0x00,0x4a,0x74,0x02,0xf8,0xc3,0x87,0xf7,0x06,0x1e,0x07,0x1f,0xc3,0x50,0xa0,0x1b,
-0x00,0x3a,0x06,0x0c,0x00,0x75,0x18,0xa0,0x11,0x00,0x8a,0x26,0x12,0x00,0x3b,0x06,
-0x1c,0x00,0x75,0x0b,0xa0,0x1e,0x00,0x3a,0x06,0x13,0x00,0x75,0x02,0x58,0xc3,0xf9,
-0x58,0xc3,0x50,0x53,0xe8,0x78,0x01,0x73,0x0f,0x80,0x3e,0x1f,0x00,0x00,0x75,0x05,
-0x80,0x0e,0x1f,0x00,0x40,0xf9,0xeb,0x6a,0xe8,0x3d,0xfb,0xb0,0x02,0x74,0x0d,0x8d,
-0x5c,0x0a,0x02,0x1e,0x13,0x00,0x80,0xd7,0x00,0x8a,0x47,0xff,0xa2,0x18,0x00,0x80,
-0x3e,0x15,0x00,0x00,0x74,0x0b,0xe8,0x5c,0x02,0xc6,0x06,0x15,0x00,0x00,0x9c,0xeb,
-0x3d,0x06,0x57,0x0e,0x07,0x8b,0x3e,0x19,0x00,0xa0,0x13,0x00,0xa2,0x14,0x00,0xa2,
-0x15,0x00,0xe8,0x40,0x02,0xc6,0x06,0x15,0x00,0x00,0x5f,0x07,0x9c,0xb0,0xff,0x72,
-0x0a,0x80,0x3e,0x27,0x00,0x42,0x74,0x16,0xa0,0x0c,0x00,0xa2,0x1b,0x00,0xa0,0x11,
-0x00,0x8a,0x26,0x12,0x00,0xa3,0x1c,0x00,0xa0,0x13,0x00,0xa2,0x1e,0x00,0x9d,0xe8,
-0x97,0xfc,0x5b,0x58,0xc3,0xe8,0xd0,0xfa,0xb0,0x01,0x74,0x18,0x53,0x51,0x8d,0x5c,
-0x0a,0x02,0x1e,0x13,0x00,0x80,0xd7,0x00,0x8a,0x4f,0xff,0x80,0xe9,0x02,0xb0,0x01,
-0xd2,0xe0,0x59,0x5b,0xc3,0x60,0x1e,0xbb,0x40,0x00,0x53,0x1f,0xb5,0xed,0xfa,0x2e,
-0x8a,0x0e,0x0c,0x00,0xb0,0x01,0xd2,0xe0,0x84,0x47,0xff,0x74,0x04,0x38,0x2f,0x76,
-0x33,0x08,0x47,0xff,0x80,0x67,0xff,0xcf,0x8a,0xc1,0xc0,0xe0,0x04,0x08,0x47,0xff,
-0xc6,0x07,0xff,0xfb,0xba,0xf2,0x03,0x80,0xc1,0x04,0xb0,0x01,0xd2,0xe0,0x2e,0x0a,
-0x06,0x0c,0x00,0x0c,0x0c,0xee,0xb8,0xfd,0x90,0xf8,0xcd,0x15,0x72,0x06,0xb8,0xe8,
-0x03,0xe8,0x48,0x03,0x88,0x2f,0xfb,0x1f,0x61,0xc3,0x60,0xe8,0x68,0x00,0x8a,0x0e,
-0x0c,0x00,0x8a,0xc1,0xc0,0xe0,0x02,0x0c,0x01,0xd2,0xe0,0x1e,0x6a,0x40,0x1f,0xfa,
-0xa2,0x3f,0x00,0x80,0x26,0x3e,0x00,0x70,0x1f,0xc0,0xe0,0x04,0x0a,0xc1,0x0c,0x08,
-0xba,0xf2,0x03,0xee,0xe8,0x08,0x03,0x0c,0x04,0xee,0xe8,0x1a,0x02,0xb0,0x08,0xe8,
-0xc3,0x02,0xe8,0x82,0x02,0xe8,0x7f,0x02,0xe8,0x02,0x00,0x61,0xc3,0x50,0x1e,0x6a,
-0x40,0x1f,0x8a,0x26,0x8b,0x00,0x1f,0xb0,0x03,0xe8,0xa9,0x02,0xb0,0xbf,0x80,0xe4,
-0xc0,0x74,0x09,0xb0,0xaf,0x80,0xfc,0xc0,0x74,0x02,0xb0,0xdf,0xe8,0x96,0x02,0xb0,
-0x02,0xe8,0x91,0x02,0x58,0xc3,0x60,0x1e,0xb0,0xff,0x72,0x0a,0x6a,0x00,0x1f,0xc5,
-0x1e,0x78,0x00,0x8a,0x47,0x02,0x6a,0x40,0x1f,0xa2,0x40,0x00,0x1f,0x61,0xc3,0x60,
-0xe8,0x87,0x00,0xe8,0xb7,0xff,0xb4,0x01,0x8a,0x0e,0x0c,0x00,0xd2,0xe4,0x1e,0x6a,
-0x40,0x1f,0x84,0x26,0x3e,0x00,0x1f,0x75,0x05,0xe8,0xa6,0x00,0x72,0x69,0xbb,0x94,
-0x00,0x02,0x1e,0x0c,0x00,0xa0,0x11,0x00,0x1e,0x6a,0x40,0x1f,0x08,0x26,0x3e,0x00,
-0x8a,0x26,0x41,0x00,0x3a,0x07,0x88,0x07,0x1f,0x75,0x05,0x80,0xfc,0x40,0x75,0x44,
-0xb0,0x0f,0xe8,0x30,0x02,0x72,0x40,0xa0,0x12,0x00,0xc0,0xe0,0x02,0x0a,0x06,0x0c,
-0x00,0xe8,0x21,0x02,0xa0,0x11,0x00,0xe8,0x1b,0x02,0xe8,0x6a,0x01,0x72,0x28,0xb0,
-0x08,0xe8,0x11,0x02,0x72,0x21,0xe8,0xce,0x01,0x72,0x1c,0x8a,0xe0,0xe8,0xc7,0x01,
-0xf6,0xc4,0xc0,0x75,0x12,0xb0,0x0f,0x80,0x3e,0x27,0x00,0x4a,0x74,0x02,0xb0,0x01,
-0x98,0xe8,0x38,0x02,0x61,0xf8,0xc3,0x61,0xf9,0xc3,0x60,0xe8,0x4a,0xf9,0x8b,0x44,
-0x06,0x74,0x02,0x8a,0xc4,0x1e,0x6a,0x40,0x1f,0x8a,0x26,0x8b,0x00,0xc0,0xec,0x06,
-0x3a,0xc4,0x74,0x10,0xba,0xf7,0x03,0xee,0xc0,0xe0,0x06,0x80,0x26,0x8b,0x00,0x3f,
-0x08,0x06,0x8b,0x00,0x1f,0xbf,0x1f,0x00,0xb9,0x08,0x00,0x88,0x2d,0x47,0xe2,0xfb,
-0x61,0xc3,0x60,0xbb,0x94,0x00,0x02,0x1e,0x0c,0x00,0x1e,0x6a,0x40,0x1f,0x88,0x3f,
-0x1f,0xb9,0x02,0x00,0xb0,0x07,0xe8,0x9c,0x01,0x72,0x35,0xa0,0x12,0x00,0xc0,0xe0,
-0x02,0x0a,0x06,0x0c,0x00,0xe8,0x8d,0x01,0x72,0x26,0xe8,0xda,0x00,0x72,0x21,0xb0,
-0x08,0xe8,0x81,0x01,0x72,0x1a,0xe8,0x3e,0x01,0x72,0x15,0x8a,0xe0,0xe8,0x37,0x01,
-0x80,0xf4,0x20,0xf6,0xc4,0xf0,0x75,0x08,0xb8,0x01,0x00,0xe8,0xae,0x01,0xeb,0x03,
-0xe2,0xc2,0xf9,0x61,0xc3,0x50,0x53,0x51,0x52,0x8a,0x0e,0x18,0x00,0xb5,0x00,0xf9,
-0xd2,0xd5,0xb1,0x00,0xa0,0x15,0x00,0x2a,0x06,0x14,0x00,0x40,0x98,0xf7,0xe1,0x8b,
-0xd0,0x8b,0xc8,0x49,0x8c,0xc0,0xe8,0x72,0x00,0x72,0x6a,0xa0,0x27,0x00,0xe8,0xb7,
-0x00,0x3c,0x4a,0xb0,0xc5,0x74,0x02,0xb0,0xe6,0xe8,0x29,0x01,0x72,0x57,0xa0,0x12,
-0x00,0xc0,0xe0,0x02,0x0a,0x06,0x0c,0x00,0xe8,0x1a,0x01,0xa0,0x11,0x00,0xe8,0x14,
-0x01,0xa0,0x12,0x00,0xe8,0x0e,0x01,0xa0,0x14,0x00,0xe8,0x08,0x01,0xa0,0x18,0x00,
-0xe8,0x02,0x01,0xa0,0x15,0x00,0xe8,0xfc,0x00,0x8a,0x44,0x08,0xe8,0xf6,0x00,0xb0,
-0x80,0xe8,0xf1,0x00,0xe8,0x40,0x00,0x9c,0xbb,0x20,0x00,0xb9,0x07,0x00,0xe8,0xa6,
-0x00,0x88,0x07,0x43,0xe2,0xf8,0x9d,0x72,0x0c,0xf6,0x06,0x20,0x00,0xc0,0x75,0x05,
-0x03,0xfa,0xf8,0xeb,0x01,0xf9,0x5a,0x59,0x5b,0x58,0xc3,0x52,0xbb,0x10,0x00,0xf7,
-0xe3,0x03,0xc7,0x83,0xd2,0x00,0x8b,0xd8,0x8a,0xe2,0x8b,0xd1,0x03,0xd3,0x73,0x05,
-0xc6,0x06,0x1f,0x00,0x09,0x5a,0xc3,0xfb,0x60,0x1e,0x6a,0x40,0x1f,0xb8,0x01,0x90,
-0xf8,0xcd,0x15,0xba,0x80,0x02,0xbb,0x3e,0x00,0x72,0x0f,0x33,0xc9,0x84,0x17,0x75,
-0x0f,0xe8,0xf6,0x00,0xe2,0xf7,0xfe,0xce,0x75,0xf1,0x2e,0x08,0x16,0x1f,0x00,0xf9,
-0x9c,0x80,0x27,0x7f,0x9d,0x1f,0x61,0xc3,0x50,0xfa,0xe6,0x0b,0xb0,0x00,0xeb,0x00,
-0xeb,0x00,0xe6,0x0c,0x8a,0xc3,0xeb,0x00,0xeb,0x00,0xe6,0x04,0x8a,0xc7,0xeb,0x00,
-0xeb,0x00,0xe6,0x04,0xeb,0x00,0xeb,0x00,0x8a,0xc4,0xe6,0x81,0x8a,0xc1,0xeb,0x00,
-0xeb,0x00,0xe6,0x05,0x8a,0xc5,0xeb,0x00,0xeb,0x00,0xe6,0x05,0xfb,0xb0,0x02,0xeb,
-0x00,0xeb,0x00,0xe6,0x0a,0x58,0xc3,0x51,0x52,0x50,0xe8,0x72,0x00,0xba,0xf4,0x03,
-0xb9,0x85,0x00,0xeb,0x00,0xeb,0x00,0xec,0x24,0xc0,0x3c,0xc0,0x74,0x1c,0xeb,0x00,
-0xeb,0x00,0xe4,0x61,0x24,0x10,0x3a,0xc4,0x74,0xe9,0x8a,0xe0,0xe2,0xe5,0x58,0x5a,
-0x59,0x80,0x0e,0x1f,0x00,0x80,0xb0,0x00,0xf9,0xc3,0x58,0x42,0xeb,0x00,0xeb,0x00,
-0xec,0x5a,0x59,0xf8,0xc3,0x51,0x52,0x50,0xe8,0x34,0x00,0xba,0xf4,0x03,0xb9,0x85,
-0x00,0xeb,0x00,0xeb,0x00,0xec,0xa8,0x80,0x75,0x1a,0xeb,0x00,0xeb,0x00,0xe4,0x61,
-0x24,0x10,0x3a,0xc4,0x74,0xeb,0x8a,0xe0,0xe2,0xe7,0x58,0x5a,0x59,0x80,0x0e,0x1f,
-0x00,0x80,0xf9,0xc3,0x42,0x58,0xeb,0x00,0xeb,0x00,0xee,0x5a,0x59,0xf8,0xc3,0x50,
-0x51,0xb9,0x04,0x00,0xe8,0x23,0x00,0xe2,0xfb,0x59,0x58,0xc3,0x9c,0x60,0xba,0x4a,
-0x42,0xf7,0xe2,0x8a,0xcc,0x8a,0xea,0x8a,0xd6,0xb6,0x00,0xe8,0x0c,0x00,0xe2,0xfb,
-0x23,0xd2,0x74,0x03,0x4a,0xeb,0xf4,0x61,0x9d,0xc3,0xeb,0x00,0xeb,0x00,0xe4,0x61,
-0x24,0x10,0x3a,0xc4,0x74,0xf4,0x8a,0xe0,0xc3,0x1e,0x16,0x1f,0x26,0xa2,0x2b,0x00,
-0x26,0x88,0x26,0x43,0x00,0xbf,0xfc,0x09,0xbe,0x4c,0x00,0xfc,0xfa,0xa5,0xa5,0xc7,
-0x44,0xfc,0x5b,0x00,0x8c,0x44,0xfe,0xfb,0x1f,0xcb,0x00,0x00,0xd9,0x09,0x55,0xaa
-};
-#endif
-
-char program_2m_magic[] = {
-0x2b,0x00,0x43,0x00,0x32,0x30,0x32,0x4d,0x2d,0x53,0x54,0x56,0x00,0x00,0x00,0x00
-};
-
-do_2m_write()
-{
- int i;
- char * mbr;
-
- if( read_sector(bs_offset+1, buffer+512) != 0 )
- exit(1);
-
- if( memcmp(buffer+512, program_2m_magic, 16) == 0 )
- {
- /* Seems to be properly formatted already */
-
- write_sector(bs_offset, buffer);
- return;
- }
-#ifdef HAS_2M20
- else if( disk_trck != 82 || disk_sect != 22 )
- {
- fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with DOS 2m.\n");
- if( !force ) exit(1);
- fprintf(stderr, "But I'll try it\n");
- }
- write_sector(bs_offset, buffer);
-
- /* This needs to be altered to allow for the disk format description to
- be copied from the old boot sector */
-
- if( disk_sect == 23 ) mbr = boot_sector_2m_23_82;
- else mbr = boot_sector_2m_22_82;
-
- for(i=0; i<sysboot_dosfs_stat; i++)
- buffer[i] = mbr[i];
- for(i=sysboot_codestart; i<512; i++)
- buffer[i] = mbr[i];
-
- write_sector(0, buffer);
-
- for(i=0; i<sizeof(program_2m_vsn_20); i+=512)
- {
- write_sector(bs_offset+i/512+1, program_2m_vsn_20+i);
- }
-#else
- fprintf(stderr, "To be bootable a 2M disk must be formatted with the DOS 2m driver.\n");
- exit(1);
-#endif
-}
diff --git a/bootblocks/mbr.s b/bootblocks/mbr.s
index fdfadca..fb3ac50 100644
--- a/bootblocks/mbr.s
+++ b/bootblocks/mbr.s
@@ -1,513 +1,606 @@
!
! This is a 'Master Boot Record' following the MSDOS 'standards'.
-! This BB successfully boots MSDOS or Linux.
+! This BB successfully boots MSDOS, Windows or Linux in CHS or Linear.
!
-! In addition it can:
-! Display a message configure at install time.
-! Load and execute a small program before the boot blocks are checked.
-!
-! Or
-!
-! Space for 12 extra partitions in the 'Old Disk Manager' form that Linux
-! _does_ understand (unfortunatly there doesn't appear to be an fdisk that
-! understands them.)
+! Copyright GPL2, Robert de Bath, 1996-2008.
!
! NB: This needs as86 0.16.0 or later
-
+!
! Lowest available is $0500, MSDOS appears to use $0600 ... I wonder why?
-ORGADDR=$0500
-copyright=1 ! Add in the copyright message; if room.
-preboot=0 ! Include the pre-boot loader.
-mbrkey=0 ! Option to choose the boot record based on keystroke
-message=1 ! Display boot message
-use512=0 ! Put the end marker at byte 510..512
-markptab=1 ! Put an end marker just below the partition table.
+ORGADDR=$0600
+BOOTADDR=0x7c00
-diskman=0 ! Disk manager partitions, allows 16 partitions but
- ! don't overwrite this with a LILO BB.
+pbr=0 ! Make this a partition boot record for ldboot.
+direct=1 ! Direct boot from MBR to any sector.
-linear=1 ! Use the linear addresses not the CHS ones (if available)
+copyright=0 ! Add in the copyright message; if room.
+mbrkey=0 ! Option to choose the boot record based on keystroke (107)
+message=1 ! Display boot message (6+message space)
+
+markptab=1 ! Put an end marker just below the partition table.
+use512=0 ! Put the end marker at byte 510..512
+
+linear=1 ! Use the LBA BIOS addresses.
useCHS=1 ! Disable CHS if you need space.
+linCHS=1 ! Calculate CHS from linear mbr values. (41 bytes)
-partition_start=ORGADDR+0x1BE
-partition_size=0x10
-partition_end=ORGADDR+0x1FE
+preboot=0 ! Include the pre-boot loader. (40 bytes)
- if diskman
- ! Partition table start ...
- table_start=ORGADDR+0xFC
- low_partition=table_start+2
- else
- table_start=partition_start
- endif
+if linCHS
+ ! Allow immediate shifts etc.
+ use16 186
+endif
+ mbr_extras=ORGADDR+0x1B6
+ partition_start=ORGADDR+0x1BE
+ partition_size=0x10
+ partition_end=ORGADDR+0x1FE
+
+if pbr|direct
+ table_start=ORGADDR+0x1A2 ! Space for special table.
+else
+ table_start=mbr_extras
+endif
+export pbr
+export direct
export linear
-export diskman
export useCHS
+export linCHS
export mbrkey
+export end_of_code
+
+if preboot
export preboot
+endif
org ORGADDR
- cli ! Assume _nothing_!
- cld
- mov bx,#$7C00 ! Pointer to start of BB.
- xor ax,ax ! Segs all to zero
- mov ds,ax
- mov es,ax
- mov ss,ax
- mov sp,bx ! SP Just below BB
- mov cx,#$100 ! Move 256 words
- mov si,bx ! From default BB
- mov di,#ORGADDR ! To the correct address.
- rep
- movsw
- jmpi cont,#0 ! Set CS:IP correct.
+ if pbr
+ ! Skip a potential MSDOS BPB.
+boot_start:
+ j code
+ nop ! DOS appears to _require_ this to identify an MSDOS disk!!
+
+ .blkb boot_start+3-*
+ .ascii "LINUX" ! System ID
+ .byte 0,0,0
+ .blkb boot_start+0x5A-*
+code:
+ endif
+
+ cli ! Assume _nothing_! (needed for NT 4)
+ cld
+ mov bx,#BOOTADDR ! Pointer to start of BB.
+ xor ax,ax ! Segs all to zero
+ mov ss,ax
+ mov sp,bx ! SP Just below BB
+ if pbr
+ push [si+10] ! Save the inbound disk offset and drive
+ push [si+8] ! As if called pbr(drive, offset)
+ push dx
+ endif
+ mov ds,ax
+ mov es,ax
+ mov cx,#$100 ! Move 256 words
+ mov si,bx ! From default BB
+ mov di,#ORGADDR ! To the correct address.
+ rep
+ movsw
+ jmpi cont,#0 ! Set CS:IP correct.
cont:
- sti ! Let the interrupts back in.
+ sti ! Let the interrupts back in.
+ if pbr
+ pop [boot_drive]
+ pop [boot_part]
+ pop [boot_part+2]
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! Next check for a pre-boot message, load or keypress
- if message
- call disp_message
- endif
- if preboot
- call preboot_code
- endif
- if mbrkey
- call key_wait
- endif
-
- if (linear|useCHS)
+ if message
+ call disp_message
+ endif
+ if preboot
+ call preboot_code
+ endif
+ if mbrkey
+ call key_wait
+ endif
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+ if (linear|useCHS)
+
+ if pbr=0
! Now check the partition table, must use SI as pointer cause that's what the
! partition boot blocks expect.
-! If we're using diskman and we're short of space check the partitions in
-! physical order. (Order. 4,3,2,1,5,6,7,8,9,10,11,12,13,14,15,16)
-
- if (diskman&linear&useCHS)
-
- mov si,#partition_end
-check_next:
- sub si,#partition_size
- cmp byte [si],#$80 ! Flag for activated partition
- jz found_active
- cmp si,#low_partition
- jnz check_next
-
- else
-
! Normal active partition check, (Order: 1,2,3,4)
- mov si,#partition_start
+ mov si,#partition_start
check_active:
- cmp byte [si],#$80 ! Flag for activated partition
- jz found_active
+ cmp byte [si],#$80 ! Flag for activated partition
+ jz found_active
+ if direct=0
+try_next_part: ! Only if no direct.
+ endif
+ add si,#partition_size
+ cmp si,#partition_end
+ jnz check_active
+ endif
+
+ if pbr|direct
+ mov si,#table_start
+ cmp byte [si],#0
+ jnz found_active
try_next_part:
- add si,#partition_size
- cmp si,#partition_end
- jnz check_active
-
-! Check for Disk manager partitions in the order that Linux numbers them.
- if diskman&~(linear&useCHS)
- cmp word ptr diskman_magic,#$AA55
- jnz no_diskman
- mov si,#partition_start
-check_next:
- sub si,#partition_size
- cmp byte [si],#$80 ! Flag for activated partition
- jz found_active
- cmp si,#low_partition
- jnz check_next
-
-no_diskman:
- endif
- endif
-
- if mbrkey=0
-bad_boot:
- endif
- mov si,#no_bootpart ! Message & boot
- jmp no_boot
+ endif
+
+ jmp no_partition
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! Active partition found, boot it.
found_active:
- mov di,#6 ! Max retries, int doc says 3 ... double it
- movb [$7DFE],#0 ! Clear magic for dosemu
+ mov di,#6 ! Max retries, int doc says 3 ... double it
+ movb [$7DFE],#0 ! Clear magic for dosemu
retry:
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! If the BIOS has LBA extensions use them.
- if linear
- if useCHS
- mov ah,#$41
- mov bx,#$55AA
- mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
- push si ! Save SI on read.
- if mbrkey
- test dl,#$80
- jz do_CHS
- endif
- int $13
- jc do_CHS
- cmp bx,#$AA55
- jnz do_CHS
- else
- mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
- push si ! Save SI
- endif
- mov bx,#disk_address
- mov ax,[si+8]
- mov [bx],ax
- mov ax,[si+10]
- mov [bx+2],ax
- mov si,#disk_packet
- mov ah,#$42
- int $13
- pop si
- jc retry_error
- j sector_loaded
-disk_packet:
- .byte $10
- .byte 0
- .word 1
- .word $7C00
- .word 0
-disk_address:
- .long 0
- .long 0
-
- if useCHS
+! If we have no CHS don't check for LBA just use it.
+ if linear
+ mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
+
+ if useCHS
+ mov ah,#$41
+ mov bx,#$55AA
+ if mbrkey
+ test dl,#$80
+ jz do_CHS
+ endif
+ int $13
+ jc do_CHS ! Unknown call
+ cmp bx,#$AA55
+ jnz do_CHS ! Wrong call
+ test cl,#1
+ jz do_CHS ! EDD basic functions OK.
+ endif
+
+ push si ! Save SI on read.
+
+ if pbr|direct
+ mov ax,[si+8] ! 32bit disk address
+ mov cx,[si+10]
+ cmp si,#table_start
+ jnz normal_part
+ add ax,[boot_offset]
+ adc cx,[boot_offset+2]
+normal_part:
+ endif
+
+ xor bx,bx
+ push bx ! 64bit disk address
+ push bx
+ if pbr|direct
+ push cx ! 32bit disk address
+ push ax
+ else
+ push [si+10] ! 32bit disk address
+ push [si+8]
+ endif
+ push bx ! Load segment
+ push #BOOTADDR ! Load address
+ push #1 ! Number of sectors
+ push #16 ! Packet size
+ mov si,sp
+ mov ah,#$42
+ int $13
+ lea sp,[si+16]
+
+ pop si
+ jc retry_error
+ j sector_loaded
+
+ endif !linear
+
+ if useCHS
do_CHS:
- pop si
- endif
- endif
-
-if useCHS
- mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
- mov cx,[si+2] ! cx = Sector & head encoded for int $13
- ! bx is correct at $7C00
-
- mov ax,#$0201 ! Read 1 sector
- int $13 ! Disk read.
- jnc sector_loaded
-endif
+
+ if linCHS
+ call calc_chs
+ else
+ mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
+ mov cx,[si+2] ! cx = Sector & head encoded for int $13
+ endif
+
+ mov bx,#BOOTADDR ! Pointer to start of BB.
+ mov ax,#$0201 ! Read 1 sector
+ int $13 ! Disk read.
+ jnc sector_loaded
+ endif
! Error, reset and retry
retry_error:
- xor ax,ax
- int $13 ! Disk reset
+ xor ax,ax
+ int $13 ! Disk reset
- dec di
- jnz retry ! Try again
+ dec di
+ jnz retry ! Try again
- mov si,#disk_read_error
- jmp no_boot ! Sorry it ain't gonna work.
+ mov si,#disk_read_error
+ jmp no_boot ! Sorry it ain't gonna work.
sector_loaded:
- mov di,#$7DFE ! End of sector loaded
- cmp [di],#$AA55 ! Check for magic
- if diskman
- jnz bad_boot ! Can't try again, two places to return to.
- else
- jnz try_next_part ! No? Try next partition.
- endif
-
- mov bp,si ! LILO says some BBs use bp rather than si
- jmpi #$7C00,#0 ! Go!
+ mov di,#$7DFE ! End of sector loaded
+ cmp [di],#$AA55 ! Check for magic
+ jnz try_next_part ! No? Try next partition.
- else
- mov si,#no_bootpart ! Message & boot
- endif !(linear|useCHS)
+ mov bp,si ! LILO says some BBs use bp rather than si
+ jmpi #BOOTADDR,#0 ! Go!
-! Fatal errors ...........
- if mbrkey
-bad_boot:
- mov si,#no_bootpart
+no_partition:
+ mov si,#no_bootpart
no_boot: ! SI now has pointer to error message
- call puts
- mov si,#crlf
- call puts
- j key_pause
+ call puts
- else
+ endif !(linear|useCHS)
-no_boot: ! SI now has pointer to error message
- lodsb
- cmp al,#0
- jz EOS
- mov bx,#7
- mov ah,#$E ! Can't use $13 cause that's AT+ only!
- int $10
- jmp no_boot
-EOS:
- cmp si,#press_end ! After msg output 'press key' message
- jz keyboot
- mov si,#press_key
- jmp no_boot
+! Fatal errors ...........
+ if mbrkey
+ mov si,#crlf
+ call puts
+ j key_pause
+ else
+
+ mov si,#press_key
+ call puts
keyboot: ! Wait for a key then reboot
- xor ax,ax
- int $16
- jmpi $0,$FFFF ! Reboot.
+ xor ax,ax
+ int $16
+ jmpi $0,$FFFF ! Reboot.
+ endif
+
+ if useCHS
+ if linCHS
+
+calc_chs: ! From lilo.
+ mov ah,#8
+ int $13 ! Drive Geom
+ shr dx,#8
+ xchg ax,dx
+ inc ax ! AX = No. Heads
+ dec cx ! Davide BIOS bug: CX=0 => Sectors=64
+ and cx,#$3f ! CX = Sectors
+ inc cx
+
+ mul cx
+ xchg ax,bx ! BX = Cylinder size
+
+ mov ax,[si+8] ! Linear partition address.
+ mov dx,[si+10]
+
+ if pbr|direct
+ cmp si,#table_start
+ jnz std_part
+ add ax,[boot_offset]
+ adc dx,[boot_offset+2]
+std_part:
+ endif
+
+ div bx ! AX = Cyl, DX = head & sect
+
+ shl ah,#6
+ xchg ah,al
+ xchg dx,ax
+ div cl ! AH = sect-1, AL = Head
+ or dl,ah ! merge for CX arg.
+ mov cx,dx
+ inc cx ! Adjust sector No.
+
+ mov dx,[si] ! dh = Orig Drive head, dl = $80 ie HD drive 0
+
+ mov dh,al ! Head No.
+ ; CX & DX ready for int $13
+ ret
+
+ endif
+ endif
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+ if message
+disp_message:
+ mov si,#Banner
+ endif
+
+! Display message uses SI,AX,BX
+puts: ! This is smaller than using $13
+ lodsb
+ cmp al,#0
+ jz .EOS
+ mov bx,#7
+ mov ah,#$E
+ int $10
+ jmp puts
+.EOS:
+ ret
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+
+ if mbrkey=0
press_key:
- .asciz "\r\nPress return:"
-press_end:
- endif
+ .asciz "\r\nPress return:"
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+ if (linear|useCHS)
+ if mbrkey
+disk_read_error:
no_bootpart:
- .asciz "Bad partition"
+ .asciz "Boot error"
+ else
disk_read_error:
- .asciz "Read error"
+ .asciz "Disk read error"
+no_bootpart:
+ .asciz "No bootable partition"
+ endif
+ endif !(linear|useCHS)
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! Choose the partition based on a pressed key ...
- if mbrkey
+ if mbrkey
key_wait:
- mov si,#Prompt
- call puts
- call wait_key
- jnz key_pause
+ mov si,#Prompt
+ call puts
+ call wait_key
+ jnz key_pause
- mov si,#Unprompt ! Nothing has happened, return.
- call puts
- ret
+ mov si,#Unprompt ! Nothing has happened, return.
+ call puts
+ ret
key_pause:
- mov si,#Pause
- call puts
+ mov si,#Pause
+ call puts
key_tick:
- call wait_key
- jz key_tick
- j Got_key
+ call wait_key
+ jz key_tick
+ j Got_key
wait_key:
- mov di,#19 ! Wait for 18-19 ticks
+ mov di,#19 ! Wait for 18-19 ticks
next_loop:
- mov ah,#1
- int $16
- jnz done_wait
- mov ah,#0
- int $1A ! Get current tick
- cmp dx,si ! If changed DEC our counter.
- jz next_loop
- mov si,dx
- dec di
- jnz next_loop
+ mov ah,#1
+ int $16
+ jnz done_wait
+ mov ah,#0
+ int $1A ! Get current tick
+ cmp dx,si ! If changed DEC our counter.
+ jz next_loop
+ mov si,dx
+ dec di
+ jnz next_loop
done_wait:
- ret
+ ret
Got_key:
- mov ah,#0 ! Clean the kbd buffer.
- int $16
- cmp al,#0x20
- jz key_tick
-
- push ax
- mov Showkey,al
- mov si,#Showkey
- call puts
- pop ax
-
- ! ... Now we use our key ...
- ! 0 => Floppy
- ! 1 .. 4 => Hard disk partition.
-
- if useCHS
- cmp al,#'F
- jz is_floppy
- cmp al,#'f
- jz is_floppy
- endif
-
- cmp al,#'1
- jb key_pause
- cmp al,#'4
- ja key_pause
-
- and ax,#0x7
- dec ax
- mov cl,#4
- shl ax,cl
- add ax,#partition_start
- mov si,ax
+ mov ah,#0 ! Clean the kbd buffer.
+ int $16
+ cmp al,#0x20
+ jz key_tick
+
+ push ax
+ mov Showkey,al
+ mov si,#Showkey
+ call puts
+ pop ax
+
+ ! ... Now we use our key ...
+ ! 0 => Floppy
+ ! 1 .. 4 => Hard disk partition.
+
+ if useCHS
+ cmp al,#'F
+ jz is_floppy
+ cmp al,#'f
+ jz is_floppy
+ endif
+
+ cmp al,#'1
+ jb key_pause
+ cmp al,#'4
+ ja key_pause
+
+ and ax,#0x7
+ dec ax
+ mov cl,#4
+ shl ax,cl
+ add ax,#partition_start
+ mov si,ax
! Set active flag for disk interrupt.
- or byte [si],#$80
- br found_active
+ or byte [si],#$80
+ br found_active
- if useCHS
+ if useCHS
is_floppy:
- mov si,#floppy_part
- br found_active
- endif
-
- if message
-disp_message:
- mov si,#Banner
- endif
-
-puts:
- lodsb
- cmp al,#0
- jz EOS
- push bx
- mov bx,#7
- mov ah,#$E ! Can't use $13 cause that's AT+ only!
- int $10
- pop bx
- jmp puts
-EOS:
- ret
+ mov si,#floppy_part
+ br found_active
+ endif
Prompt:
- .asciz "\rMBR: "
+ .asciz "\rMBR: "
Unprompt:
- .asciz "\r \r"
+ .asciz "\r \r"
Pause:
- if useCHS
- .asciz "\rMBR F1234> "
- else
- .asciz "\rMBR 1234> "
- endif
+ if useCHS
+ .asciz "\rMBR F1234> "
+ else
+ .asciz "\rMBR 1234> "
+ endif
Showkey:
- .ascii " "
+ .ascii " "
crlf:
- .asciz "\r\n"
+ .asciz "\r\n"
floppy_part:
- .word 0,1
+ .word 0,1
- endif
+ endif
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! This is the pre-boot loader it uses CHS but that's ok for track 0
!
- if preboot
+ if preboot
public preboot_code
preboot_code:
- push bx
- mov si,#pre_boot_table
- lodsw
- mov di,ax ! First word is execute address
+ mov si,#pre_boot_table
+ lodsw
+ mov di,ax ! First word is execute address
more_boot:
- lodsw
- test ah,ah
- jz load_done
- mov bx,ax ! word 1 address
- lodsw
- mov cx,ax ! word 2 CX, cylinder/sector
- lodsw
- mov dx,ax ! word 3 DX, drive, head
- lodsw ! word 4 AX, $02, sector count
- int $13
- jnc more_boot ! This doesn't retry, with a HD it shouldn't be bad.
-
- mov si,#disk_read_error
- br no_boot ! Sorry it ain't gonna work.
+ lodsw
+ test ah,ah
+ jz load_done
+ mov bx,ax ! word 1 address
+ lodsw
+ mov cx,ax ! word 2 CX, cylinder/sector
+ lodsw
+ mov dx,ax ! word 3 DX, drive, head
+ lodsw ! word 4 AX, $02, sector count
+ int $13
+ jnc more_boot ! This doesn't retry, with a HD it shouldn't be bad.
+
+ mov si,#disk_read_error
+ br no_boot ! Sorry it ain't gonna work.
load_done:
- call di
+ call di
exec_done:
- pop bx
-
return:
- ret
+ ret
export pre_boot_table
pre_boot_table:
- ! Example: Do nothing.
- .word return,0
-
- ! Labels
- ! .word <execute address>
- ! Then repeat ..
- ! .word <BX>, <CX>, <DX>, <AX>
- ! Or.
- ! .word <Load Address>
- ! .byte <sector> + (<cyl> & $300)>>2), <cyl> & $FF, <Drive>, <Head>, <cnt>, 2
- ! Finally
- ! .word 0
-
- ! Example: Load rest of H0,C0 into mem at $7C00 (8k).
- ! .word $7C00
- ! .word $7C00,$0002,$8000,$0210
- ! .word $0000
- endif
+ ! Example: Do nothing.
+ .word return,0
+
+ ! If the message is in use, preallocate some extents
+ if message
+ .blkb 64
+ endif
+
+ ! Labels
+ ! .word <execute address>
+ ! Then repeat ..
+ ! .word <BX>, <CX>, <DX>, <AX>
+ ! Or.
+ ! .word <Load Address>
+ ! .byte <sector> + (<cyl> & $300)>>2), <cyl> & $FF
+ ! .byte <Drive>, <Head>, <cnt>, 2
+ ! Finally
+ ! .word 0
+
+ ! Example: Load rest of H0,C0 into mem at BOOTADDR
+ ! .word BOOTADDR
+ ! .word BOOTADDR,$0002,$8000,$0210
+ ! .word $0000
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+end_of_code:
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
!
- if message&~mbrkey
-disp_message:
- mov si,#Banner
-
-puts:
- lodsb
- cmp al,#0
- jz .EOS
- push bx
- mov bx,#7
- mov ah,#$E ! Can't use $13 cause that's AT+ only!
- int $10
- pop bx
- jmp puts
-.EOS:
- ret
- endif
- if message
+ if message
export Banner
Banner:
- .blkb 16 ! 16 bytes for the message at least.
- endif
-
-!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-! Now make sure this isn't too big!
-end_of_code:
- if *>table_start
- fail! Partition table overlaps
+ if (linear|useCHS)
+ if *<ORGADDR+0x100
+ org ORGADDR+0x100
+ endif
+ .blkb 80 ! At least 80 bytes for the message.
+ else
+ .asciz "This disk is not bootable."
+ endif
endif
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-! The diskman magic number and empty DM partitions.
- if diskman
- org table_start
-public diskman_magic
-diskman_magic:
- .word 0xAA55
- .blkb 12*partition_size-1
- endif
+! Now make sure this isn't too big! Don't overlap disk serial numbers.
+ if *>table_start
+ fail! Partition table overlaps
+ endif
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! And a copyright message if there's room.
- if copyright
- if *<ORGADDR+0x180
- org ORGADDR+0x180
-.asciz "ELKS MBR "
-.asciz "Robert de Bath,"
-.asciz "Copyright "
-.asciz "1996-2003. "
- org partition_start-1
- .byte 0xFF
- endif
- endif
+ if copyright
+ if *<ORGADDR+0x170
+ org ORGADDR+0x170
+ .asciz "ELKS MBR "
+ .asciz "Robert de Bath,"
+ .asciz "Copyright GPL2 "
+ .asciz "1996-2008."
+ endif
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+ if pbr|direct
+ if message
+ org table_start-1
+ .byte 0xFF
+ else
+ org table_start
+ endif
+boot_drive:
+ .word 0
+ .blkb 6
+boot_part:
+ .long 0
+ .long 0
+boot_offset:
+ .long 0x7FFFFFFF
+
+ if pbr=0
+export boot_offset
+export boot_drive
+export boot_part
+ endif
+ endif
+
+ org mbr_extras ! Dirty bit, Serial number
+ .word 0
+serial_no:
+ .blkb 4
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
! Clear the sector to the bottom of the partition table.
- if markptab
- if *<partition_start-1
- org partition_start-1
- .byte 0xFF
- endif
- endif
-
- if use512
- org ORGADDR+0x1FE
- .word 0xAA55
- endif
-
- if 1&~(useCHS|linear|preboot)
- fail! Errm, you can't boot anything without 'linear' or 'useCHS'
- endif
+ if markptab
+ if *<partition_start
+ org partition_start-1
+ .byte 0
+ endif
+ endif
+
+ if use512
+ org ORGADDR+0x1FE
+ .word 0xAA55
+ endif
+
+! Sanity check.
+
+ if pbr|direct
+ if useCHS
+ if linCHS=0
+ fail !Raw CHS doesn't work with pbr or direct.
+ endif
+ endif
+ endif
!THE END
diff --git a/bootblocks/mbr_dm.s b/bootblocks/mbr_dm.s
new file mode 100644
index 0000000..9ec16f5
--- /dev/null
+++ b/bootblocks/mbr_dm.s
@@ -0,0 +1,313 @@
+!
+! This is a 'Master Boot Record' following the MSDOS 'standards'.
+! This BB successfully boots MSDOS, Windows or Linux in CHS or Linear.
+!
+! NB: This needs as86 0.16.0 or later
+
+! Lowest available is $0500, MSDOS appears to use $0600 ... I wonder why?
+ORGADDR=$0500
+use512=0 ! Put the end marker at byte 510..512
+markptab=1 ! Put an end marker just below the partition table.
+
+diskman=1 ! Disk manager partitions, allows 16 partitions but
+ ! don't overwrite this with a LILO BB.
+revorder=0 ! Use physical order for choosing diskman boot partition
+
+linear=0 ! Use the linear addresses not the CHS ones (if available)
+useCHS=1 ! Disable CHS if you need space.
+linCHS=0 ! Calculate CHS from linear mbr values.
+
+ if 1&~(useCHS|linear)
+ fail! Errm, you can't boot anything without 'linear' or 'useCHS'
+ endif
+
+partition_start=ORGADDR+0x1BE
+partition_size=0x10
+partition_end=ORGADDR+0x1FE
+
+ if diskman
+ ! Partition table start ...
+ table_start=ORGADDR+0xFC
+ low_partition=table_start+2
+ else
+ table_start=partition_start
+ endif
+
+export linear
+export diskman
+export useCHS
+export linCHS
+
+org ORGADDR
+ cli ! Assume _nothing_!
+ cld
+ mov bx,#$7C00 ! Pointer to start of BB.
+ xor ax,ax ! Segs all to zero
+ mov ds,ax
+ mov es,ax
+ mov ss,ax
+ mov sp,bx ! SP Just below BB
+ mov cx,#$100 ! Move 256 words
+ mov si,bx ! From default BB
+ mov di,#ORGADDR ! To the correct address.
+ rep
+ movsw
+ jmpi cont,#0 ! Set CS:IP correct.
+cont:
+ sti ! Let the interrupts back in.
+
+ if (linear|useCHS)
+
+! Now check the partition table, must use SI as pointer cause that's what the
+! partition boot blocks expect.
+
+! If we're using diskman and we're short of space check the partitions in
+! physical order. (Order. 4,3,2,1,5,6,7,8,9,10,11,12,13,14,15,16)
+
+ if (diskman&revorder)
+
+ mov si,#partition_end
+check_next:
+ sub si,#partition_size
+ cmp byte [si],#$80 ! Flag for activated partition
+ jz found_active
+ cmp si,#low_partition
+ jnz check_next
+
+ else
+
+! Normal active partition check, (Order: 1,2,3,4)
+ mov si,#partition_start
+check_active:
+ cmp byte [si],#$80 ! Flag for activated partition
+ jz found_active
+try_next_part:
+ add si,#partition_size
+ cmp si,#partition_end
+ jnz check_active
+
+! Check for Disk manager partitions in the order that Linux numbers them.
+ if diskman&~(revorder)
+ cmp word ptr diskman_magic,#$AA55
+ jnz no_diskman
+ mov si,#partition_start
+check_next:
+ sub si,#partition_size
+ cmp byte [si],#$80 ! Flag for activated partition
+ jz found_active
+ cmp si,#low_partition
+ jnz check_next
+
+no_diskman:
+ endif
+ endif
+
+bad_boot:
+ mov si,#no_bootpart ! Message & boot
+ jmp no_boot
+
+! Active partition found, boot it.
+found_active:
+ mov di,#6 ! Max retries, int doc says 3 ... double it
+ movb [$7DFE],#0 ! Clear magic for dosemu
+retry:
+
+! If the BIOS has LBA extensions use them.
+ if linear
+ if useCHS
+ mov ah,#$41
+ mov bx,#$55AA
+ mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
+ push si ! Save SI on read.
+ int $13
+ jc do_CHS
+ cmp bx,#$AA55
+ jnz do_CHS
+ else
+ mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
+ push si ! Save SI
+ endif
+ mov bx,#disk_address
+ mov ax,[si+8]
+ mov [bx],ax
+ mov ax,[si+10]
+ mov [bx+2],ax
+ mov si,#disk_packet
+ mov ah,#$42
+ int $13
+ pop si
+ jc retry_error
+ j sector_loaded
+disk_packet:
+ .byte $10
+ .byte 0
+ .word 1
+ .word $7C00
+ .word 0
+disk_address:
+ .long 0
+ .long 0
+
+ if useCHS
+do_CHS:
+ pop si
+ endif
+ endif
+
+if useCHS
+if linCHS
+ call calc_chs
+else
+ mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0
+ mov cx,[si+2] ! cx = Sector & head encoded for int $13
+ ! bx is correct at $7C00
+endif
+
+ mov ax,#$0201 ! Read 1 sector
+ int $13 ! Disk read.
+ jnc sector_loaded
+endif
+
+! Error, reset and retry
+retry_error:
+ xor ax,ax
+ int $13 ! Disk reset
+
+ dec di
+ jnz retry ! Try again
+
+ mov si,#disk_read_error
+ jmp no_boot ! Sorry it ain't gonna work.
+
+sector_loaded:
+ mov di,#$7DFE ! End of sector loaded
+ cmp [di],#$AA55 ! Check for magic
+ if diskman
+ jnz bad_boot ! Can't try again, two places to return to.
+ else
+ jnz try_next_part ! No? Try next partition.
+ endif
+
+ mov bp,si ! LILO says some BBs use bp rather than si
+ jmpi #$7C00,#0 ! Go!
+
+ else
+ mov si,#no_bootpart ! Message & boot
+ endif !(linear|useCHS)
+
+! Fatal errors ...........
+
+no_boot: ! SI now has pointer to error message
+ call puts
+ mov si,#press_key
+ call puts
+
+keyboot: ! Wait for a key then reboot
+ xor ax,ax
+ int $16
+ jmpi $0,$FFFF ! Reboot.
+
+if useCHS
+if linCHS
+calc_chs:
+ push bx ! Save load location
+
+ mov ah,#8
+ int $13 ! Drive Geom
+ shr dx,#8
+ xchg ax,dx
+ inc ax ! AX = No. Heads
+ and cx,#$3f ! CX = Sectors
+ mul cx
+ xchg ax,bx ! BX = .
+
+ mov ax,[si+8] ! Linear partition address.
+ mov dx,[si+10]
+
+ div bx ! AX = Cyl, DX = head & sect
+
+ shl ah,#6
+ xchg ah,al
+ xchg dx,ax
+ div cl ! AH = sect-1, AL = Head
+ or dl,ah ! merge for CX arg.
+ mov cx,dx
+ inc cx ! Adjust sector No.
+
+ mov dx,[si] ! dh = Orig Drive head, dl = $80 ie HD drive 0
+
+ mov dh,al ! Head No.
+
+ ; CX & DX ready for int $13
+
+ pop bx
+ ret
+endif
+endif
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+puts:
+ lodsb
+ cmp al,#0
+ jz .EOS
+ push bx
+ mov bx,#7
+ mov ah,#$E ! Can't use $13 cause that's AT+ only!
+ int $10
+ pop bx
+ jmp puts
+.EOS:
+ ret
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+
+press_key:
+ .asciz "\r\nPress return:"
+press_end:
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+
+ if (linear|useCHS)
+disk_read_error:
+ .asciz "Read error"
+no_bootpart:
+ .asciz "Bad partition"
+ else
+no_bootpart:
+ .asciz "Not a bootable disk"
+ endif !(linear|useCHS)
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+! Now make sure this isn't too big!
+end_of_code:
+ if *>table_start
+ fail! Partition table overlaps
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+! The diskman magic number and empty DM partitions.
+ if diskman
+ org table_start
+public diskman_magic
+diskman_magic:
+ .word 0xAA55
+ .blkb 12*partition_size-1
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+! Clear the sector to the bottom of the partition table.
+ if markptab
+ if *<partition_start-2
+ org partition_start-2
+ .word 0xAA55
+ endif
+ endif
+
+ if use512
+ org ORGADDR+0x1FE
+ .word 0xAA55
+ endif
+
+!THE END
diff --git a/bootblocks/minix.c b/bootblocks/minix.c
index 69daa1a..6532650 100644
--- a/bootblocks/minix.c
+++ b/bootblocks/minix.c
@@ -53,7 +53,7 @@ BOOTADDR = 0x7c00
org ORGADDR ! The lowest available address.
start:
#ifndef MIN_SPACE
- include sysboot.s
+ include sysboot16.s
org start ! The lowest available address, again.
j skip_vars
diff --git a/bootblocks/msdos.s b/bootblocks/msdos.s
index 971975e..ddaa870 100644
--- a/bootblocks/msdos.s
+++ b/bootblocks/msdos.s
@@ -54,7 +54,7 @@ mend
org ORGADDR
start:
-include sysboot.s
+include sysboot16.s
org dos_sysid
.ascii "DOSFS" ! System ID
diff --git a/bootblocks/nombr.s b/bootblocks/nombr.s
new file mode 100644
index 0000000..b73947f
--- /dev/null
+++ b/bootblocks/nombr.s
@@ -0,0 +1,23 @@
+
+include sysmbr.s
+
+org codestart
+ mov si,#message
+nextc:
+ lodsb
+ cmp al,#0
+ jz eos
+ mov bx,#7
+ mov ah,#$E ! Can't use $13 cause that's AT+ only!
+ int $10
+ jmp nextc
+eos: ! Wait for a key then reboot
+ xor ax,ax
+ int $16
+ jmpi $0,$FFFF ! Wam! Try or die!
+
+export message
+message:
+ .asciz "MBR loaded but not bootable.\r\n"
+
+include sysmbrtail.s
diff --git a/bootblocks/sysboot.s b/bootblocks/sysboot.s
index baac806..b6adc75 100644
--- a/bootblocks/sysboot.s
+++ b/bootblocks/sysboot.s
@@ -48,7 +48,8 @@ dos4_fattype: .blkb 8 ! FAT type
!
! This is where the code will be overlaid, the default is a hang
-.blkb sysboot_start+0x3E-*
+! The 0x5A offset clears the FAT32 header.
+.blkb sysboot_start+0x5A-*
public codestart
codestart:
j codestart
diff --git a/bootblocks/sysboot16.s b/bootblocks/sysboot16.s
new file mode 100644
index 0000000..baac806
--- /dev/null
+++ b/bootblocks/sysboot16.s
@@ -0,0 +1,82 @@
+
+! The master boot sector will have setup a stack,
+! this is normally at 0:7c00 down.
+! DS, SS, CS and ES will all have value 0 so the execution address is 0:7c00
+! On entry the register SI will be pointer to the partition entry that
+! this sector was loaded from, DL is the drive.
+
+! Also if it's a standard Master boot DH will be the head, CX will be the
+! sector and cylinder, BX=7C00, AX=1, DI=7DFE, BP=SI. There's a reasonable
+! chance that this isn't true though.
+
+! The Master boot itself will have been loaded and run at $07c00
+! The BIOS must have setup a stack because interrupts are enabled
+! Little else can be assumed because DOS doesn`t assume anything either
+
+sysboot_start:
+j codestart
+nop ! DOS appears to _require_ this to identify an MSDOS disk!!
+
+.blkb sysboot_start+3-*
+public dosfs_stat
+dos_sysid: .ascii "LINUX" ! System ID
+ .byte 0,0,0
+dosfs_stat:
+dos_sect: .blkw 1 ! Sector size
+dos_clust: .blkb 1 ! Cluster size
+dos_resv: .blkw 1 ! Res-sector
+dos_nfat: .blkb 1 ! FAT count
+dos_nroot: .blkw 1 ! Root dir entries
+dos_maxsect: .blkw 1 ! Sector count (=0 if large FS)
+dos_media: .blkb 1 ! Media code
+dos_fatlen: .blkw 1 ! FAT length
+dos_spt: .blkw 1 ! Sect/Track
+dos_heads: .blkw 1 ! Heads
+dos_hidden: .blkw 2 ! Hidden sectors
+
+! Here down is DOS 4+ and probably not needed for floppy boots.
+
+dos4_maxsect: .blkw 2 ! Large FS sector count
+dos4_phy_drive: .blkb 1 ! Phys drive
+.blkb 1 ! Reserved
+.blkb 1 ! DOS 4
+
+floppy_temp:
+dos4_serial: .blkw 2 ! Serial number
+dos4_label: .blkb 11 ! Disk Label (DOS 4+)
+dos4_fattype: .blkb 8 ! FAT type
+
+!
+! This is where the code will be overlaid, the default is a hang
+.blkb sysboot_start+0x3E-*
+public codestart
+codestart:
+ j codestart
+
+! Partition table
+public bootblock_magic
+
+.blkb sysboot_start+0x1BE-*
+partition_1:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+.blkb sysboot_start+0x1CE-*
+partition_2:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+.blkb sysboot_start+0x1DE-*
+partition_3:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+.blkb sysboot_start+0x1EE-*
+partition_4:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+
+.blkb sysboot_start+0x1FE-*
+bootblock_magic:
+.word 0xAA55
diff --git a/bootblocks/sysmbr.s b/bootblocks/sysmbr.s
new file mode 100644
index 0000000..eb609de
--- /dev/null
+++ b/bootblocks/sysmbr.s
@@ -0,0 +1,76 @@
+
+! The master boot sector will have setup a stack,
+! this is normally at 0:7c00 down.
+! DS, SS, CS and ES will all have value 0 so the execution address is 0:7c00
+! On entry the register SI will be pointer to the partition entry that
+! this sector was loaded from, DL is the drive.
+
+! Also if it's a standard Master boot DH will be the head, CX will be the
+! sector and cylinder, BX=7C00, AX=1, DI=7DFE, BP=SI. There's a reasonable
+! chance that this isn't true though.
+
+! The Master boot itself will have been loaded and run at $07c00
+! The BIOS must have setup a stack because interrupts are enabled
+! Little else can be assumed because DOS doesn`t assume anything either
+
+! Lowest available is $0500, MSDOS appears to use $0600 ... I wonder why?
+ORGADDR=$0500
+
+org ORGADDR
+
+sysboot_start:
+ cli ! Assume _nothing_!
+ cld
+ mov bx,#$7C00 ! Pointer to start of BB.
+ xor ax,ax ! Segs all to zero
+ mov ds,ax
+ mov es,ax
+ mov ss,ax
+ mov sp,bx ! SP Just below BB
+ mov cx,#$100 ! Move 256 words
+ mov si,bx ! From default BB
+ mov di,#ORGADDR ! To the correct address.
+ rep
+ movsw
+ jmpi cont,#0 ! Set CS:IP correct.
+cont:
+ sti ! Let the interrupts back in.
+
+! This is where the code will be overlaid, the default is a hang
+public codestart
+codestart:
+ j codestart
+
+! Partition table
+public bootblock_magic
+
+.blkb sysboot_start+0x1B6-*
+table_start:
+.blkb 2 ! Dirty bits
+.blkb 4 ! Volume Serial Number
+.blkb 2 ! Possible Magic number
+
+.blkb sysboot_start+0x1BE-*
+partition_1:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+.blkb sysboot_start+0x1CE-*
+partition_2:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+.blkb sysboot_start+0x1DE-*
+partition_3:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+.blkb sysboot_start+0x1EE-*
+partition_4:
+.blkb 8 ! IN,SH,SS,ST,OS,EH,ES,ET
+.blkw 2 ! Linear position (0 based)
+.blkw 2 ! Linear length
+
+.blkb sysboot_start+0x1FE-*
+bootblock_magic:
+.blkb 2
diff --git a/bootblocks/sysmbrtail.s b/bootblocks/sysmbrtail.s
new file mode 100644
index 0000000..1b37022
--- /dev/null
+++ b/bootblocks/sysmbrtail.s
@@ -0,0 +1,13 @@
+
+! Now make sure this isn't too big!
+end_of_code:
+ if *>table_start
+ fail! Partition table overlaps
+ endif
+
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+! Clear the sector to the bottom of the partition table.
+ if *<table_start-1
+ org table_start-1
+ .byte 0xFF
+ endif
diff --git a/elksemu/elks.c b/elksemu/elks.c
index 3dd3a4d..08858fe 100644
--- a/elksemu/elks.c
+++ b/elksemu/elks.c
@@ -162,6 +162,9 @@ void run_elks()
case VM86_STI:
fprintf(stderr, "VM86_STI returned\n");
break; /* Shouldnt be seen */
+ default:
+ fprintf(stderr, "Unknown return value from vm86\n");
+ exit(1);
}
}
diff --git a/ifdef.c b/ifdef.c
index 5f67acf..702f827 100644
--- a/ifdef.c
+++ b/ifdef.c
@@ -443,10 +443,6 @@ manifest_constant()
#ifdef __i386__
save_name("__elksemu_works__", 'D');
#endif
-/* Is this true ? */
-#ifdef __x86_64__
- save_name("__elksemu_works__", 'D');
-#endif
#endif
#ifdef __unix__
save_name("__unix__", 'D');
diff --git a/libc/gtermcap/Makefile.old b/libc/gtermcap/Makefile.old
deleted file mode 100644
index 453c47a..0000000
--- a/libc/gtermcap/Makefile.old
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Makefile for termcap functions
-#
-
-override DEBUG=false
-override PROFILE=false
-#override CHECKER=false
-JUMP_LIB=libtermcap
-
-TOPDIR=..
-
-include $(TOPDIR)/Makeconfig
-include $(TOPDIR)/Makerules
-
-override STATIC_LIB=$(STATIC_DIR)/libtermcap.a
-override SHARED_LIB=$(SHARED_DIR)/libtermcap.a
-override CHECKER_LIB=$(CHECKER_DIR)/libtermcap.a
-
-DIRS:=
-SRCS = termcap.c tparam.c
-ASMS= $(SRCS:.c=.s)
-OBJS= $(SRCS:.c=.o)
-ALIASES=
-
-include $(TOPDIR)/Maketargets
diff --git a/libc/i386sys/Makefile b/libc/i386sys/Makefile
index 665f71a..9de3232 100644
--- a/libc/i386sys/Makefile
+++ b/libc/i386sys/Makefile
@@ -12,7 +12,7 @@ DSRC=dirent.c
DOBJ=opendir.o closedir.o readdir.o
ifeq ($(LIB_CPU)-$(LIB_OS),i386-ELKS)
-OBJ=$(LOBJ3) $(LOBJ) $(EOBJ) $(DOBJ) setjmp3.o
+OBJ=$(LOBJ) $(EOBJ) $(DOBJ) setjmp3.o
SYSCALLS=syscalls
CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
diff --git a/libc/msdos/msdos.c b/libc/msdos/msdos.c
index ae10b39..f9bfb9b 100644
--- a/libc/msdos/msdos.c
+++ b/libc/msdos/msdos.c
@@ -401,18 +401,23 @@ static int xlate_mode[] = {
if( (cmode & 0222) == 0 ) creat_mode = 1;
- /* BzzzT. Assume these flags both mean the merge of them */
- /* BzzzT. Also ignore O_EXCL */
- if( type & (O_TRUNC|O_CREAT) )
- rv = __dos_creat(nname, creat_mode);
+ /* BzzzT. Ignore O_EXCL */
+ if( type & O_TRUNC ) /* Assume TRUNC always means CREAT too */
+ rv = __dos_creat(nname, creat_mode);
else
{
+ int sv = errno;
/* If we would open in compatibility mode make it a little more unixy */
if( type & O_DENYMODE )
rv = __dos_open(nname, type&(O_ACCMODE|O_DENYMODE|O_SETFD));
else
rv = __dos_open(nname, xlate_mode[type&O_ACCMODE]);
+
+ if (rv == -1 && errno == ENOENT && (type & O_CREAT)) {
+ errno = sv;
+ rv = __dos_creat(nname, creat_mode);
+ }
}
return rv;
}
diff --git a/libc/syscall/syscall.dev86.old b/libc/syscall/syscall.dev86.old
deleted file mode 100644
index 29e7b5e..0000000
--- a/libc/syscall/syscall.dev86.old
+++ /dev/null
@@ -1,160 +0,0 @@
-#
-# WARNING!
-# This file is used to generate the system call lists for Dev86(elks)
-# ELKSemu and elks itself. Changes to this may require changes in
-# all three of those packages.
-#
-# . = Ok, with comment
-# * = Needs libc code (Prefix __)
-# - = Obsolete/not required
-# @ = May be required later
-#
-# An initial plus on the call number specifies that this call is
-# implemented in the kernel.
-#
-# Package versions are matched.
-# Dev86/Elksemu version - 0.13.1
-# Elks version - 0.0.66
-#
-# Name No Args Flag, comment
-#
-exit +1 1 * c exit does stdio, _exit in crt0
-fork +2 0
-read +3 3
-write +4 3
-open +5 3
-close +6 1
-wait4 +7 4
-creat 8 0 - Not needed alias for open
-link +9 2
-unlink +10 1
-execve +11 3 * execve minix style
-chdir +12 1
-time 13 1 - Use settimeofday
-mknod +14 3
-chmod +15 2
-chown +16 3
-brk +17 1 * This is only to tell the system
-stat +18 2
-lseek +19 3 * nb 2nd arg is an io ptr to long not a long.
-getpid +20 1 * this gets both pid & ppid
-mount +21 5
-umount +22 1
-setuid +23 1
-getuid +24 1 * this gets both uid and euid
-stime 25 2 - this must not exist - even as a libc.
-ptrace 26 4 @ adb/sdb/dbx need this.
-alarm 27 2
-fstat +28 2
-pause 29 0
-utime 30 2
-chroot +31 1
-vfork 32 0
-access +33 2
-nice 34 1
-sleep 35 1
-sync +36 0
-kill 37 2
-rename +38 2
-mkdir +39 2
-rmdir +40 1
-dup +41 1 . There is a fcntl lib function too.
-pipe 42 1
-times 43 2 * 2nd arg is pointer for long ret val.
-profil 44 4 @
-dup2 +45 2
-setgid +46 1
-getgid 47 1 * this gets both gid and egid
-signal 48 2 * have put the despatch table in user space.
-getinfo 49 1 @ possible? gets pid,ppid,uid,euid etc
-fcntl +50 3
-acct 51 1 @ Accounting to named file (off if null)
-phys 52 3 - Replaced my mmap()
-lock 53 1 @ Prevent swapping for this proc if flg!=0
-ioctl +54 3 . make this and fcntl the same ?
-reboot +55 3 . the magic number is 0xfee1,0xdead,...
-mpx 56 2 - Replaced by fifos and select.
-lstat +57 2
-symlink +58 2
-readlink +59 3
-umask +60 1
-settimeofday 61 2
-gettimeofday 62 2
-select 63 5 *
-readdir +64 3 *
-
-#
-# Name No Args Flag&comment
-#
-# ( awk '{$2=NR+500;OFS="\t";print ;}'| expand -24,32,40 | unexpand ) <<!
-#
-ADJTIMEX 501 X @
-FCHDIR 502 1 @
-FCHMOD 503 2 @
-FCHOWN 504 3 @
-FDATASYNC 505 X @
-FLOCK 506 2 - Use fcntl
-FSTATFS 507 2 @
-FSYNC 508 1 @
-FTIME 509 1 - Use gettimeofday
-FTRUNCATE 510 3 @
-GETDENTS 511 X @
-GETGROUPS 512 2 @
-GETITIMER 513 2 @
-GETPGID 514 1 @
-GETPGRP 515 0 - Use getpgid(0)
-GETPRIORITY 516 2 @
-GETRLIMIT 517 2 @
-GETRUSAGE 518 2 @
-GETSID 519 X @
-IPC 520 5 @ This is for all SYSV IPC (c/f mpx)
-LLSEEK 521 3 @ 2nd arg is ptr to two longs
-MPROTECT 522 X @
-MSYNC 523 X @
-MUNLOCK 524 X @
-MUNLOCKALL 525 X @
-MUNMAP 526 X @
-PERSONALITY 527 X @
-QUOTACTL 528 X @
-READV 529 3 @
-SCHED_GETPARAM 530 X @
-SCHED_GETSCHEDULER 531 X @
-SCHED_GET_PRIORITY_MAX 532 X @
-SCHED_GET_PRIORITY_MIN 533 X @
-SCHED_RR_GET_INTERVAL 534 X @
-SCHED_SETPARAM 535 X @
-SCHED_SETSCHEDULER 536 X @
-SCHED_YIELD 537 X @
-SETDOMAINNAME 538 X @
-SETFSGID 539 1 @
-SETFSUID 540 1 @
-SETGROUPS 541 2 @
-SETHOSTNAME 542 2 @
-SETITIMER 543 3 @
-SETPGID 544 2 @
-SETPRIORITY 545 3 @
-SETREGID 546 2 @
-SETREUID 547 2 @
-SETRLIMIT 548 2 @
-SETSID 549 0 @
-SGETMASK 550 X @
-SIGACTION 551 X @
-SIGPENDING 552 X @
-SIGPROCMASK 553 X @
-SIGRETURN 554 X @
-SIGSUSPEND 555 X @
-SOCKETCALL 556 X @
-SSETMASK 557 X @
-STATFS 558 2 @
-SWAPOFF 559 X @
-SWAPON 560 X @
-SYSCTL 561 X @
-SYSFS 562 X @
-SYSINFO 563 X - Use /proc
-SYSLOG 564 X @ Poss fifo & libc implementation.
-TRUNCATE 565 3 @
-ULIMIT 566 2 @
-UNAME 567 1 @
-USTAT 568 2 @
-VHANGUP 569 0 @
-WRITEV 570 3 @
diff --git a/makefile.in b/makefile.in
index 2f3832c..afedd16 100644
--- a/makefile.in
+++ b/makefile.in
@@ -149,13 +149,7 @@ bindir: $(MAKEX)
@ln -s ../kinclude/arch include/arch 2>/dev/null || true
#endif
-bcc86: bindir
- echo '#define VERSION "'"$(VERSION)"'"' > bcc/version.h
- VER=$(VERSION) ; \
- echo "#define VER_MAJ $${VER%%.*}" >> bcc/version.h ; \
- VER="$${VER#*.}" ; \
- echo "#define VER_MIN $${VER%.*}" >> bcc/version.h ; \
- echo "#define VER_PAT $${VER#*.}" >> bcc/version.h
+bcc86: bindir versions
$(MAKEC) bcc $(MAKEARG) BCCARCH='$(BCCARCH)' bcc ncc bcc-cc1
cp -p bcc/bcc$(EXE) bin/Bcc$(EXE)
cp -p bcc/ncc$(EXE) bin/ncc$(EXE)
@@ -177,8 +171,7 @@ copt: bindir
cp -p copt/rules.386 lib/i386/.
cp -p copt/rules.end lib/i386/.
-as86: bindir
- echo '#define VERSION "'"$(VERSION)"'"' > as/version.h
+as86: bindir versions
$(MAKEC) as $(MAKEARG) all
cp -p as/as86$(EXE) bin/as86$(EXE)
cp -p as/as86_encap bin/as86_encap
@@ -187,8 +180,7 @@ ar86: bindir
$(MAKEC) ar $(MAKEARG) all
cp -p ar/ar86$(EXE) bin/ar86$(EXE)
-ld86: bindir
- echo '#define VERSION "'"$(VERSION)"'"' > ld/version.h
+ld86: bindir versions
$(MAKEC) ld $(MAKEARG) ld86
cp -p ld/ld86$(EXE) bin/ld86$(EXE)
@@ -206,7 +198,7 @@ elksemu: bindir
$(MAKEC) elksemu elksemu
cp -p elksemu/elksemu bin/elksemu
#else
-elksemu: bindir
+try_elksemu: bindir
$(MAKEC) elksemu CC='ncc' elksemu
cp -p elksemu/elksemu bin/elksemu
#endif
@@ -333,6 +325,20 @@ makec:
echo 'cd $$1 ; shift ; make "$$@"' > makec
chmod +x makec
+versions: bcc/version.h
+
+bcc/version.h: Makefile
+ echo '#define VERSION "'"$(VERSION)"'"' > bcc/version.h
+ echo '#define VERSION "'"$(VERSION)"'"' > as/version.h
+ echo '#define VERSION "'"$(VERSION)"'"' > bootblocks/version.h
+ echo '#define VERSION "'"$(VERSION)"'"' > ld/version.h
+
+ VER=$(VERSION) ; \
+ echo "#define VER_MAJ $${VER%%.*}" >> bcc/version.h ; \
+ VER="$${VER#*.}" ; \
+ echo "#define VER_MIN $${VER%.*}" >> bcc/version.h ; \
+ echo "#define VER_PAT $${VER#*.}" >> bcc/version.h
+
##############################################################################
install-other: other
@@ -340,8 +346,7 @@ install-other: other
$(MAKEC) $$i BCC=ncc DIST=$(DIST) PREFIX=$(PREFIX) install || exit 1 ; \
done
-other:
- echo '#define VERSION "'"$(VERSION)"'"' > bootblocks/version.h
+other: versions
@for i in $(OTHERS) ; do \
$(MAKEC) $$i BCC=ncc DIST=$(DIST) PREFIX=$(PREFIX) || exit 1; \
done
diff --git a/tests/Makefile b/tests/Makefile
index fb77f34..6e83245 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -9,12 +9,24 @@ CFLAGS=-O
SRC=env.c ft.c hd.c sync.c compr.c ucomp.c ouch.c lines.c \
wc.c line2.c rand.c grab.c
OBJ=
-EXE=env ft hd sync compr ucomp ouch lines wc line2 rand grab
+EXE=env ft hd sync compr ucomp ouch lines wc line2 rand grab bcc-x86
LINK_FILES=cat chgrp chmod chown cp install ln mkdir mkfifo mknod mv rm
all: $(EXE)
+bcc-x86:
+ $(CC) -O -o bcc-x86 \
+ ../bcc/assign.c ../bcc/bcc-cc1.c ../bcc/codefrag.c \
+ ../bcc/dbnode.c ../bcc/debug.c ../bcc/declare.c \
+ ../bcc/express.c ../bcc/exptree.c ../bcc/floatop.c \
+ ../bcc/function.c ../bcc/gencode.c ../bcc/genloads.c \
+ ../bcc/glogcode.c ../bcc/hardop.c ../bcc/hashcmd.c \
+ ../bcc/input.c ../bcc/label.c ../bcc/loadexp.c \
+ ../bcc/longop.c ../bcc/output.c ../bcc/preproc.c \
+ ../bcc/preserve.c ../bcc/scan.c ../bcc/softop.c \
+ ../bcc/state.c ../bcc/table.c ../bcc/type.c
+
install:
echo Use real-install if you actually want to install these
diff --git a/tests/a.out b/tests/a.out
new file mode 100755
index 0000000..46f8688
--- /dev/null
+++ b/tests/a.out
Binary files differ
diff --git a/tests/hello_world.s b/tests/hello_world.s
new file mode 100644
index 0000000..8932287
--- /dev/null
+++ b/tests/hello_world.s
@@ -0,0 +1,18 @@
+
+.text
+entry start
+start:
+mov ax,#4
+mov bx,#1
+mov cx,#hello
+mov dx,#endhello-hello
+int $80
+
+mov bx,#0
+mov ax,#1
+int $80
+
+.data
+hello:
+ .ascii "Hello world!\n"
+endhello:
diff --git a/unproto/Makefile.old b/unproto/Makefile.old
deleted file mode 100644
index 2d7a98c..0000000
--- a/unproto/Makefile.old
+++ /dev/null
@@ -1,123 +0,0 @@
-# @(#) Makefile 1.6 93/06/18 22:29:40
-
-## BEGIN CONFIGURATION STUFF
-
-# In the unlikely case that your compiler has no hooks for alternate
-# compiler passes, use a "cc cflags -E file.c | unproto >file.i"
-# pipeline, then "cc cflags -c file.i" to compile the resulting
-# intermediate file.
-#
-# Otherwise, the "/lib/cpp | unproto" pipeline can be packaged as an
-# executable shell script (see the provided "cpp.sh" script) that should
-# be installed as "/whatever/cpp". This script should then be specified
-# to the C compiler as a non-default preprocessor.
-#
-# PROG = unproto
-# PIPE =
-
-# The overhead and problems of shell script interpretation can be
-# eliminated by having the unprototyper program itself open the pipe to
-# the preprocessor. In that case, define the PIPE_THROUGH_CPP macro as
-# the path name of the default C preprocessor (usually "/lib/cpp"),
-# install the unprototyper as "/whatever/cpp" and specify that to the C
-# compiler as a non-default preprocessor.
-#
-PROG = cpp
-PIPE = -DPIPE_THROUGH_CPP=\"/lib/cpp\"
-
-# Some compilers complain about some #directives. The following is only a
-# partial solution, because the directives are still seen by /lib/cpp.
-# Be careful with filtering out #pragma, because some pre-ANSI compilers
-# (SunOS) rely on its use.
-#
-# SKIP = -DIGNORE_DIRECTIVES=\"pragma\",\"foo\",\"bar\"
-#
-SKIP =
-
-# The bell character code depends on the character set. With ASCII, it is
-# 7. Specify a string constant with exactly three octal digits. If you
-# change this definition, you will have to update the example.out file.
-#
-BELL = -DBELL=\"007\"
-
-# Some C compilers have problems with "void". The nature of the problems
-# depends on the age of the compiler.
-#
-# If your compiler does not understand "void" at all, compile with
-# -DMAP_VOID. The unprototyper will replace "void *" by "char *", a
-# (void) argument list by an empty one, and will replace all other
-# instances of "void" by "int".
-#
-# If your compiler has problems with "void *" only, compile with
-# -DMAP_VOID_STAR. The unprototyper will replace "void *" by "char *",
-# and will replace a (void) argument list by an empty one. All other
-# instances of "void" will be left alone.
-#
-# If neither of these are defined, (void) argument lists will be replaced
-# by empty ones.
-#
-# MAP = -DMAP_VOID_STAR
-
-# Now that we have brought up the subject of antique C compilers, here's
-# a couple of aliases that may be useful, too.
-#
-# ALIAS = -Dstrchr=index
-
-# If you need support for functions that implement ANSI-style variable
-# length argument lists, edit the stdarg.h file provided with this
-# package so that it contains the proper definitions for your machine.
-
-## END CONFIGURATION STUFF
-
-SHELL = /bin/sh
-
-CFILES = unproto.c tok_io.c tok_class.c tok_pool.c vstring.c symbol.c error.c \
- hash.c strsave.c
-HFILES = error.h token.h vstring.h symbol.h
-SCRIPTS = cpp.sh acc.sh
-SAMPLES = stdarg.h stddef.h stdlib.h varargs.c example.c example.out
-SOURCES = README $(CFILES) $(HFILES) Makefile $(SCRIPTS) $(SAMPLES)
-FILES = $(SOURCES) unproto.1
-OBJECTS = tok_io.o tok_class.o tok_pool.o unproto.o vstring.o symbol.o error.o \
- hash.o strsave.o
-
-CFLAGS = -O $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS)
-#CFLAGS = -O $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS) -p -Dstatic=
-#CFLAGS = -g $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS) -DDEBUG
-
-$(PROG): $(OBJECTS)
- $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(MALLOC)
-
-# For linting, enable all bells and whistles.
-
-lint:
- lint -DPIPE_THROUGH_CPP=\"foo\" -DIGNORE_DIRECTIVES=\"foo\",\"bar\" \
- $(BELL) -DMAP_VOID $(ALIAS) $(CFILES)
-
-# Testing requires that the program is compiled with -DDEBUG.
-
-test: $(PROG) cpp example.c example.out
- ./cpp example.c >example.tmp
- @echo the following diff command should produce no output
- diff -b example.out example.tmp
- rm -f example.tmp
-
-shar: $(FILES)
- @shar $(FILES)
-
-archive:
- $(ARCHIVE) $(SOURCES)
-
-clean:
- rm -f *.o core cpp unproto mon.out varargs.o varargs example.tmp
-
-error.o : error.c token.h error.h Makefile
-hash.o : hash.c Makefile
-strsave.o : strsave.c error.h Makefile
-symbol.o : symbol.c error.h token.h symbol.h Makefile
-tok_class.o : tok_class.c error.h vstring.h token.h symbol.h Makefile
-tok_io.o : tok_io.c token.h vstring.h error.h Makefile
-tok_pool.o : tok_pool.c token.h vstring.h error.h Makefile
-unproto.o : unproto.c vstring.h stdarg.h token.h error.h symbol.h Makefile
-varargs.o : varargs.c stdarg.h Makefile
-vstring.o : vstring.c vstring.h Makefile
diff --git a/unproto/unproto.c.old b/unproto/unproto.c.old
deleted file mode 100644
index 2b2e764..0000000
--- a/unproto/unproto.c.old
+++ /dev/null
@@ -1,999 +0,0 @@
-/*++
-/* NAME
-/* unproto 1
-/* SUMMARY
-/* compile ANSI C with traditional UNIX C compiler
-/* PACKAGE
-/* unproto
-/* SYNOPSIS
-/* /somewhere/cpp ...
-/*
-/* cc cflags -E file.c | unproto >file.i; cc cflags -c file.i
-/* DESCRIPTION
-/* This document describes a filter that sits in between the UNIX
-/* C preprocessor and the next UNIX C compiler stage, on the fly rewriting
-/* ANSI-style syntax to old-style syntax. Typically, the program is
-/* invoked by the native UNIX C compiler as an alternate preprocessor.
-/* The unprototyper in turn invokes the native C preprocessor and
-/* massages its output. Similar tricks can be used with the lint(1)
-/* command.
-/*
-/* Language constructs that are always rewritten:
-/* .TP
-/* function headings, prototypes, pointer types
-/* ANSI-C style function headings, function prototypes, function
-/* pointer types and type casts are rewritten to old style.
-/* <stdarg.h> support is provided for functions with variable-length
-/* argument lists.
-/* .TP
-/* character and string constants
-/* The \\a and \\x escape sequences are rewritten to their (three-digit)
-/* octal equivalents.
-/*
-/* Multiple string tokens are concatenated; an arbitrary number of
-/* whitespace or comment tokens may appear between successive
-/* string tokens.
-/*
-/* Within string constants, octal escape sequences are rewritten to the
-/* three-digit \\ddd form, so that string concatenation produces correct
-/* results.
-/* .TP
-/* date and time
-/* The __DATE__ and __TIME__ tokens are replaced by string constants
-/* of the form "Mmm dd yyyy" and "hh:mm:ss", respectively. The result
-/* is subjected to string concatenation, just like any other string
-/* constant.
-/* .PP
-/* Language constructs that are rewritten only if the program has been
-/* configured to do so:
-/* .TP
-/* void types
-/* The unprototyper can be configured to rewrite "void *" to "char *",
-/* and even to rewrite plain "void" to "int".
-/* These features are configurable because many traditional UNIX C
-/* compilers do not need them.
-/*
-/* Note: (void) argument lists are always replaced by empty ones.
-/* .PP
-/* ANSI C constructs that are not rewritten because the traditional
-/* UNIX C preprocessor provides suitable workarounds:
-/* .TP
-/* const and volatile
-/* Use the "-Dconst=" and/or "-Dvolatile=" preprocessor directives to
-/* get rid of unimplemented keywords.
-/* .TP
-/* token pasting and stringizing
-/* The traditional UNIX C preprocessor provides excellent alternatives.
-/* For example:
-/*
-/* .nf
-/* .ne 2
-/* #define string(bar) "bar" /* instead of: # x */
-/* #define paste(x,y) x/**\/y /* instead of: x##y */
-/* .fi
-/*
-/* There is a good reason why the # and ## operators are not implemented
-/* in the unprototyper.
-/* After program text has gone through a non-ANSI C preprocessor, all
-/* information about the grouping of the operands of # and ## is lost.
-/* Thus, if the unprototyper were to perform these operations, it would
-/* produce correct results only in the most trivial cases. Operands
-/* with embedded blanks, operands that expand to null tokens, and nested
-/* use of # and/or ## would cause all kinds of obscure problems.
-/* .PP
-/* Unsupported ANSI features:
-/* .TP
-/* trigraphs and #pragmas
-/* Trigraphs are useful only for systems with broken character sets.
-/* If the local compiler chokes on #pragma, insert a blank before the
-/* "#" character, and enclose the offending directive between #ifdef
-/* and #endif.
-/* SEE ALSO
-/* .ad
-/* .fi
-/* cc(1), how to specify a non-default C preprocessor.
-/* Some versions of the lint(1) command are implemented as a shell
-/* script. It should require only minor modification for integration
-/* with the unprototyper. Other versions of the lint(1) command accept
-/* the same command syntax as the C compiler for the specification of a
-/* non-default preprocessor. Some research may be needed.
-/* FILES
-/* /wherever/stdarg.h, provided with the unproto filter.
-/* DIAGNOSTICS
-/* Problems are reported on the standard error stream.
-/* A non-zero exit status means that there was a problem.
-/* BUGS
-/* The unprototyper should be run on preprocessed source only:
-/* unexpanded macros may confuse the program.
-/*
-/* Declarations of (object) are misunderstood and will result in
-/* syntax errors: the objects between parentheses disappear.
-/*
-/* Sometimes does not preserve whitespace after parentheses and commas.
-/* This is a purely aesthetical matter, and the compiler should not care.
-/* Whitespace within string constants is, of course, left intact.
-/*
-/* Does not generate explicit type casts for function-argument
-/* expressions. The lack of explicit conversions between integral
-/* and/or pointer argument types should not be a problem in environments
-/* where sizeof(int) == sizeof(long) == sizeof(pointer). A more serious
-/* problem is the lack of automatic type conversions between integral and
-/* floating-point argument types. Let lint(1) be your friend.
-/* AUTHOR(S)
-/* Wietse Venema (wietse@wzv.win.tue.nl)
-/* Eindhoven University of Technology
-/* Department of Mathematics and Computer Science
-/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
-/* LAST MODIFICATION
-/* 93/06/18 22:29:37
-/* VERSION/RELEASE
-/* 1.6
-/*--*/
-
-static char unproto_sccsid[] = "@(#) unproto.c 1.6 93/06/18 22:29:37";
-
-/* C library */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <errno.h>
-
-extern void exit();
-extern int optind;
-extern char *optarg;
-extern int getopt();
-
-/* Application-specific stuff */
-
-#include "vstring.h"
-#include "stdarg.h"
-#include "token.h"
-#include "error.h"
-#include "symbol.h"
-
-/* Forward declarations. */
-
-static struct token *dcl_flush();
-static void block_flush();
-static void block_dcls();
-static struct token *show_func_ptr_type();
-static struct token *show_struct_type();
-static void show_arg_name();
-static void show_type();
-static void pair_flush();
-static void check_cast();
-static void show_empty_list();
-
-#define check_cast_flush(t) (check_cast(t), tok_free(t))
-
-#ifdef PIPE_THROUGH_CPP
-static int pipe_stdin_through_cpp();
-#endif
-
-/* Disable debugging printfs while preserving side effects. */
-
-#ifdef DEBUG
-#define DPRINTF printf
-#else
-#define DPRINTF (void)
-#endif
-
-/* An attempt to make some complicated expressions a bit more readable. */
-
-#define STREQ(x,y) (*(x) == *(y) && !strcmp((x),(y)))
-
-#define LAST_ARG_AND_EQUAL(s,c) ((s)->next && (s)->next->next == 0 \
- && (s)->head && ((s)->head == (s)->tail) \
- && (STREQ((s)->head->vstr->str, (c))))
-
-#define LIST_BEGINS_WITH_STAR(s) (s->head->head && s->head->head->tokno == '*')
-
-#define IS_FUNC_PTR_TYPE(s) (s->tokno == TOK_LIST && s->next \
- && s->next->tokno == TOK_LIST \
- && LIST_BEGINS_WITH_STAR(s))
-
-/* What to look for to detect a (void) argument list. */
-
-#ifdef MAP_VOID
-#define VOID_ARG "int" /* bare "void" is mapped to "int" */
-#else
-#define VOID_ARG "void" /* bare "void" is left alone */
-#endif
-
-/* main - driver */
-
-int main(argc, argv)
-int argc;
-char **argv;
-{
- register struct token *t;
-#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */
- int cpp_status;
- int wait_pid;
- int cpp_pid;
-
- cpp_pid = pipe_stdin_through_cpp(argv);
-#endif
-
- sym_init(); /* prime the symbol table */
-
- while (t = tok_class()) {
- if (t = dcl_flush(t)) { /* try declaration */
- if (t->tokno == '{') { /* examine rejected token */
- block_flush(t); /* body */
- } else {
- tok_flush(t); /* other, recover */
- }
- }
- }
-
-#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */
- while ((wait_pid = wait(&cpp_status)) != -1 && wait_pid != cpp_pid)
- /* void */ ;
- return (errcount != 0 || wait_pid != cpp_pid || cpp_status != 0);
-#else
- return (errcount != 0);
-#endif
-}
-
-#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */
-
-/* pipe_stdin_through_cpp - avoid shell script overhead */
-
-static int pipe_stdin_through_cpp(argv)
-char **argv;
-{
- int pipefds[2];
- int pid;
- char **cpptr = argv;
- int i;
- struct stat st;
-
- /*
- * The code that sets up the pipe requires that file descriptors 0,1,2
- * are already open. All kinds of mysterious things will happen if that
- * is not the case. The following loops makes sure that descriptors 0,1,2
- * are set up properly.
- */
-
- for (i = 0; i < 3; i++) {
- if (fstat(i, &st) == -1 && open("/dev/null", 2) != i) {
- perror("open /dev/null");
- exit(1);
- }
- }
-
- /*
- * With most UNIX implementations, the second non-option argument to
- * /lib/cpp specifies the output file. If an output file other than
- * stdout is specified, we must force /lib/cpp to write to stdout, and we
- * must redirect our own standard output to the specified output file.
- */
-
-#define IS_OPTION(cp) ((cp)[0] == '-' && (cp)[1] != 0)
-
- /* Skip to first non-option argument, if any. */
-
- while (*++cpptr && IS_OPTION(*cpptr))
- /* void */ ;
-
- /*
- * Assume that the first non-option argument is the input file name. The
- * next argument could be the output destination or an option (System V
- * Release 2 /lib/cpp gets the options *after* the file arguments).
- */
-
- if (*cpptr && *++cpptr && **cpptr != '-') {
-
- /*
- * The first non-option argument is followed by another argument that
- * is not an option ("-stuff") or a hyphen ("-"). Redirect our own
- * standard output before we clobber the file name.
- */
-
- if (freopen(*cpptr, "w", stdout) == 0) {
- perror(*cpptr);
- exit(1);
- }
- /* Clobber the file name argument so that /lib/cpp writes to stdout */
-
- *cpptr = "-";
- }
- /* Set up the pipe that connects /lib/cpp to our standard input. */
-
- if (pipe(pipefds)) {
- perror("pipe");
- exit(1);
- }
- switch (pid = fork()) {
- case -1: /* error */
- perror("fork");
- exit(1);
- /* NOTREACHED */
- case 0: /* child */
- (void) close(pipefds[0]); /* close reading end */
- (void) close(1); /* connect stdout to pipe */
- if (dup(pipefds[1]) != 1)
- fatal("dup() problem");
- (void) close(pipefds[1]); /* close redundant fd */
- (void) execv(PIPE_THROUGH_CPP, argv);
- perror(PIPE_THROUGH_CPP);
- exit(1);
- /* NOTREACHED */
- default: /* parent */
- (void) close(pipefds[1]); /* close writing end */
- (void) close(0); /* connect stdin to pipe */
- if (dup(pipefds[0]) != 0)
- fatal("dup() problem");
- close(pipefds[0]); /* close redundant fd */
- return (pid);
- }
-}
-
-#endif
-
-/* show_arg_names - display function argument names */
-
-static void show_arg_names(t)
-register struct token *t;
-{
- register struct token *s;
-
- /* Do argument names, but suppress void and rewrite trailing ... */
-
- if (LAST_ARG_AND_EQUAL(t->head, VOID_ARG)) {
- show_empty_list(t); /* no arguments */
- } else {
- for (s = t->head; s; s = s->next) { /* foreach argument... */
- if (LAST_ARG_AND_EQUAL(s, "...")) {
-#ifdef _VA_ALIST_ /* see ./stdarg.h */
- tok_show_ch(s); /* ',' */
- put_str(_VA_ALIST_); /* varargs magic */
-#endif
- } else {
- tok_show_ch(s); /* '(' or ',' or ')' */
- show_arg_name(s); /* extract argument name */
- }
- }
- }
-}
-
-/* show_arg_types - display function argument types */
-
-static void show_arg_types(t)
-register struct token *t;
-{
- register struct token *s;
-
- /* Do argument types, but suppress void and trailing ... */
-
- if (!LAST_ARG_AND_EQUAL(t->head, VOID_ARG)) {
- for (s = t->head; s; s = s->next) { /* foreach argument... */
- if (LAST_ARG_AND_EQUAL(s, "...")) {
-#ifdef _VA_DCL_ /* see ./stdarg.h */
- put_str(_VA_DCL_); /* varargs magic */
- put_nl(); /* make output look nicer */
-#endif
- } else {
- if (s->head != s->tail) { /* really new-style argument? */
- show_type(s); /* rewrite type info */
- put_ch(';');
- put_nl(); /* make output look nicer */
- }
- }
- }
- }
-}
-
-/* header_flush - rewrite new-style function heading to old style */
-
-static void header_flush(t)
-register struct token *t;
-{
- show_arg_names(t); /* show argument names */
- put_nl(); /* make output look nicer */
- show_arg_types(t); /* show argument types */
- tok_free(t); /* discard token */
-}
-
-/* fpf_header_names - define func returning ptr to func, no argument types */
-
-static void fpf_header_names(list)
-struct token *list;
-{
- register struct token *s;
- register struct token *p;
-
- /*
- * Recurse until we find the argument list. Account for the rare case
- * that list is a comma-separated list (which should be a syntax error).
- * Display old-style fuction argument names.
- */
-
- for (s = list->head; s; s = s->next) {
- tok_show_ch(s); /* '(' or ',' or ')' */
- for (p = s->head; p; p = p->next) {
- if (p->tokno == TOK_LIST) {
- if (IS_FUNC_PTR_TYPE(p)) { /* recurse */
- fpf_header_names(p);
- show_empty_list(p = p->next);
- } else { /* display argument names */
- show_arg_names(p);
- }
- } else { /* pass through other stuff */
- tok_show(p);
- }
- }
- }
-}
-
-/* fpf_header_types - define func returning ptr to func, argument types only */
-
-static void fpf_header_types(list)
-struct token *list;
-{
- register struct token *s;
- register struct token *p;
-
- /*
- * Recurse until we find the argument list. Account for the rare case
- * that list is a comma-separated list (which should be a syntax error).
- * Display old-style function argument types.
- */
-
- for (s = list->head; s; s = s->next) {
- for (p = s->head; p; p = p->next) {
- if (p->tokno == TOK_LIST) {
- if (IS_FUNC_PTR_TYPE(p)) { /* recurse */
- fpf_header_types(p);
- p = p->next;
- } else { /* display argument types */
- show_arg_types(p);
- }
- }
- }
- }
-}
-
-/* fpf_header - define function returning pointer to function */
-
-static void fpf_header(l1, l2)
-struct token *l1;
-struct token *l2;
-{
- fpf_header_names(l1); /* strip argument types */
- show_empty_list(l2); /* strip prototype */
- put_nl(); /* nicer output */
- fpf_header_types(l1); /* show argument types */
-}
-
-/* skip_enclosed - skip over enclosed tokens */
-
-static struct token *skip_enclosed(p, stop)
-register struct token *p;
-register int stop;
-{
- register int start = p->tokno;
-
- /* Always return a pointer to the last processed token, never NULL. */
-
- while (p->next) {
- p = p->next;
- if (p->tokno == start) {
- p = skip_enclosed(p, stop); /* recurse */
- } else if (p->tokno == stop) {
- break; /* done */
- }
- }
- return (p);
-}
-
-/* show_arg_name - extract argument name from argument type info */
-
-static void show_arg_name(s)
-register struct token *s;
-{
- if (s->head) {
- register struct token *p;
- register struct token *t = 0;
-
- /* Find the last interesting item. */
-
- for (p = s->head; p; p = p->next) {
- if (p->tokno == TOK_WORD) {
- t = p; /* remember last word */
- } else if (p->tokno == '{') {
- p = skip_enclosed(p, '}'); /* skip structured stuff */
- } else if (p->tokno == '[') {
- break; /* dimension may be a macro */
- } else if (IS_FUNC_PTR_TYPE(p)) {
- t = p; /* or function pointer */
- p = p->next;
- }
- }
-
- /* Extract argument name from last interesting item. */
-
- if (t) {
- if (t->tokno == TOK_LIST)
- show_arg_name(t->head); /* function pointer, recurse */
- else
- tok_show(t); /* print last word */
- }
- }
-}
-
-/* show_type - rewrite type to old-style syntax */
-
-static void show_type(s)
-register struct token *s;
-{
- register struct token *p;
-
- /*
- * Rewrite (*stuff)(args) to (*stuff)(). Rewrite word(args) to word(),
- * but only if the word was preceded by a word, '*' or '}'. Leave
- * anything else alone.
- */
-
- for (p = s->head; p; p = p->next) {
- if (IS_FUNC_PTR_TYPE(p)) {
- p = show_func_ptr_type(p, p->next); /* function pointer type */
- } else {
- register struct token *q;
- register struct token *r;
-
- tok_show(p); /* other */
- if ((p->tokno == TOK_WORD || p->tokno == '*' || p->tokno == '}')
- && (q = p->next) && q->tokno == TOK_WORD
- && (r = q->next) && r->tokno == TOK_LIST) {
- tok_show(q); /* show name */
- show_empty_list(p = r); /* strip args */
- }
- }
- }
-}
-
-/* show_func_ptr_type - display function_pointer type using old-style syntax */
-
-static struct token *show_func_ptr_type(t1, t2)
-struct token *t1;
-struct token *t2;
-{
- register struct token *s;
-
- /*
- * Rewrite (list1) (list2) to (list1) (). Account for the rare case that
- * (list1) is a comma-separated list. That should be an error, but we do
- * not want to waste any information.
- */
-
- for (s = t1->head; s; s = s->next) {
- tok_show_ch(s); /* '(' or ',' or ')' */
- show_type(s); /* recurse */
- }
- show_empty_list(t2);
- return (t2);
-}
-
-/* show_empty_list - display opening and closing parentheses (if available) */
-
-static void show_empty_list(t)
-register struct token *t;
-{
- tok_show_ch(t->head); /* opening paren */
- if (t->tail->tokno == ')')
- tok_show_ch(t->tail); /* closing paren */
-}
-
-/* show_struct_type - display structured type, rewrite function-pointer types */
-
-static struct token *show_struct_type(p)
-register struct token *p;
-{
- tok_show(p); /* opening brace */
-
- while (p->next) { /* XXX cannot return 0 */
- p = p->next;
- if (IS_FUNC_PTR_TYPE(p)) {
- p = show_func_ptr_type(p, p->next); /* function-pointer member */
- } else if (p->tokno == '{') {
- p = show_struct_type(p); /* recurse */
- } else {
- tok_show(p); /* other */
- if (p->tokno == '}') {
- return (p); /* done */
- }
- }
- }
- DPRINTF("/* missing '}' */");
- return (p);
-}
-
-/* is_func_ptr_cast - recognize function-pointer type cast */
-
-static int is_func_ptr_cast(t)
-register struct token *t;
-{
- register struct token *p;
-
- /*
- * Examine superficial structure. Require (list1) (list2). Require that
- * list1 begins with a star.
- */
-
- if (!IS_FUNC_PTR_TYPE(t))
- return (0);
-
- /*
- * Make sure that there is no name in (list1). Do not worry about
- * unexpected tokens, because the compiler will complain anyway.
- */
-
- for (p = t->head->head; p; p = p->next) {
- switch (p->tokno) {
- case TOK_LIST: /* recurse */
- return (is_func_ptr_cast(p));
- case TOK_WORD: /* name in list */
- return (0);
- case '[':
- return (1); /* dimension may be a macro */
- }
- }
- return (1); /* no name found */
-}
-
-/* check_cast - display ()-delimited, comma-separated list */
-
-static void check_cast(t)
-struct token *t;
-{
- register struct token *s;
- register struct token *p;
-
- /*
- * Rewrite function-pointer types and function-pointer casts. Do not
- * blindly rewrite (*list1)(list2) to (*list1)(). Function argument lists
- * are about the only thing we can discard without provoking diagnostics
- * from the compiler.
- */
-
- for (s = t->head; s; s = s->next) {
- tok_show_ch(s); /* '(' or ',' or ')' */
- for (p = s->head; p; p = p->next) {
- switch (p->tokno) {
- case TOK_LIST:
- if (is_func_ptr_cast(p)) { /* not: IS_FUNC_PTR_TYPE(p) */
- p = show_func_ptr_type(p, p->next);
- } else {
- check_cast(p); /* recurse */
- }
- break;
- case '{':
- p = show_struct_type(p); /* rewrite func. ptr. types */
- break;
- default:
- tok_show(p);
- break;
- }
- }
- }
-}
-
-/* block_dcls - on the fly rewrite decls/initializers at start of block */
-
-static void block_dcls()
-{
- register struct token *t;
-
- /*
- * Away from the top level, a declaration should be preceded by type or
- * storage-class information. That is why inside blocks, structs and
- * unions we insist on reading one word before passing the _next_ token
- * to the dcl_flush() function.
- *
- * Struct and union declarations look the same everywhere: we make an
- * exception for these more regular constructs and pass the "struct" and
- * "union" tokens to the type_dcl() function.
- */
-
- while (t = tok_class()) {
- switch (t->tokno) {
- case TOK_WSPACE: /* preserve white space */
- case '\n': /* preserve line count */
- tok_flush(t);
- break;
- case TOK_WORD: /* type declarations? */
- tok_flush(t); /* advance to next token */
- t = tok_class(); /* null return is ok */
- /* FALLTRHOUGH */
- case TOK_COMPOSITE: /* struct or union */
- if ((t = dcl_flush(t)) == 0)
- break;
- /* FALLTRHOUGH */
- default: /* end of declarations */
- DPRINTF("/* end dcls */");
- /* FALLTRHOUGH */
- case '}': /* end of block */
- tok_unget(t);
- return;
- }
- }
-}
-
-/* block_flush - rewrite struct, union or statement block on the fly */
-
-static void block_flush(t)
-register struct token *t;
-{
- static int count = 0;
-
- tok_flush(t);
- DPRINTF("/*%d*/", ++count);
-
- /*
- * Rewrite function pointer types in declarations and function pointer
- * casts in initializers at start of block.
- */
-
- block_dcls();
-
- /* Remainder of block: only rewrite function pointer casts. */
-
- while (t = tok_class()) {
- if (t->tokno == TOK_LIST) {
- check_cast_flush(t);
- } else if (t->tokno == '{') {
- block_flush(t);
- } else {
- tok_flush(t);
- if (t->tokno == '}') {
- DPRINTF("/*%d*/", count--);
- return;
- }
- }
- }
- DPRINTF("/* missing '}' */");
-}
-
-/* pair_flush - on the fly rewrite casts in grouped stuff */
-
-static void pair_flush(t, start, stop)
-register struct token *t;
-register int start;
-register int stop;
-{
- tok_flush(t);
-
- while (t = tok_class()) {
- if (t->tokno == start) { /* recurse */
- pair_flush(t, start, stop);
- } else if (t->tokno == TOK_LIST) { /* expression or cast */
- check_cast_flush(t);
- } else { /* other, copy */
- tok_flush(t);
- if (t->tokno == stop) { /* done */
- return;
- }
- }
- }
- DPRINTF("/* missing '%c' */", stop);
-}
-
-/* initializer - on the fly rewrite casts in initializer */
-
-static void initializer()
-{
- register struct token *t;
-
- while (t = tok_class()) {
- switch (t->tokno) {
- case ',': /* list separator */
- case ';': /* list terminator */
- tok_unget(t);
- return;
- case TOK_LIST: /* expression or cast */
- check_cast_flush(t);
- break;
- case '[': /* array subscript, may nest */
- pair_flush(t, '[', ']');
- break;
- case '{': /* structured data, may nest */
- pair_flush(t, '{', '}');
- break;
- default: /* other, just copy */
- tok_flush(t);
- break;
- }
- }
-}
-
-/* func_ptr_dcl_flush - rewrite function pointer stuff */
-
-static struct token *func_ptr_dcl_flush(list)
-register struct token *list;
-{
- register struct token *t;
- register struct token *t2;
-
- /*
- * Ignore blanks and newlines because we are too lazy to maintain more
- * than one token worth of lookahead. The output routines will regenerate
- * discarded newline tokens.
- */
-
- while (t = tok_class()) {
- switch (t->tokno) {
- case TOK_WSPACE:
- case '\n':
- tok_free(t);
- break;
- case TOK_LIST:
- /* Function pointer or function returning pointer to function. */
- while ((t2 = tok_class()) /* skip blanks etc. */
- &&(t2->tokno == TOK_WSPACE || t2->tokno == '\n'))
- tok_free(t2);
- switch (t2 ? t2->tokno : 0) {
- case '{': /* function heading (new) */
- fpf_header(list, t);
- break;
- case TOK_WORD: /* function heading (old) */
- tok_show(list);
- tok_show(t);
- break;
- default: /* func pointer type */
- (void) show_func_ptr_type(list, t);
- break;
- }
- tok_free(list);
- tok_free(t);
- if (t2)
- tok_unget(t2);
- return (0);
- default: /* not a declaration */
- tok_unget(t);
- return (list);
- }
- }
-
- /* Hit EOF; must be mistake, but do not waste any information. */
-
- return (list);
-}
-
-/* function_dcl_flush - rewrite function { heading, type declaration } */
-
-static struct token *function_dcl_flush(list)
-register struct token *list;
-{
- register struct token *t;
-
- /*
- * Ignore blanks and newlines because we are too lazy to maintain more
- * than one token worth of lookahead. The output routines will regenerate
- * ignored newline tokens.
- */
-
- while (t = tok_class()) {
- switch (t->tokno) {
- case TOK_WSPACE:
- case '\n':
- tok_free(t);
- break;
- case '{':
- /* Function heading: word (list) { -> old style heading */
- header_flush(list);
- tok_unget(t);
- return (0);
- case TOK_WORD:
- /* Old-style function heading: word (list) word... */
- tok_flush(list);
- tok_unget(t);
- return (0);
- case TOK_LIST:
- /* Function pointer: word (list1) (list2) -> word (list1) () */
- tok_flush(list);
- show_empty_list(t);
- tok_free(t);
- return (0);
- case ',':
- case ';':
- /* Function type declaration: word (list) -> word () */
- show_empty_list(list);
- tok_free(list);
- tok_unget(t);
- return (0);
- default:
- /* Something else, reject the list. */
- tok_unget(t);
- return (list);
- }
- }
-
- /* Hit EOF; must be mistake, but do not waste any information. */
-
- return (list);
-}
-
-/* dcl_flush - parse declaration on the fly, return rejected token */
-
-static struct token *dcl_flush(t)
-register struct token *t;
-{
- register int got_word;
-
- /*
- * Away from the top level, type or storage-class information is required
- * for an (extern or forward) function type declaration or a variable
- * declaration.
- *
- * With our naive word-counting approach, this means that the caller should
- * read one word before passing the next token to us. This is how we
- * distinguish, for example, function declarations from function calls.
- *
- * An exception are structs and unions, because they look the same at any
- * level. The caller should give is the "struct" or "union" token.
- */
-
- for (got_word = 0; t; t = tok_class()) {
- switch (t->tokno) {
- case TOK_WSPACE: /* advance past blanks */
- case '\n': /* advance past newline */
- case '*': /* indirection: keep trying */
- tok_flush(t);
- break;
- case TOK_WORD: /* word: keep trying */
- case TOK_COMPOSITE: /* struct or union */
- got_word = 1;
- tok_flush(t);
- break;
- default:
-
- /*
- * Function pointer types can be preceded by zero or more words
- * (at least one when not at the top level). Other stuff can be
- * accepted only after we have seen at least one word (two words
- * when not at the top level). See also the above comment on
- * structs and unions.
- */
-
- if (t->tokno == TOK_LIST && LIST_BEGINS_WITH_STAR(t)) {
- if (t = func_ptr_dcl_flush(t)) {
- return (t); /* reject token */
- } else {
- got_word = 1; /* for = and [ and , and ; */
- }
- } else if (got_word == 0) {
- return (t); /* reject token */
- } else {
- switch (t->tokno) {
- case TOK_LIST: /* function type */
- if (t = function_dcl_flush(t))
- return (t); /* reject token */
- break;
- case '[': /* dimension, does not nest */
- pair_flush(t, '[', ']');
- break;
- case '=': /* initializer follows */
- tok_flush(t);
- initializer(); /* rewrite casts */
- break;
- case '{': /* struct, union, may nest */
- block_flush(t); /* use code for stmt blocks */
- break;
- case ',': /* separator: keep trying */
- got_word = 0;
- tok_flush(t);
- break;
- case ';': /* terminator: succeed */
- tok_flush(t);
- return (0);
- default: /* reject token */
- return (t);
- }
- }
- }
- }
- return (0); /* hit EOF */
-}