diff options
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: ; @@ -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.' @@ -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 Binary files differnew file mode 100644 index 0000000..1fbb636 --- /dev/null +++ b/bootblocks/freedosboot.zip 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); } } @@ -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 Binary files differnew file mode 100755 index 0000000..46f8688 --- /dev/null +++ b/tests/a.out 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 */ -} |