summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes23
-rw-r--r--Contributors7
-rw-r--r--Libc_version2
-rw-r--r--MAGIC2
-rw-r--r--Makefile25
-rw-r--r--README28
-rw-r--r--as/as.c8
-rw-r--r--as/as86_encap.sh10
-rw-r--r--as/globvar.h2
-rw-r--r--as/pops.c5
-rw-r--r--as/readsrc.c1
-rw-r--r--bcc/align.h2
-rw-r--r--bcc/assign.c14
-rw-r--r--bcc/bcc.c106
-rw-r--r--bcc/codefrag.c76
-rw-r--r--bcc/debug.c2
-rw-r--r--bcc/declare.c32
-rw-r--r--bcc/express.c2
-rw-r--r--bcc/exptree.c2
-rw-r--r--bcc/function.c8
-rw-r--r--bcc/gencode.c38
-rw-r--r--bcc/gencode.h34
-rw-r--r--bcc/genloads.c38
-rw-r--r--bcc/glogcode.c4
-rw-r--r--bcc/hardop.c16
-rw-r--r--bcc/label.c12
-rw-r--r--bcc/loadexp.c14
-rw-r--r--bcc/longop.c2
-rw-r--r--bcc/output.c12
-rw-r--r--bcc/preserve.c8
-rw-r--r--bcc/proto.h48
-rw-r--r--bcc/sizes.h6
-rw-r--r--bcc/softop.c66
-rw-r--r--bcc/state.c24
-rw-r--r--bcc/type.c20
-rw-r--r--bcc/type.h12
-rw-r--r--bcc/types.h14
-rw-r--r--bootblocks/Makefile14
-rw-r--r--bootblocks/bzimage.c197
-rw-r--r--bootblocks/fs.c81
-rw-r--r--bootblocks/fs_dos.c (renamed from bootblocks/dosfs.c)291
-rw-r--r--bootblocks/fs_min.c31
-rw-r--r--bootblocks/fs_tar.c156
-rw-r--r--bootblocks/i86_funcs.c1
-rw-r--r--bootblocks/makeboot.c348
-rw-r--r--bootblocks/mbr.s5
-rw-r--r--bootblocks/monitor.c85
-rw-r--r--bootblocks/msdos.s48
-rw-r--r--bootblocks/nofs.c55
-rw-r--r--bootblocks/readfs.h27
-rw-r--r--bootblocks/relocate.c27
-rw-r--r--bootblocks/standalone.c1
-rw-r--r--bootblocks/sysboot.s4
-rw-r--r--bootblocks/tarboot.s4
-rw-r--r--bootblocks/trk_buf.c275
-rw-r--r--bootblocks/unix.c137
-rw-r--r--copt/copt.c72
-rw-r--r--copt/copt.diff72
-rw-r--r--copt/rules.868
-rw-r--r--copt/rules.end2
-rw-r--r--elksemu/elks.c24
-rw-r--r--elksemu/elks_sys.c30
-rw-r--r--ld/Makefile6
-rw-r--r--ld/dumps.c24
-rw-r--r--ld/io.c48
-rw-r--r--ld/objchop.c2
-rw-r--r--ld/objdump86.c681
-rw-r--r--ld/syshead.h2
-rw-r--r--ld/type.h1
-rw-r--r--ld/writex86.c80
-rw-r--r--ld/x1
-rw-r--r--libc/Config_sh4
-rw-r--r--libc/Makefile7
-rw-r--r--libc/bios/Makefile2
-rw-r--r--libc/bios/bios_vid.c7
-rw-r--r--libc/bios/time.c127
-rw-r--r--libc/error/sys_errlist.c13
-rw-r--r--libc/getent/pwent.c2
-rw-r--r--libc/include/asm/limits.h16
-rw-r--r--libc/include/dos.h1
-rw-r--r--libc/kinclude/Config2
-rw-r--r--libc/misc/Makefile2
-rw-r--r--libc/misc/crypt.c45
-rw-r--r--libc/misc/tmpnam.c50
-rw-r--r--libc/msdos/Makefile2
-rw-r--r--libc/msdos/i86.c50
-rw-r--r--libc/msdos/time.c2
-rw-r--r--libc/msdos/xxx/KEYTEST.C575
-rw-r--r--libc/msdos/xxx/KEYTEST.EXEbin0 -> 12236 bytes
-rw-r--r--libc/msdos/xxx/KEYTEST.OBJbin0 -> 5567 bytes
-rw-r--r--libc/msdos/xxx/TALK.C3931
-rw-r--r--libc/msdos/xxx/TALK.EXEbin0 -> 23166 bytes
-rw-r--r--libc/msdos/xxx/ZIP.COMbin0 -> 16336 bytes
-rw-r--r--libc/msdos/xxx/comx.combin0 -> 7772 bytes
-rw-r--r--libc/msdos/xxx/cpu.combin0 -> 4824 bytes
-rw-r--r--libc/msdos/xxx/list.combin0 -> 25927 bytes
-rw-r--r--libc/msdos/xxx/mail-to-lasu.html105
-rw-r--r--libc/msdos/xxx/mailfilter-mh.html86
-rw-r--r--libc/msdos/xxx/mailfilter.html153
-rw-r--r--libc/msdos/xxx/mailfilter2.tar.gzbin0 -> 7104 bytes
-rw-r--r--libc/msdos/xxx/mips.combin0 -> 13312 bytes
-rw-r--r--libc/msdos/xxx/tryit.combin0 -> 3504 bytes
-rw-r--r--libc/stdio2/stdio.c54
-rw-r--r--libc/string/string.c2
-rw-r--r--libc/syscall/Makefile9
-rw-r--r--libc/syscall/TODO2
-rw-r--r--libc/syscall/dirent.c28
-rw-r--r--libc/syscall/exec.c4
-rw-r--r--libc/syscall/mkentry.sh83
-rw-r--r--libc/syscall/mksyscall31
-rw-r--r--libc/syscall/syscall.dat142
-rw-r--r--libc/syscall/syscall.dev86160
-rw-r--r--makefile.in38
-rw-r--r--man/as86.12
-rw-r--r--man/bcc.118
-rw-r--r--man/ld86.12
116 files changed, 8248 insertions, 1074 deletions
diff --git a/Changes b/Changes
index d141964..28cef57 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,24 @@
+For version 0.14.0.
+
+> Objdump86 utility added, also includes nm86 and size86 that work on
+ as86's object files and elks executables.
+
+> Added ability to put ELKSSRC=/././. on initial make command line.
+
+> Some bug fixes and buffering improvements for stdio2.
+
+> Changed output of linker -m option to be more verbose (useful).
+
+> Linker errors are now directed to STDERR on unix/elks.
+
+> Alterations to elksemu and the C library to be closer to elks, 0.13.1+
+ should not need a patch to work with 0.0.60+ ELKS.
+
+> Link symbol dump now flags local variables differently to exported.
+
+> Fixes for libc/misc/crypt.c, they do change the values of the encrypted
+ password so beware.
+
For version 0.13.0.
> Removed too eager 'typeconv.c' warning.
@@ -177,7 +198,7 @@ For version 0.0.10.
standalone executable to be executed from an msdos floppy. Makeboot
can also install several other types of bootblock.
-> Monitor.out not includes 'bzimage' command, which will boot a Linux-i386
+> Monitor.out now includes 'bzimage' command, which will boot a Linux-i386
bzImage with command line and initrd.
> 'skip.s' bootblock fixed.
diff --git a/Contributors b/Contributors
index 976e69e..33398b4 100644
--- a/Contributors
+++ b/Contributors
@@ -7,8 +7,8 @@ the master files.
Robert de Bath <robert@mayday.cix.co.uk>
-The files are available at linux.mit.edu with pointers and yesterday's
-patch file available via http://www.cix.co.uk/~mayday
+The files are available at linux.mit.edu with the source and yesterday's
+patch file available via http://poboxes.com/rdebath
We're all available through the Linux-8086 mailing list at:
linux-8086@vger.rutgers.edu
@@ -23,8 +23,11 @@ Finally the list itself, if you're missing send me a patch :-)
Alan Cox <alan@cymru.net>
Nat Friedman <ndf@aleph1.mit.edu>
Steven Huang <sthuang@hns.com>
+Steffen Kaiser <Steffen.Kaiser@fh-rhein-sieg.de>
+Shane Kerr <kerr@wizard.net>
Gero Kuhlmann <gero@gkminix.han.de>
Chad Page <page0588@sundance.sjsu.edu>
Dick Porter <dick@cymru.net>
Dale Schumacher <dal@syntel.UUCP>
+Wietse Venema <wietse@wzv.win.tue.nl>
Joel Weber II <nemo@koa.iolani.honolulu.hi.us>
diff --git a/Libc_version b/Libc_version
index 54d1a4f..c37136a 100644
--- a/Libc_version
+++ b/Libc_version
@@ -1 +1 @@
-0.13.0
+0.13.5
diff --git a/MAGIC b/MAGIC
index 319751e..42710b3 100644
--- a/MAGIC
+++ b/MAGIC
@@ -13,7 +13,7 @@ Useful bits for /etc/magic:
>28 long !0 not stripped
#
0 string \243\206\001\0 Linux-8086 object file
-# There is _no_ difference between 16 and 32 bit .o files
+# There is _no_ difference between 16 and 32 bit .o files that file can see.
#
0 string \01\03\020\20 Minix-386 impure executable
>28 long !0 not stripped
diff --git a/Makefile b/Makefile
index a57731e..4ba277d 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,7 @@ TARGETS= \
all-libs alt-libs library lib-386 lib-bsd lib-dos lib-fast lib-stand \
config other tests dis88 doselks bootblocks ld86r
+ELKSSRC= /usr/src/elks
PREFIX= /usr/bcc
BINDIR= /usr/bin
LIBDIR= $(PREFIX)/lib/bcc
@@ -36,6 +37,7 @@ make.fil: ifdef makefile.in
sed -e "s:%PREFIX%:$(PREFIX):" \
-e "s:%BINDIR%:$(BINDIR):" \
-e "s:%LIBDIR%:$(LIBDIR):" \
+ -e "s:%ELKSSRC%:$(ELKSSRC):" \
-e "s:%CC%:$(CC):" \
-e "s:%CFLAGS%:$(CFLAGS):" \
-e "s:%LDFLAGS%:$(LDFLAGS):" \
@@ -57,6 +59,7 @@ Uninstall: phony
rm -rf /usr/bcc
rm -f $(BINDIR)/bcc $(BINDIR)/as86_encap $(BINDIR)/dis86
rm -f $(BINDIR)/as86 $(BINDIR)/ld86
+ rm -f $(BINDIR)/objdump86 $(BINDIR)/nm86 $(BINDIR)/size86
rm -f /lib/elksemu
rm -f /usr/lib/liberror.txt
rm -f /usr/man/man1/elks.1* /usr/man/man1/elksemu.1*
@@ -67,21 +70,33 @@ Uninstall: phony
distribution:
@rm -f /tmp/linux-86 || true
@[ ! -f Copy_dist ] || sh Copy_dist
- mkdir -p /tmp/Dist
+ mkdir -p -m 0777 /tmp/Dist
[ -d /tmp/linux-86 ] || ln -s `pwd` /tmp/linux-86
cd /tmp &&\
$(MAKE) -C linux-86 realclean &&\
$(MAKE) -C linux-86/libc Libc_version &&\
VER=`cat linux-86/Libc_version` &&\
- tar cf Dist/Dev86src-$$VER.tar linux-86/* &&\
+ tar cf Dist/Dev86src-$$VER.tar linux-86/*
+ gzip -f9 /tmp/Dist/Dev86src-*.tar &
+
+ cd /tmp &&\
+ VER=`cat linux-86/Libc_version` &&\
ln -s linux-86/as as86 &&\
cp -p linux-86/man/as86.1 as86/as86.1 &&\
cp -p linux-86/COPYING as86/COPYING &&\
tar cf Dist/as86-$$VER.tar `find as86/* -prune -type f` &&\
- rm as86/as86.1 as86 &&\
+ rm as86/as86.1 as86
+ gzip -f9 /tmp/Dist/as86-*.tar &
+
+ cd /tmp &&\
+ VER=`cat linux-86/Libc_version` &&\
ln -s linux-86/libc libc-$$VER &&\
tar cf Dist/libc-8086-$$VER.tar libc-$$VER/* &&\
- rm libc-$$VER &&\
+ rm libc-$$VER
+ gzip -f9 /tmp/Dist/libc-8086-*.tar &
+
+ cd /tmp &&\
+ VER=`cat linux-86/Libc_version` &&\
$(MAKE) -C /tmp/linux-86 install \
ARFLAGS=q DIST=/tmp/linux-86-dist ELKSSRC=/dev/null &&\
$(MAKE) -C /tmp/linux-86 other &&\
@@ -94,5 +109,5 @@ distribution:
Bcc/lib/i386/crt0.o Bcc/lib/i386/libc.a &&\
rm Bcc
- gzip -v9f /tmp/Dist/*.tar
+ gzip -v9f /tmp/Dist/Dev86bin-*.tar
@rm /tmp/linux-86 || true
diff --git a/README b/README
index 52380d2..95afbe8 100644
--- a/README
+++ b/README
@@ -14,13 +14,16 @@ If you don't want it to install some bits in /usr/bin you can override
the bindir on the first make ie: 'make BINDIR=/usr/local/bin' this
is remembered until 'make.fil' is rebuilt.
-The manual pages in the man subdirectory are a start as some pages matched
-to these programs, there are also some hints for using as86 well.
-The tests and bootblocks directories give some example code.
+The manual pages in the man subdirectory are matched to these programs,
+there are also some hints for using as86 well. The tests and bootblocks
+directories give some example code.
-The bcc command defaults to using /usr/bcc/include and /usr/bcc/lib the
-libraries _and_ include files are copied to these locations by install.
-This can be changed by overriding 'PREFIX=...' on the initial make.
+The bcc command defaults to using /usr/bcc/include and /usr/bcc/lib/bcc
+the libraries _and_ include files are copied to these locations by
+install. This can be changed by overriding 'PREFIX=/usr/bcc' or
+'LIBDIR=/usr/bcc/lib/bcc' on the initial make. Also available in the
+same way the 'ELKSSRC=/usr/src/elks' variable can be altered if you
+have ELKS on a different path.
All the versions of the library are built by make; 'normal', 'fast',
'MSDOS', 'standalone' and Linux-i386.
@@ -47,7 +50,7 @@ work correctly here!
I _strongly_ suggest you install the kernel patch or load the module in
the elksemu directory in your Linux-i386 kernel, it makes things _much_
-easier. If you're using a post 2.1.43 kernel the modeule you need is
+easier. If you're using a post 2.1.43 kernel the module you need is
the binfmt_misc driver as described in elksemu/README.
(All the options need the elksemu executable installed correctly)
@@ -58,9 +61,12 @@ the GPL. The `bccfp' library now in the libc/i386fp directory is under
the LGPL. (Copyright holder Bruce Evans)
The contents of the libc and libbsd subdirectories are under the LGPL
-with a few noted exceptions. The programs in 'tests', elksemu, copt and
-the bootblocks directory are under the GPL. Dis88 and unproto are freely
-distributable if the source is distributed also.
+with a few noted exceptions. The programs in 'tests', elksemu, copt
+and the bootblocks directory are under the GPL. Dis88 is freely
+distributable if the source is distributed also. Unproto is freely
+distributable as long as Wietse Venema <wietse@wzv.win.tue.nl> and the
+"Mathematics and Computing Science Dept. Eindhoven University of
+Technology. The Netherlands." is given credit.
In libc the regular expression routine and the printf/scanf functions are
not under LGPL, the former is 'freely distributable' the latter is public
@@ -70,4 +76,4 @@ See the COPYING file in this directory for the GPL and the COPYING file
in the libc directories for the LGPL.
--
-Rob. (Robert de Bath <robert@mayday.cix.co.uk>)
+Rob. (Robert de Bath <rdebath@poboxes.com>)
diff --git a/as/as.c b/as/as.c
index 8f45f40..4bf76c7 100644
--- a/as/as.c
+++ b/as/as.c
@@ -68,6 +68,7 @@ char **argv;
last_pass=1;
process_args(argc, argv);
initscan();
+ ptext();
assemble(); /* doesn't return, maybe use setjmp */
@@ -256,6 +257,13 @@ char **argv;
--argc;
++argv;
break;
+ case 't':
+ if (!isnextarg || binfil != 0)
+ usage();
+ textseg = atoi(nextarg);
+ --argc;
+ ++argv;
+ break;
case 'u':
if( flag_state ) inidata = IMPBIT | SEGM;
else inidata = 0;
diff --git a/as/as86_encap.sh b/as/as86_encap.sh
index e5cf9e7..6bad886 100644
--- a/as/as86_encap.sh
+++ b/as/as86_encap.sh
@@ -57,10 +57,10 @@ $LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
if( flg == 1 )
{
if( !started )
- printf "int %s = 0;\n", sname;
+ printf "#define %s 0\n", sname;
printf "\n";
- printf "char %sdata[] = {\n", prefix;
+ printf "static char %sdata[] = {\n", prefix;
bincount=0;
}
next;
@@ -70,12 +70,12 @@ $LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
if( substr($2,1,4) == "0000" ) $2=substr($2,5);
if( $1 == "+" && $4 == "$start" )
{
- printf "int %s = 0x%s;\n", sname, $2;
+ printf "#define %s 0x%s\n", sname, $2;
started = 1;
}
else if( substr($3, 1, 1) == "E" && $4 != "start" && $4 != "size" && $4 != "data" )
{
- printf "int %s%s = 0x%s;\n", prefix, $4, $2;
+ printf "#define %s%s 0x%s\n", prefix, $4, $2;
}
next;
}
@@ -93,7 +93,7 @@ $LIBDIR/as86 "$@" "$IFILE" -b _$$.bin -s _$$.sym || RV=$?
}
END {
printf "};\n\n";
- printf "int %ssize = %d;\n", prefix, bincount;
+ printf "#define %ssize %d\n", prefix, bincount;
}
'
RV=$?
diff --git a/as/globvar.h b/as/globvar.h
index aed6aed..df4ed6e 100644
--- a/as/globvar.h
+++ b/as/globvar.h
@@ -83,6 +83,8 @@ EXTERN unsigned char pcrflag; /* OBJ_RMASK set if addressing is PC-relative */
EXTERN int last_pass; /* Pass number of last pass */
EXTERN int dirty_pass; /* Set if this pass had a label movement */
+EXTERN int textseg; /* Text segment id */
+
#ifdef I80386
EXTERN opcode_t aprefix; /* address size prefix or 0 */
diff --git a/as/pops.c b/as/pops.c
index e239892..c9aba90 100644
--- a/as/pops.c
+++ b/as/pops.c
@@ -983,7 +983,10 @@ PUBLIC void psetdp()
PUBLIC void ptext()
{
- setloc(TEXTLOC);
+ if( textseg <= 0 )
+ setloc(TEXTLOC);
+ else
+ setloc(BSSLOC+textseg);
}
/* .WARN pseudo-op */
diff --git a/as/readsrc.c b/as/readsrc.c
index 557ca5d..80c62f2 100644
--- a/as/readsrc.c
+++ b/as/readsrc.c
@@ -253,6 +253,7 @@ PUBLIC void pproceof()
maclevel = iflevel = blocklevel =
totwarn = toterr = linum = macnum = 0;
initp1p2(); /* reset other varaiables */
+ ptext();
if(pass==last_pass)
binaryc = binaryg;
#ifdef I80386
diff --git a/bcc/align.h b/bcc/align.h
index 2fce75d..422471b 100644
--- a/bcc/align.h
+++ b/bcc/align.h
@@ -12,4 +12,4 @@
# endif
#endif
-extern uoffset_t alignmask; /* general alignment mask */
+extern uoffset_T alignmask; /* general alignment mask */
diff --git a/bcc/assign.c b/bcc/assign.c
index 977d23e..f7e2853 100644
--- a/bcc/assign.c
+++ b/bcc/assign.c
@@ -12,7 +12,7 @@
FORWARD void blockmove P((struct symstruct *source, struct symstruct *target));
FORWARD void call3 P((char *funcname, struct symstruct *target,
- struct symstruct *source, uoffset_t size));
+ struct symstruct *source, uoffset_T size));
FORWARD void fconvert P((struct symstruct *source, struct typestruct *type));
PUBLIC void assign(source, target)
@@ -129,7 +129,7 @@ struct symstruct *source;
struct symstruct *target;
{
struct symstruct oldtarget;
- uoffset_t typesize;
+ uoffset_T typesize;
struct symstruct worksource;
oldtarget = *target;
@@ -176,10 +176,10 @@ PRIVATE void call3(funcname, target, source, size)
char *funcname;
struct symstruct *target;
struct symstruct *source;
-uoffset_t size;
+uoffset_T size;
{
store_pt regpushed;
- offset_t spmark;
+ offset_T spmark;
struct symstruct *length;
pushlist(regpushed = reguse & ~calleemask);
@@ -203,9 +203,9 @@ struct typestruct *type;
struct symstruct *target;
{
scalar_t newscalar;
- uoffset_t newsize;
+ uoffset_T newsize;
scalar_t oldscalar;
- uoffset_t oldsize;
+ uoffset_T oldsize;
store_pt targreg;
if (type->constructor & (ARRAY | FUNCTION)
@@ -356,7 +356,7 @@ PRIVATE void fconvert(source, type)
struct symstruct *source;
struct typestruct *type;
{
- offset_t spmark;
+ offset_T spmark;
pushlist(reguse & OPREG);
spmark = sp;
diff --git a/bcc/bcc.c b/bcc/bcc.c
index 1200926..643f766 100644
--- a/bcc/bcc.c
+++ b/bcc/bcc.c
@@ -45,7 +45,7 @@
#define EXESUF
#endif
-#if defined(__minix) || defined(_AIX) || defined(__BCC__)
+#if defined(__minix) || defined(__BCC__)
#define realpath(x,y) 0
#endif
@@ -57,7 +57,6 @@
#define CC1_MINUS_O_BROKEN FALSE
#define CPP "bcc-cc1" EXESUF
#define CPPFLAGS "-E"
-#define CRT0 "crt0.o"
#define GCC "gcc"
#define LD "ld86" EXESUF
#define UNPROTO "unproto" EXESUF
@@ -135,15 +134,6 @@ PRIVATE struct arg_s ccargs = { CC1, CC1_MINUS_O_BROKEN, };
PRIVATE struct arg_s cppargs = { CPP, };
PRIVATE struct arg_s unprotoargs = { UNPROTO, TRUE };
PRIVATE struct arg_s optargs = { OPTIM };
-#ifdef STANDARD_CRT0_PREFIX
-PRIVATE struct prefix_s crt0_prefix = { STANDARD_CRT0_PREFIX, };
-#endif
-#ifdef STANDARD_CRT0_0_PREFIX
-PRIVATE struct prefix_s crt0_0_prefix = { STANDARD_CRT0_0_PREFIX, };
-#endif
-#ifdef STANDARD_CRT0_3_PREFIX
-PRIVATE struct prefix_s crt0_3_prefix = { STANDARD_CRT0_3_PREFIX, };
-#endif
PRIVATE struct prefix_s exec_prefix;
PRIVATE struct arg_s ldargs = { LD, };
#ifdef BAS86
@@ -201,7 +191,6 @@ FORWARD void startarg P((struct arg_s *argp));
FORWARD char *stralloc P((char *s));
FORWARD char *stralloc2 P((char *s1, char *s2));
FORWARD void trap P((int signum));
-FORWARD void unsupported P((char *option, char *message));
FORWARD void writen P((void));
FORWARD void writes P((char *s));
FORWARD void writesn P((char *s));
@@ -233,21 +222,18 @@ char **argv;
#else
bool_T cpp_pass = FALSE;
#endif
-#ifdef BCC86
- char *crt0;
-#endif
char *libc = "-lc";
#ifdef MSDOS
char major_mode = 'd';
#else
char major_mode = 0;
#endif
+ bool_T has_crt0 = TRUE;
bool_T debug = FALSE;
bool_T echo = FALSE;
unsigned errcount = 0;
char ext;
char *f_out = NUL_PTR;
- bool_T float_emulation = FALSE;
#ifdef BAS86
bool_T gnu_objects = FALSE;
#endif
@@ -263,6 +249,7 @@ char **argv;
bool_T profile = FALSE;
bool_T prep_only = FALSE;
bool_T prep_line_numbers = FALSE;
+ bool_T compiler_warnings = TRUE;
int status;
char *temp;
bool_T patch_exe = FALSE; /* Hackish patch to convert minix i386->OMAGIC */
@@ -334,13 +321,8 @@ char **argv;
case 'e':
cpp_pass = TRUE;
break;
- case 'f':
- float_emulation = TRUE;
- ++errcount;
- unsupported(arg, "float emulation");
- break;
case 'g':
- debug = TRUE; /* unsupported( arg, "debug" ); */
+ debug = TRUE; /* unsupported */
break;
case 'o':
if (argc <= 1)
@@ -359,15 +341,20 @@ char **argv;
break;
case 'p':
profile = TRUE;
- ++errcount;
- unsupported(arg, "profile");
break;
case 'v':
++verbosity;
break;
+ case 'w':
+ compiler_warnings = FALSE;
+ aswarn = FALSE;
+ break;
case 'W':
aswarn = TRUE;
break;
+ case 'x':
+ has_crt0 = FALSE;
+ break;
case 'I':
add_default_inc = 0;
break;
@@ -391,6 +378,10 @@ char **argv;
adddefine("-D__STDC__=0");
}
break;
+ case 't':
+ addarg(&asargs, "-t");
+ addarg(&asargs, arg+2);
+ break;
case 'A':
addarg(&asargs, arg + 2);
break;
@@ -436,10 +427,6 @@ char **argv;
case 'T':
tmpdir = arg + 2;
break;
- case 't':
- ++errcount;
- unsupported(arg, "pass number");
- break;
default:
*argdone = FALSE;
break;
@@ -486,7 +473,6 @@ char **argv;
libc= "-ldos";
adddefine("-D__MSDOS__");
addarg(&ldargs, "-d");
- addarg(&ldargs, "-s");
addarg(&ldargs, "-T100");
break;
@@ -525,7 +511,11 @@ char **argv;
libc= "-lc";
adddefine("-D__linux__");
adddefine("-D__unix__");
+#ifdef __linux__
addarg(&ldargs, "-N"); /* Make OMAGIC */
+#else
+ patch_exe = TRUE;
+#endif
break;
case '?':
@@ -598,16 +588,10 @@ char **argv;
#ifdef BCC86
#ifdef STANDARD_CRT0_3_PREFIX
if (bits32)
- {
bits_arg = "-3";
- crt0 = fixpath(CRT0, &crt0_3_prefix, R_OK);
- }
else
#endif
- {
bits_arg = "-0";
- crt0 = fixpath(CRT0, &crt0_0_prefix, R_OK);
- }
addarg(&ccargs, bits_arg);
addarg(&cppargs, bits_arg);
addarg(&asargs, bits_arg);
@@ -616,15 +600,11 @@ char **argv;
{
addarg(&ldargs, bits_arg);
addarg(&ldrargs, bits_arg);
- /* addarg(&ldargs, crt0);*/
- addarg(&ldargs, "-C0");
+ if( has_crt0 )
+ addarg(&ldargs, "-C0");
}
#endif /* BAS86 */
#endif /* BCC86 */
-#if defined(BAS86) && !defined(BCC86)
- if (!gnu_objects)
- addarg(&ldargs, fixpath(CRT0, &crt0_prefix, R_OK));
-#endif
set_trap();
/* Pass 2 over argv to compile and assemble .c, .i, .S and .s files and
@@ -839,15 +819,19 @@ char * fname;
{
/* OMAGIC */
-#define AOUT_MAG 0x640107L
-#define ELKS_MAG1 0x1010
-#define ELKS_MAG2 0x1011 /* -z */
-#define ELKS_MAG3 0x1020 /* -i */
-#define ELKS_MAG4 0x1021 /* -i -z */
+#define AOUT_MAG "\x07\x01\x64\x00" /* 0x640107L */
+#define ELKS_MAG1 0x10
+#define ELKS_MAG2 0x11 /* -z */
+#define ELKS_MAG3 0x20 /* -i */
+#define ELKS_MAG4 0x21 /* -i -z */
static struct ELKS_exec { /* ELKS a.out header */
- long a_magic; /* magic number */
- long a_hdrlen; /* length, etc of header */
+ char a_magic1; /* magic number */
+ char a_magic2; /* magic number */
+ char a_magic3; /* magic number */
+ char a_magic4; /* magic number */
+ char a_hdrlen; /* length, etc of header */
+ char a_hdrlen3[3];
long a_text; /* size of text segement in bytes */
long a_data; /* size of data segment in bytes */
long a_bss; /* size of bss segment in bytes */
@@ -858,7 +842,7 @@ static struct ELKS_exec { /* ELKS a.out header */
static struct aout_exec {
- unsigned long a_info; /* Use macros N_MAGIC, etc for access */
+ char a_info[4]; /* Use macros N_MAGIC, etc for access */
unsigned a_text; /* length of text, in bytes */
unsigned a_data; /* length of data, in bytes */
unsigned a_bss; /* length of uninitialized data area, in bytes */
@@ -879,32 +863,33 @@ static struct aout_exec {
return;
}
- if( instr.a_hdrlen != 0x20 || (instr.a_magic & 0xFFFF) != 0x0301 )
+ if( instr.a_hdrlen != 0x20 || instr.a_magic1 != 0x01 ||
+ instr.a_magic2 != 0x03 || instr.a_magic4 != 0x10 )
{
- writesn("Executable cannot be converted to OMAGIC");
+ writesn("Executable cannot be converted to OMAGIC - bad magics");
return;
}
- switch((int)(instr.a_magic >> 16))
+ switch((int)(instr.a_magic3))
{
case ELKS_MAG1:
- outstr.a_info = AOUT_MAG;
break;
case ELKS_MAG2:
- writesn("Executable cannot be converted to OMAGIC");
+ writesn("Executable cannot be converted to OMAGIC (compiled with -z)");
return;
case ELKS_MAG3:
case ELKS_MAG4:
writesn("Executable file is split I/D, data overlaps text");
return;
default:
- writesn("Executable cannot be converted to OMAGIC");
+ writesn("Executable cannot be converted to OMAGIC (unknown type)");
return;
}
if( instr.a_syms != 0 )
writesn("Warning: executable file isn't stripped");
+ memcpy(outstr.a_info, AOUT_MAG, 4);
outstr.a_text = instr.a_text;
outstr.a_data = instr.a_data;
outstr.a_bss = instr.a_bss;
@@ -1337,17 +1322,6 @@ int signum;
fatal("");
}
-PRIVATE void unsupported(option, message)
-char *option;
-char *message;
-{
- show_who("compiler option ");
- writes(option);
- writes(" (");
- writes(message);
- writesn(") not supported yet");
-}
-
PRIVATE void writen()
{
writes("\n");
diff --git a/bcc/codefrag.c b/bcc/codefrag.c
index 0423a44..e4359bb 100644
--- a/bcc/codefrag.c
+++ b/bcc/codefrag.c
@@ -121,12 +121,12 @@ PRIVATE void adjcarry()
{
outop3str("rcl\t");
outregname(DXREG);
- outncimmadr((offset_t) 9);
+ outncimmadr((offset_T) 9);
outand();
bumplc2();
bumplc2();
outregname(DXREG);
- outncimmadr((offset_t) 0x100);
+ outncimmadr((offset_T) 0x100);
}
PUBLIC void clrBreg()
{
@@ -608,22 +608,22 @@ PUBLIC void adc0()
{
outadc();
outhiaccum();
- outncimmadr((offset_t) 0);
+ outncimmadr((offset_T) 0);
}
}
/* add constant to register */
PUBLIC void addconst(offset, reg)
-offset_t offset;
+offset_T offset;
store_pt reg;
{
#ifdef I8088
#ifdef I80386
- if ((i386_32 && (uoffset_t) offset + 1 <= 2) /* do -1 to 1 by dec/inc */
- || (!i386_32 && (uoffset_t) offset + 2 <= 4)) /* do -2 to 2 */
+ if ((i386_32 && (uoffset_T) offset + 1 <= 2) /* do -1 to 1 by dec/inc */
+ || (!i386_32 && (uoffset_T) offset + 2 <= 4)) /* do -2 to 2 */
#else
- if ((uoffset_t) offset + 2 <= 4) /* do -2 to 2 */
+ if ((uoffset_T) offset + 2 <= 4) /* do -2 to 2 */
#endif
{
if (reg == ALREG)
@@ -668,7 +668,7 @@ store_pt reg;
/* adjust lc for signed offset */
PUBLIC void adjlc(offset, reg)
-offset_t offset;
+offset_T offset;
store_pt reg;
{
if (!(reg & CHARREGS))
@@ -704,7 +704,7 @@ label_no label;
else
{
outplus();
- outhex((uoffset_t) - sp);
+ outhex((uoffset_T) - sp);
}
#ifdef MC6809
outcregname(LOCAL);
@@ -719,18 +719,18 @@ label_no label;
/* and accumulator with constant */
PUBLIC void andconst(offset)
-offset_t offset;
+offset_T offset;
{
char_t botbits;
- uoffset_t topbits;
+ uoffset_T topbits;
- if ((topbits = offset & ~(uoffset_t) CHMASKTO & intmaskto) != 0 &&
- topbits != (~(uoffset_t) CHMASKTO & intmaskto))
+ if ((topbits = offset & ~(uoffset_T) CHMASKTO & intmaskto) != 0 &&
+ topbits != (~(uoffset_T) CHMASKTO & intmaskto))
/* if topbits == 0, callers reduce the type */
{
#ifdef OP1
outandhi();
- outncimmadr((offset_t) (topbits >> (INT16BITSTO - CHBITSTO)));
+ outncimmadr((offset_T) (topbits >> (INT16BITSTO - CHBITSTO)));
#else
outandac();
#ifdef I80386
@@ -746,7 +746,7 @@ offset_t offset;
else if (botbits != CHMASKTO)
{
outandlo();
- outncimmadr((offset_t) botbits);
+ outncimmadr((offset_T) botbits);
}
}
@@ -805,7 +805,7 @@ PUBLIC label_no casejump()
PRIVATE void clr(reg)
store_pt reg;
{
- loadconst((offset_t) 0, reg);
+ loadconst((offset_T) 0, reg);
}
/* define common storage */
@@ -838,19 +838,19 @@ PUBLIC void cseg()
/* define long */
PUBLIC void deflong(value)
-uoffset_t value;
+uoffset_T value;
{
- uoffset_t longhigh;
- uoffset_t longlow;
+ uoffset_T longhigh;
+ uoffset_T longlow;
- longlow = value & (uoffset_t) intmaskto;
+ longlow = value & (uoffset_T) intmaskto;
#ifdef I80386
if (i386_32)
defdword();
else
#endif
{
- longhigh = (value >> INT16BITSTO) & (uoffset_t) intmaskto;
+ longhigh = (value >> INT16BITSTO) & (uoffset_T) intmaskto;
defword();
#if DYNAMIC_LONG_ORDER
if (long_big_endian)
@@ -875,7 +875,7 @@ uoffset_t value;
/* define null storage */
PUBLIC void defnulls(nullcount)
-uoffset_t nullcount;
+uoffset_T nullcount;
{
if (nullcount != 0)
{
@@ -946,7 +946,7 @@ bool_pt dataflag;
{
if (count < DEFSTR_BYTEMAX - 1)
outcomma(); /* byte separator */
- outhex((uoffset_t) byte);
+ outhex((uoffset_T) byte);
byte = (unsigned char) *sptr++;
}
outnl();
@@ -1044,7 +1044,7 @@ char *string;
PUBLIC void equlab(label, offset)
label_no label;
-offset_t offset;
+offset_T offset;
{
outbyte(LOCALSTARTCHAR);
outlabel(label);
@@ -1092,7 +1092,7 @@ store_pt reg;
clr(reg);
testhi();
sbranch(GE, exitlab = getlabel());
- loadconst((offset_t) - 1, reg);
+ loadconst((offset_T) - 1, reg);
outnlabel(exitlab);
#endif
}
@@ -1124,7 +1124,7 @@ char *name;
/* load effective address */
PUBLIC void lea(offset, sourcereg, targreg)
-offset_t offset;
+offset_T offset;
store_pt sourcereg;
store_pt targreg;
{
@@ -1140,7 +1140,7 @@ store_pt targreg;
/* load constant into given register */
PUBLIC void loadconst(offset, reg)
-offset_t offset;
+offset_T offset;
store_pt reg;
{
#ifdef I8088
@@ -1304,7 +1304,7 @@ bool_pt uflag;
{
if (sign)
negDreg();
- andconst((offset_t) divisor); /* if original divisor 0, this is
+ andconst((offset_T) divisor); /* if original divisor 0, this is
null */
if (sign)
negDreg();
@@ -1440,7 +1440,7 @@ PUBLIC void outhiaccum()
/* print immediate address */
PUBLIC void outimmadr(offset)
-offset_t offset;
+offset_T offset;
{
#ifdef I8088
if (!isbyteoffset(offset))
@@ -1456,7 +1456,7 @@ offset_t offset;
/* print register, comma, immediate address and adjust lc */
PUBLIC void outimadj(offset, targreg)
-offset_t offset;
+offset_T offset;
store_pt targreg;
{
outregname(targreg);
@@ -1492,7 +1492,7 @@ char *name;
/* print separator, immediate address, newline */
PUBLIC void outncimmadr(offset)
-offset_t offset;
+offset_T offset;
{
#ifdef I8088
outcomma();
@@ -1507,7 +1507,7 @@ offset_t offset;
/* print signed offset and adjust lc */
PUBLIC void outoffset(offset)
-offset_t offset;
+offset_T offset;
{
#ifdef MC6809
if (!is5bitoffset(offset))
@@ -1595,7 +1595,7 @@ PUBLIC void sbc0()
{
outsbc();
outhiaccum();
- outncimmadr((offset_t) 0);
+ outncimmadr((offset_T) 0);
}
}
@@ -1603,7 +1603,7 @@ PUBLIC void sbc0()
PUBLIC void set(name, value)
char *name;
-offset_t value;
+offset_T value;
{
outccname(funcname);
outbyte(LOCALSTARTCHAR);
@@ -1644,7 +1644,7 @@ store_pt reg;
if (shift != 1)
bumplc();
outregname(reg);
- outncimmadr((offset_t) shift);
+ outncimmadr((offset_T) shift);
}
return;
}
@@ -1666,7 +1666,7 @@ store_pt reg;
outload();
outregname(SHIFTREG);
outcomma();
- outimmadr((offset_t) shift);
+ outimmadr((offset_T) shift);
outnl();
outsl();
outregname(reg);
@@ -1698,7 +1698,7 @@ bool_pt uflag;
if (shift != 1)
bumplc();
outaccum();
- outncimmadr((offset_t) shift);
+ outncimmadr((offset_T) shift);
}
return;
}
@@ -1728,7 +1728,7 @@ bool_pt uflag;
outload();
outregname(SHIFTREG);
outcomma();
- outimmadr((offset_t) shift);
+ outimmadr((offset_T) shift);
outnl();
if ((bool_t) uflag)
outusr();
diff --git a/bcc/debug.c b/bcc/debug.c
index 9e97ae7..e437f78 100644
--- a/bcc/debug.c
+++ b/bcc/debug.c
@@ -113,7 +113,7 @@ struct symstruct *item;
break;
default:
outstr("bad storage (");
- outhex((uoffset_t) item->storage);
+ outhex((uoffset_T) item->storage);
outbyte(')');
outstr(" offset ");
}
diff --git a/bcc/declare.c b/bcc/declare.c
index 1c9b43a..73a8524 100644
--- a/bcc/declare.c
+++ b/bcc/declare.c
@@ -33,7 +33,7 @@ FORWARD void declarator P((void));
FORWARD void declarg P((void));
FORWARD struct typestruct *declenum P((void));
FORWARD void declfunc P((void));
-FORWARD void declselt P((struct typestruct *structype, offset_t *psoffset,
+FORWARD void declselt P((struct typestruct *structype, offset_T *psoffset,
struct typelist ** ptypelist));
FORWARD bool_pt declspec P((void));
FORWARD struct typestruct *declsu P((void));
@@ -89,7 +89,7 @@ PUBLIC void decllist()
PRIVATE void declaf()
{
- uoffset_t asize;
+ uoffset_T asize;
bool_t levelnew;
#ifdef TESTING_PROTOTYPES
char ogvarname[NAMESIZE];
@@ -253,7 +253,7 @@ PRIVATE struct typestruct *declenum()
{
register struct symstruct *esymptr;
register struct typestruct *enumtype;
- offset_t ordinal;
+ offset_T ordinal;
nextsym();
if (sym != IDENT && sym != TYPEDEFNAME)
@@ -314,13 +314,13 @@ PRIVATE struct typestruct *declenum()
PRIVATE void declselt(structype, psoffset, ptypelist)
struct typestruct *structype;
-offset_t *psoffset;
+offset_T *psoffset;
struct typelist **ptypelist;
{
struct typestruct *basetype;
value_t fieldwidth;
value_t fwidth;
- offset_t offset;
+ offset_T offset;
scalar_t scalar=0;
offset = *psoffset;
@@ -521,8 +521,8 @@ break2:
PRIVATE struct typestruct *declsu()
{
sym_t ogvarsc;
- offset_t soffset;
- offset_t struclength;
+ offset_T soffset;
+ offset_T struclength;
sym_t susym;
struct typelist *typelist;
struct typestruct *structype;
@@ -575,8 +575,8 @@ PRIVATE struct typestruct *declsu()
PRIVATE void declfunc()
{
- offset_t argsp;
- uoffset_t argsize;
+ offset_T argsp;
+ uoffset_T argsize;
struct symstruct *symptr;
int main_flag = 0;
@@ -679,7 +679,7 @@ PRIVATE void idecllist()
struct typestruct *basetype;
struct typestruct *inittype;
scopelev_t levelmark;
- uoffset_t newoffset;
+ uoffset_T newoffset;
argsallowed = level == GLBLEVEL;
levelmark = level;
@@ -862,12 +862,12 @@ PRIVATE void idecllist()
PRIVATE void initarray(type)
struct typestruct *type;
{
- uoffset_t basesize;
+ uoffset_T basesize;
struct typestruct *basetype;
- uoffset_t dimension;
+ uoffset_T dimension;
char *stringend;
- uoffset_t stringlength;
- uoffset_t remaining;
+ uoffset_T stringlength;
+ uoffset_T remaining;
if ((basesize = (basetype = type->nexttype)->typesize) == 0)
dimension = remaining = 0;
@@ -938,8 +938,8 @@ PRIVATE void initstruct(type)
struct typestruct *type;
{
struct typestruct *memtype;
- uoffset_t newoffset;
- uoffset_t offset;
+ uoffset_T newoffset;
+ uoffset_T offset;
struct typelist *typelist;
offset = 0;
diff --git a/bcc/express.c b/bcc/express.c
index 22d5bed..66298d3 100644
--- a/bcc/express.c
+++ b/bcc/express.c
@@ -306,7 +306,7 @@ PRIVATE struct nodestruct *primary_exp()
{
bool_t isdefined;
struct nodestruct *nodeptr;
- uoffset_t stringlen;
+ uoffset_T stringlen;
struct symstruct *symptr;
struct symstruct *symptr1;
bool_t waslparen;
diff --git a/bcc/exptree.c b/bcc/exptree.c
index 1a079e7..0f95439 100644
--- a/bcc/exptree.c
+++ b/bcc/exptree.c
@@ -252,7 +252,7 @@ struct nodestruct *p2;
struct symstruct *source = NULL; /* for -Wall */
value_t sourceval = 0 ; /* for -Wall */
struct symstruct *target;
- offset_t targszdelta;
+ offset_T targszdelta;
value_t targval = 0; /* for -Wall */
scalar_t rscalar = 0; /* for -Wall */
bool_t uflag;
diff --git a/bcc/function.c b/bcc/function.c
index 5d30a40..85bf007 100644
--- a/bcc/function.c
+++ b/bcc/function.c
@@ -198,7 +198,7 @@ PUBLIC void loadretexpression()
PUBLIC void listo(target, lastargsp)
struct symstruct *target;
-offset_t lastargsp;
+offset_T lastargsp;
{
extend(target);
push(target);
@@ -364,11 +364,11 @@ PUBLIC void reslocals()
PUBLIC void ret()
{
#ifdef FRAMEPOINTER
- offset_t newsp;
+ offset_T newsp;
if (framep != 0)
{
- newsp = -(offset_t) func1saveregsize;
+ newsp = -(offset_T) func1saveregsize;
if (switchnow != NULL || newsp - sp >= 0x80)
changesp(newsp, TRUE);
else
@@ -403,7 +403,7 @@ PUBLIC void ret()
#else
if (sp != 0)
{
- modstk(-(offset_t) func1saveregsize);
+ modstk(-(offset_T) func1saveregsize);
poplist(callee1mask);
}
outreturn();
diff --git a/bcc/gencode.c b/bcc/gencode.c
index a16ff74..8e0a0f5 100644
--- a/bcc/gencode.c
+++ b/bcc/gencode.c
@@ -37,7 +37,7 @@ PUBLIC store_pt allregs = BREG | DREG | DATREG1 | DATREG2
PUBLIC store_pt allregs = BREG | DREG | INDREG0 | INDREG1 | INDREG2;
#endif
PUBLIC store_pt allindregs = INDREG0 | INDREG1 | INDREG2;
-PUBLIC uoffset_t alignmask = ~(uoffset_t) 0x0001;
+PUBLIC uoffset_T alignmask = ~(uoffset_T) 0x0001;
PUBLIC bool_t arg1inreg = FALSE;
PUBLIC store_pt calleemask = INDREG1 | INDREG2;
PUBLIC bool_t callersaves = FALSE;
@@ -45,8 +45,8 @@ PUBLIC char *callstring = "call\t";
PUBLIC store_pt doubleargregs = DREG | INDREG0 | INDREG1 | INDREG2;
PUBLIC store_pt doubleregs = DREG | INDREG0 | INDREG1 | INDREG2;
PUBLIC store_pt doublreturnregs = DREG | INDREG0 | INDREG1 | INDREG2;
-PUBLIC offset_t jcclonger = 3;
-PUBLIC offset_t jmplonger = 1;
+PUBLIC offset_T jcclonger = 3;
+PUBLIC offset_T jmplonger = 1;
PUBLIC char *jumpstring = "br \t";
PUBLIC char *regpulllist = "f2ax2ax2bx2si2di2bp2qx2qx2cx2dx2";
PUBLIC char *regpushlist = "dx2cx2qx2qx2bp2di2si2bx2ax2ax2f2";
@@ -76,7 +76,7 @@ PUBLIC char *stackregstr = "sp";
#ifdef MC6809
PUBLIC store_pt allregs = BREG | DREG | INDREG0 | INDREG1 | INDREG2;
PUBLIC store_pt allindregs = INDREG0 | INDREG1 | INDREG2;
-PUBLIC uoffset_t alignmask = ~(uoffset_t) 0x0000;
+PUBLIC uoffset_T alignmask = ~(uoffset_T) 0x0000;
PUBLIC bool_t arg1inreg = TRUE;
PUBLIC store_pt calleemask = INDREG1 | INDREG2;
PUBLIC bool_t callersaves = TRUE;
@@ -84,8 +84,8 @@ PUBLIC char *callstring = "JSR\t>";
PUBLIC store_pt doubleargregs = DREG | INDREG0 | INDREG1 | INDREG2;
PUBLIC store_pt doubleregs = DREG | INDREG0 | INDREG1 | INDREG2;
PUBLIC store_pt doublreturnregs = DREG | INDREG0 | INDREG1 | INDREG2;
-PUBLIC offset_t jcclonger = 2;
-PUBLIC offset_t jmplonger = 1;
+PUBLIC offset_T jcclonger = 2;
+PUBLIC offset_T jmplonger = 1;
PUBLIC char *jumpstring = "JMP\t>";
PUBLIC char *regpulllist = "CC1B1D2X2U2Y2DP1PC2";
PUBLIC char *regpushlist = "PC2DP1Y2U2X2D2B1CC1";
@@ -100,14 +100,14 @@ PUBLIC char *ireg2str = "Y";
PUBLIC char *localregstr = "S";
#endif
-PUBLIC uoffset_t accregsize = 2;
+PUBLIC uoffset_T accregsize = 2;
#ifdef FRAMEPOINTER
-PUBLIC uoffset_t frameregsize = 2;
+PUBLIC uoffset_T frameregsize = 2;
#endif
-PUBLIC uoffset_t maxregsize = 2;
-PUBLIC uoffset_t opregsize = 2;
-PUBLIC uoffset_t pshregsize = 2;
-PUBLIC uoffset_t returnadrsize = 2;
+PUBLIC uoffset_T maxregsize = 2;
+PUBLIC uoffset_T opregsize = 2;
+PUBLIC uoffset_T pshregsize = 2;
+PUBLIC uoffset_T returnadrsize = 2;
#ifndef MC6809
PUBLIC uvalue_t intmaskto = 0xFFFFL;
@@ -121,7 +121,7 @@ PUBLIC uvalue_t shortmaskto = 0xFFFFL;
#endif
PRIVATE store_pt callermask;
-PRIVATE offset_t lastargsp;
+PRIVATE offset_T lastargsp;
PRIVATE smalin_t opdata[] =
{
@@ -391,7 +391,7 @@ PUBLIC void codeinit()
#else
allindregs = INDREG0 | INDREG1 | INDREG2;
#endif
- alignmask = ~(uoffset_t) 0x00000003;
+ alignmask = ~(uoffset_T) 0x00000003;
calleemask = INDREG0 | INDREG1 | INDREG2;
doubleargregs = DREG | DATREG2;
doubleregs = DREG | DATREG2;
@@ -470,11 +470,11 @@ struct nodestruct *exp;
ccode_t condtrue;
op_pt op;
store_t regmark;
- offset_t saveargsp = 0; /* for -Wall */
+ offset_T saveargsp = 0; /* for -Wall */
store_t savelist = 0; /* for -Wall */
- offset_t saveoffset = 0; /* for -Wall */
+ offset_T saveoffset = 0; /* for -Wall */
struct symstruct *source;
- offset_t spmark;
+ offset_T spmark;
struct symstruct *structarg = 0; /* for -Wall */
struct symstruct *target;
@@ -536,7 +536,7 @@ struct nodestruct *exp;
lastargsp = savelist = 0;
if (exp->nodetype->constructor & STRUCTU)
{
- modstk(sp - (offset_t) exp->nodetype->typesize);
+ modstk(sp - (offset_T) exp->nodetype->typesize);
onstack(structarg = constsym((value_t) 0));
}
else
@@ -615,7 +615,7 @@ struct nodestruct *exp;
/* -2 skips for ax and bx */
/* need dirtymask to mostly avoid this */
savereturn(regmark & callermask & regregs,
- spmark - 2 * (offset_t) pshregsize);
+ spmark - 2 * (offset_T) pshregsize);
if (exp->nodetype->constructor & STRUCTU)
{
address(structarg);
diff --git a/bcc/gencode.h b/bcc/gencode.h
index a6b99ec..03de445 100644
--- a/bcc/gencode.h
+++ b/bcc/gencode.h
@@ -10,10 +10,10 @@
#define OPERANDSEPARATOR ',' /* char separating operands */
#define OPSEPARATOR '\t' /* char separating op string and operand */
-EXTERN uoffset_t arg1size; /* size of 1st arg to function */
+EXTERN uoffset_T arg1size; /* size of 1st arg to function */
/* zero after allocation of 1st arg */
EXTERN store_pt callee1mask; /* calleemask with doubleregs masked if nec */
-EXTERN uoffset_t dataoffset; /* amount of initialized data so far */
+EXTERN uoffset_T dataoffset; /* amount of initialized data so far */
#ifdef DEBUG
EXTERN bool_t debugon; /* nonzero to print debugging messages */
/* depends on zero init */
@@ -21,11 +21,11 @@ EXTERN bool_t debugon; /* nonzero to print debugging messages */
#ifdef FRAMEPOINTER
EXTERN store_pt framelist; /* bit pattern for frame and saved regs */
EXTERN store_pt frame1list; /* framelist with doubleregs masked if nec */
-EXTERN offset_t framep; /* hardware relative frame ptr */
+EXTERN offset_T framep; /* hardware relative frame ptr */
#endif
-EXTERN uoffset_t func1saveregsize; /* choice of next two values */
-EXTERN uoffset_t funcdsaveregsize; /* funcsaveregsize adjusted for doubles */
-EXTERN uoffset_t funcsaveregsize; /* tot size of framelist/calleemask regs */
+EXTERN uoffset_T func1saveregsize; /* choice of next two values */
+EXTERN uoffset_T funcdsaveregsize; /* funcsaveregsize adjusted for doubles */
+EXTERN uoffset_T funcsaveregsize; /* tot size of framelist/calleemask regs */
#ifdef I80386
EXTERN bool_t i386_32; /* nonzero to generate 386 32 bit code */
/* depends on zero init */
@@ -34,7 +34,7 @@ EXTERN bool_t i386_32; /* nonzero to generate 386 32 bit code */
EXTERN bool_t long_big_endian; /* nonzero if high long word is first */
/* depends on zero init */
#endif
-EXTERN offset_t lowsp; /* low water sp (collects locals in switch) */
+EXTERN offset_T lowsp; /* low water sp (collects locals in switch) */
#ifdef POSINDEPENDENT
EXTERN bool_t posindependent; /* nonzero to generate pos-independent code */
/* depends on zero init */
@@ -44,8 +44,8 @@ EXTERN bool_t regarg; /* nonzero to show unloaded register arg */
/* depends on zero init */
EXTERN store_t reguse; /* registers in use */
EXTERN bool_t scanf_fp; /* nonzero if *scanf called with ptr-to-FP */
-EXTERN offset_t softsp; /* software sp (leads sp during declares) */
-EXTERN offset_t sp; /* hardware relative stack ptr */
+EXTERN offset_T softsp; /* software sp (leads sp during declares) */
+EXTERN offset_T sp; /* hardware relative stack ptr */
/* depends on zero init */
#ifdef FRAMEPOINTER
EXTERN bool_t stackarg; /* nonzero to show function has arg on stack */
@@ -64,8 +64,8 @@ extern char *callstring; /* opcode string for call */
extern store_pt doubleargregs; /* mask (in) for regs for 1st arg if double */
extern store_pt doubleregs; /* mask (in) for regs to temp contain double */
extern store_pt doublreturnregs; /* mask (in) for regs for returning double */
-extern offset_t jcclonger; /* amount jcc long jumps are longer */
-extern offset_t jmplonger; /* amount long jumps is longer */
+extern offset_T jcclonger; /* amount jcc long jumps are longer */
+extern offset_T jmplonger; /* amount long jumps is longer */
extern char *jumpstring; /* opcode string for jump */
extern char *regpulllist; /* reg names and sizes (0 store_t bit first) */
extern char *regpushlist; /* reg names and sizes (0 store_t bit last) */
@@ -91,11 +91,11 @@ extern char *stackregstr;
/* register sizes */
-extern uoffset_t accregsize;
+extern uoffset_T accregsize;
#ifdef FRAMEPOINTER
-extern uoffset_t frameregsize;
+extern uoffset_T frameregsize;
#endif
-extern uoffset_t maxregsize;
-extern uoffset_t opregsize;
-extern uoffset_t pshregsize;
-extern uoffset_t returnadrsize;
+extern uoffset_T maxregsize;
+extern uoffset_T opregsize;
+extern uoffset_T pshregsize;
+extern uoffset_T returnadrsize;
diff --git a/bcc/genloads.c b/bcc/genloads.c
index 26933f8..652127e 100644
--- a/bcc/genloads.c
+++ b/bcc/genloads.c
@@ -71,14 +71,14 @@ PRIVATE void blockpush(source)
struct symstruct *source;
{
struct symstruct *length;
- offset_t spmark;
- uoffset_t typesize;
+ offset_T spmark;
+ uoffset_T typesize;
typesize = source->type->typesize;
length = constsym((value_t) typesize);
length->type = uitype;
address(source);
- modstk(spmark = sp - (offset_t) typesize);
+ modstk(spmark = sp - (offset_T) typesize);
#ifdef STACKREG
regtransfer(STACKREG, DREG);
#else
@@ -157,7 +157,7 @@ struct symstruct *target;
#ifdef MC6809
bool_t canABX;
#endif
- uoffset_t size;
+ uoffset_T size;
store_pt sourcereg;
struct typestruct *targtype;
store_pt targreg;
@@ -348,8 +348,8 @@ store_pt targreg;
if (source->storage == CONSTANT)
{
/* XXX - more for non-386 */
- loadconst(((offset_t *) source->offset.offd)[0], DREG);
- loadconst(((offset_t *) source->offset.offd)[1], targreg);
+ loadconst(((offset_T *) source->offset.offd)[0], DREG);
+ loadconst(((offset_T *) source->offset.offd)[1], targreg);
}
else
{
@@ -368,7 +368,7 @@ store_pt targreg;
float val;
val = *source->offset.offd;
- loadconst(((offset_t *) &val)[0], targreg);
+ loadconst(((offset_T *) &val)[0], targreg);
}
else if (source->indcount == 0 && source->storage != CONSTANT)
loadadr(source, targreg);
@@ -454,7 +454,7 @@ struct symstruct *source;
store_pt targreg;
{
sc_t flags;
- offset_t offset;
+ offset_T offset;
store_t reg;
struct typestruct *type;
@@ -478,19 +478,19 @@ PUBLIC void loadreg(source, targreg)
struct symstruct *source;
store_pt targreg;
{
- offset_t longhigh;
- offset_t longlow;
+ offset_T longhigh;
+ offset_T longlow;
if (source->storage == CONSTANT)
{
if (source->type->scalar & CHAR && (store_t) targreg & ALLDATREGS)
targreg = BREG;
- longlow = (offset_t) source->offset.offv;
+ longlow = (offset_T) source->offset.offv;
if (source->type->scalar & DLONG)
{
- longlow &= (offset_t) intmaskto;
- longhigh = (offset_t) (source->offset.offv >> INT16BITSTO)
- & (offset_t) intmaskto;
+ longlow &= (offset_T) intmaskto;
+ longhigh = (offset_T) (source->offset.offv >> INT16BITSTO)
+ & (offset_T) intmaskto;
if ((store_t) targreg != LONGREG2) /* loading the whole long */
{
#if DYNAMIC_LONG_ORDER
@@ -589,7 +589,7 @@ store_pt targreg;
#endif
outregname(targreg);
if (source->storage == CONSTANT)
- adjlc((offset_t) source->offset.offv, targreg);
+ adjlc((offset_T) source->offset.offv, targreg);
#ifdef I8088
outcomma();
#endif
@@ -677,7 +677,7 @@ struct symstruct *adr;
switch (adr->storage)
{
case CONSTANT:
- outimmadr((offset_t) adr->offset.offv);
+ outimmadr((offset_T) adr->offset.offv);
break;
#ifdef I8088
case DREG:
@@ -827,7 +827,7 @@ struct symstruct *adr;
outlabel(adr->name.label);
else if (*adr->name.namep == 0) /* constant address */
{
- outhex((uoffset_t) adr->offset.offi);
+ outhex((uoffset_T) adr->offset.offi);
break;
}
else
@@ -998,7 +998,7 @@ struct symstruct *source;
{
store_t reg;
#ifdef I8088
- uoffset_t size;
+ uoffset_T size;
#endif
scalar_t sscalar;
@@ -1047,7 +1047,7 @@ struct symstruct *source;
if (source->storage == CONSTANT)
{
unbumplc();
- adjlc((offset_t) source->offset.offv, INDREG0);
+ adjlc((offset_T) source->offset.offv, INDREG0);
}
if (size == 2)
{
diff --git a/bcc/glogcode.c b/bcc/glogcode.c
index 279d625..782730f 100644
--- a/bcc/glogcode.c
+++ b/bcc/glogcode.c
@@ -219,7 +219,7 @@ ccode_t *pcondtrue;
targreg = YREG;
if (target->indcount != 0)
load(target, targreg);
- target->offset.offi -= (offset_t) intconst;
+ target->offset.offi -= (offset_T) intconst;
loadreg(target, targreg);
return TRUE;
}
@@ -237,7 +237,7 @@ bool_pt nojump; /* NB if nonzero, is ~0 so complement is 0 */
ccode_t condtrue;
store_t regmark;
struct symstruct *source;
- offset_t spmark;
+ offset_T spmark;
struct symstruct *target;
regmark = reguse;
diff --git a/bcc/hardop.c b/bcc/hardop.c
index 187a4f5..2aa8f55 100644
--- a/bcc/hardop.c
+++ b/bcc/hardop.c
@@ -38,7 +38,7 @@ struct symstruct *target;
extend(target);
if (target->indcount != 0 || target->storage & reguse)
loadany(target);
- target->offset.offi += (offset_t) source->offset.offv;
+ target->offset.offi += (offset_T) source->offset.offv;
}
else if (source->indcount == 0)
{
@@ -64,7 +64,7 @@ PUBLIC void incdec(op, source)
op_pt op;
struct symstruct *source;
{
- offset_t bump;
+ offset_T bump;
bool_t postflag;
store_t regmark;
struct symstruct *target;
@@ -315,7 +315,7 @@ struct symstruct *target;
load(target, DREG);
opstr = opstring(op);
if (source->storage == CONSTANT && op == ANDOP)
- andconst((offset_t) source->offset.offv);
+ andconst((offset_T) source->offset.offv);
#ifdef OP1
else if (tscalar & CHAR && !(sscalar & CHAR) && op != ANDOP)
outload();
@@ -337,12 +337,12 @@ struct symstruct *target;
if (!(sscalar & CHAR))
{
outhiaccum();
- outncimmadr((offset_t) ((uoffset_t) source->offset.offv
+ outncimmadr((offset_T) ((uoffset_T) source->offset.offv
>> (INT16BITSTO - CHBITSTO)));
outop2str(opstr);
}
outregname(BREG);
- outncimmadr((offset_t) source->offset.offv & CHMASKTO);
+ outncimmadr((offset_T) source->offset.offv & CHMASKTO);
#else /* OP1 */
if (!(sscalar & CHAR))
{
@@ -355,7 +355,7 @@ struct symstruct *target;
if (i386_32 && !(sscalar & CHAR))
bumplc2();
# endif
- outncimmadr((offset_t) source->offset.offv);
+ outncimmadr((offset_T) source->offset.offv);
#endif /* OP1 */
}
@@ -429,7 +429,7 @@ struct symstruct *source;
struct symstruct *target;
{
label_no exitlab;
- uoffset_t factor;
+ uoffset_T factor;
label_no usignlab;
if (source->indcount == 0 && source->storage != CONSTANT)
@@ -482,7 +482,7 @@ struct symstruct *target;
extend(target);
if (target->indcount != 0 || target->storage & reguse)
loadany(target);
- target->offset.offi -= (offset_t) source->offset.offv;
+ target->offset.offi -= (offset_T) source->offset.offv;
}
else
sub1(source, target);
diff --git a/bcc/label.c b/bcc/label.c
index b250d2b..64800d4 100644
--- a/bcc/label.c
+++ b/bcc/label.c
@@ -26,7 +26,7 @@
struct labdatstruct
{
label_no labnum; /* 0 if not active */
- offset_t lablc; /* location counter for branch or label */
+ offset_T lablc; /* location counter for branch or label */
char *labpatch; /* buffer ptr for branch, NULL for label */
ccode_t labcond; /* condition code for branch */
};
@@ -58,7 +58,7 @@ PRIVATE char condnames[][2] = /* names of condition codes */
PRIVATE label_no lasthighlab = 0xFFFF+1; /* temp & temp init so labels fixed */
/* lint */
PRIVATE label_no lastlab; /* bss init to 0 */
-PRIVATE offset_t lc; /* bss init to 0 */
+PRIVATE offset_T lc; /* bss init to 0 */
PRIVATE struct labdatstruct vislab[MAXVISLAB]; /* bss, all labnum's init 0 */
PRIVATE smalin_t nextvislab; /* bss init to NULL */
@@ -159,9 +159,9 @@ PUBLIC void clearswitchlabels()
/* return location counter */
-PUBLIC uoffset_t getlc()
+PUBLIC uoffset_T getlc()
{
- return (uoffset_t) lc;
+ return (uoffset_T) lc;
}
/* define location of label and backpatch references to it */
@@ -174,7 +174,7 @@ label_no label;
struct labdatstruct *labmax;
struct labdatstruct *labmid;
struct labdatstruct *labptrsave;
- offset_t nlonger;
+ offset_T nlonger;
outnlabel(label);
{
@@ -379,7 +379,7 @@ PUBLIC void outlabel(label)
label_no label;
{
outbyte(LABELSTARTCHAR);
- outhexdigs((uoffset_t) label);
+ outhexdigs((uoffset_T) label);
}
/* print label and newline */
diff --git a/bcc/loadexp.c b/bcc/loadexp.c
index 6ecb82f..30f0b50 100644
--- a/bcc/loadexp.c
+++ b/bcc/loadexp.c
@@ -40,7 +40,7 @@ struct typestruct *type;
struct symstruct *exprmark;
struct nodestruct *lhs;
struct symstruct *symptr;
- uoffset_t value;
+ uoffset_T value;
if (gvarsymptr->storage != GLOBAL)
reslocals();
@@ -76,12 +76,12 @@ struct typestruct *type;
float val;
val = *symptr->offset.offd;
- deflong(((uoffset_t *) &val)[0]);
+ deflong(((uoffset_T *) &val)[0]);
}
else
{
- deflong(((uoffset_t *) symptr->offset.offd)[0]);
- deflong(((uoffset_t *) symptr->offset.offd)[1]);
+ deflong(((uoffset_T *) symptr->offset.offd)[0]);
+ deflong(((uoffset_T *) symptr->offset.offd)[1]);
}
etptr = etmark; /* XXX - stuff from end of function */
exprptr = exprmark;
@@ -98,7 +98,7 @@ struct typestruct *type;
switch (symptr->storage)
{
case CONSTANT:
- value = (uoffset_t) symptr->offset.offv;
+ value = (uoffset_T) symptr->offset.offv;
if (type->scalar & DLONG)
{
deflong(value);
@@ -119,12 +119,12 @@ struct typestruct *type;
{
outlabel(symptr->name.label);
outplus();
- outnhex((uoffset_t) symptr->offset.offi);
+ outnhex((uoffset_T) symptr->offset.offi);
break;
}
if (*symptr->name.namep == 0) /* constant address */
{
- outnhex((uoffset_t) symptr->offset.offi);
+ outnhex((uoffset_T) symptr->offset.offi);
break;
}
outccname(symptr->name.namep);
diff --git a/bcc/longop.c b/bcc/longop.c
index 412ac25..2cdf62a 100644
--- a/bcc/longop.c
+++ b/bcc/longop.c
@@ -27,7 +27,7 @@ struct symstruct *target;
store_t regmark;
bool_t shiftflag;
scalar_t scalar;
- offset_t spmark;
+ offset_T spmark;
pushlist(reglist = (regmark = reguse) & (OPREG | OPWORKREG));
reguse &= ~reglist;
diff --git a/bcc/output.c b/bcc/output.c
index 6bc4d04..e5db292 100644
--- a/bcc/output.c
+++ b/bcc/output.c
@@ -354,7 +354,7 @@ char *str;
/* print unsigned offset, hex format */
PUBLIC void outhex(num)
-uoffset_t num;
+uoffset_T num;
{
#ifdef HEXSTARTCHAR
if (num >= 10)
@@ -370,7 +370,7 @@ uoffset_t num;
/* print unsigned offset, hex format with digits only (no hex designator) */
PUBLIC void outhexdigs(num)
-register uoffset_t num;
+register uoffset_T num;
{
if (num >= 0x10)
{
@@ -431,7 +431,7 @@ int byte;
/* print unsigned offset, hex format, then newline */
PUBLIC void outnhex(num)
-uoffset_t num;
+uoffset_T num;
{
outhex(num);
outnl();
@@ -530,14 +530,14 @@ PUBLIC void outplus()
/* print signed offset, hex format */
PUBLIC void outshex(num)
-offset_t num;
+offset_T num;
{
if (num >= -(maxoffsetto + 1))
{
outminus();
num = -num;
}
- outhex((uoffset_t) num);
+ outhex((uoffset_T) num);
}
/* print string */
@@ -771,7 +771,7 @@ register value_t num;
outminus();
num = -num;
}
- outuvalue((uoffset_t) num);
+ outuvalue((uoffset_T) num);
}
#endif /* DEBUG */
diff --git a/bcc/preserve.c b/bcc/preserve.c
index 17ded07..c8a8cea 100644
--- a/bcc/preserve.c
+++ b/bcc/preserve.c
@@ -10,7 +10,7 @@
/* change stack ptr without changing condition codes */
PUBLIC void changesp(newsp, absflag)
-offset_t newsp;
+offset_T newsp;
bool_pt absflag;
{
if (newsp != sp || ((bool_t) absflag && switchnow != NULL))
@@ -74,7 +74,7 @@ struct symstruct *target;
/* change stack ptr */
PUBLIC void modstk(newsp)
-offset_t newsp;
+offset_T newsp;
{
if (newsp != sp)
{
@@ -173,11 +173,11 @@ PRIVATE smalin_t regoffset[] = {0, 0, 0, 1, 3, 2};
PUBLIC void savereturn(savelist, saveoffset)
store_pt savelist;
-offset_t saveoffset;
+offset_T saveoffset;
{
store_t reg;
smalin_t *regoffptr;
- offset_t spoffset;
+ offset_T spoffset;
if (savelist == 0)
return;
diff --git a/bcc/proto.h b/bcc/proto.h
index 69eebb2..e4a6b38 100644
--- a/bcc/proto.h
+++ b/bcc/proto.h
@@ -13,7 +13,7 @@ void clrBreg P((void));
void comment P((void));
void ctoi P((void));
void defbyte P((void));
-void deflong P((uoffset_t value));
+void deflong P((uoffset_T value));
void defword P((void));
void defdword P((void));
void even P((void));
@@ -53,27 +53,27 @@ void outextended P((void));
void outncspregname P((void));
void outindframereg P((void));
void adc0 P((void));
-void addconst P((offset_t offset, store_pt reg));
-void adjlc P((offset_t offset, store_pt reg));
-void andconst P((offset_t offset));
+void addconst P((offset_T offset, store_pt reg));
+void adjlc P((offset_T offset, store_pt reg));
+void andconst P((offset_T offset));
void bssseg P((void));
label_no casejump P((void));
void common P((char *name));
void cseg P((void));
-void defnulls P((uoffset_t nullcount));
+void defnulls P((uoffset_T nullcount));
label_no defstr P((char *sptr, char *stop, bool_pt dataflag));
bool_pt diveasy P((value_t divisor, bool_pt uflag));
void dpseg P((void));
void dseg P((void));
void equ P((char *name, char *string));
-void equlab P((label_no label, offset_t offset));
+void equlab P((label_no label, offset_T offset));
void globl P((char *name));
void import P((char *name));
void itol P((store_pt reg));
void lcommlab P((label_no label));
void lcommon P((char *name));
-void lea P((offset_t offset, store_pt sourcereg, store_pt targreg));
-void loadconst P((offset_t offset, store_pt reg));
+void lea P((offset_T offset, store_pt sourcereg, store_pt targreg));
+void loadconst P((offset_T offset, store_pt reg));
int lslconst P((value_t shift, store_pt reg));
int lsrconst P((value_t shift, store_pt reg, bool_pt uflag));
bool_pt modeasy P((value_t divisor, bool_pt uflag));
@@ -82,19 +82,19 @@ void negreg P((store_pt reg));
char *opstring P((op_pt op));
void outccname P((char *name));
void outhiaccum P((void));
-void outimmadr P((offset_t offset));
-void outimadj P((offset_t offset, store_pt targreg));
+void outimmadr P((offset_T offset));
+void outimadj P((offset_T offset, store_pt targreg));
void outimmed P((void));
void outjumpstring P((void));
void outnccname P((char *name));
-void outncimmadr P((offset_t offset));
-void outoffset P((offset_t offset));
+void outncimmadr P((offset_T offset));
+void outoffset P((offset_T offset));
void public P((char *name));
void private P((char *name));
void regexchange P((store_pt sourcereg, store_pt targreg));
void regtransfer P((store_pt sourcereg, store_pt targreg));
void sbc0 P((void));
-void set P((char *name, offset_t value));
+void set P((char *name, offset_T value));
void sl1 P((store_pt reg));
void slconst P((value_t shift, store_pt reg));
void srconst P((value_t shift, bool_pt uflag));
@@ -144,7 +144,7 @@ void call P((char *name));
void function P((struct symstruct *source));
void ldregargs P((void));
void loadretexpression P((void));
-void listo P((struct symstruct *target, offset_t lastargsp));
+void listo P((struct symstruct *target, offset_T lastargsp));
void listroot P((struct symstruct *target));
void popframe P((void));
void reslocals P((void));
@@ -219,7 +219,7 @@ void bumplc3 P((void));
void clearfunclabels P((void));
void clearlabels P((char *patchbuf, char *patchtop));
void clearswitchlabels P((void));
-uoffset_t getlc P((void));
+uoffset_T getlc P((void));
void deflabel P((label_no label));
label_no gethighlabel P((void));
label_no getlabel P((void));
@@ -257,13 +257,13 @@ void openout P((char *oname));
void outbyte P((int ch));
void outcomma P((void));
void outcpplinenumber P((unsigned nr, char *fname, char *str));
-void outhex P((uoffset_t num));
-void outhexdigs P((uoffset_t num));
+void outhex P((uoffset_T num));
+void outhexdigs P((uoffset_T num));
void outline P((char *s));
void outminus P((void));
void outnl P((void));
void outnbyte P((int byte));
-void outnhex P((uoffset_t num));
+void outnhex P((uoffset_T num));
void outnop1str P((char *s));
void outnop2str P((char *s));
void outnstr P((char *s));
@@ -272,7 +272,7 @@ void outop1str P((char *s));
void outop2str P((char *s));
void outop3str P((char *s));
void outplus P((void));
-void outshex P((offset_t num));
+void outshex P((offset_T num));
void outstr P((char *s));
void outtab P((void));
void outudec P((unsigned num));
@@ -299,14 +299,14 @@ void skipline P((void));
void undefinestring P((char *str));
/* preserve.c */
-void changesp P((offset_t newsp, bool_pt absflag));
+void changesp P((offset_T newsp, bool_pt absflag));
void loadpres P((struct symstruct *source, struct symstruct *target));
-void modstk P((offset_t newsp));
+void modstk P((offset_T newsp));
void pres2 P((struct symstruct *source, struct symstruct *target));
void preserve P((struct symstruct *source));
store_pt preslval P((struct symstruct *source, struct symstruct *target));
void recovlist P((store_pt reglist));
-void savereturn P((store_pt savelist, offset_t saveoffset));
+void savereturn P((store_pt savelist, offset_T saveoffset));
/* sc.c */
int main P((int argc, char **argv));
@@ -323,7 +323,7 @@ void softop P((op_pt op, struct symstruct *source, struct symstruct *target));
/* state.c */
void compound P((void));
-void outswoffset P((offset_t offset));
+void outswoffset P((offset_T offset));
void outswstacklab P((void));
/* table.c */
@@ -359,7 +359,7 @@ struct typestruct *iscalartotype P((scalar_pt scalar));
struct typestruct *newtype P((void));
void outntypechar P((struct typestruct *type));
struct typestruct *pointype P((struct typestruct *type));
-struct typestruct *prefix P((constr_pt constructor, uoffset_t size,
+struct typestruct *prefix P((constr_pt constructor, uoffset_T size,
struct typestruct *type));
struct typestruct *promote P((struct typestruct *type));
struct typestruct *tounsigned P((struct typestruct *type));
diff --git a/bcc/sizes.h b/bcc/sizes.h
index df0d141..866b203 100644
--- a/bcc/sizes.h
+++ b/bcc/sizes.h
@@ -21,12 +21,12 @@
#define MINSCHTO (-128) /* minimum signed character */
#ifdef MC6809
-# define is5bitoffset(n) ((uoffset_t) (n) + 0x10 < 0x20)
+# define is5bitoffset(n) ((uoffset_T) (n) + 0x10 < 0x20)
#endif
-#define isbyteoffset(n) ((uoffset_t) (n) - MINSCHTO <= MAXSCHTO - MINSCHTO)
+#define isbyteoffset(n) ((uoffset_T) (n) - MINSCHTO <= MAXSCHTO - MINSCHTO)
#define ischarconst(n) ((uvalue_t) (n) <= MAXUCHTO)
#define isnegbyteoffset(n) ((uvalue_t) (n) + MAXSCHTO <= MAXSCHTO - MINSCHTO)
-#define isshortbranch(n) ((uoffset_t) (n) - MINSCHTO <= MAXSCHTO - MINSCHTO)
+#define isshortbranch(n) ((uoffset_T) (n) - MINSCHTO <= MAXSCHTO - MINSCHTO)
#ifdef MC6809
/* Hack to reduce number of direct page variables. */
diff --git a/bcc/softop.c b/bcc/softop.c
index 6f2dbce..e2e2b25 100644
--- a/bcc/softop.c
+++ b/bcc/softop.c
@@ -188,36 +188,58 @@ struct symstruct *target;
extend(target);
load(target, DREG);
- load(source, OPREG);
- switch ((op_t) op)
+#ifndef IN_FUNC /* I8088 ? */
+ if ((op_t) op != DIVOP && (op_t) op != MODOP )
{
- case DIVOP:
+ load(source, DATREG1); /* CX */
+ switch ((op_t) op)
+ {
+ case MULOP:
+ outnop2str("imul\tcx");
+ break;
+ case SLOP:
+ outnop2str("shl\tax,cl");
+ break;
+ case SROP:
+ if (uflag) outnop2str("shr\tax,cl");
+ else outnop2str("sar\tax,cl");
+ break;
+ }
+ }
+ else
+#endif
+ {
+ load(source, OPREG);
+ switch ((op_t) op)
+ {
+ case DIVOP:
#ifdef I8088
- call("idiv_");
+ call("idiv_");
#else
- call("idiv");
+ call("idiv");
#endif
- break;
- case MODOP:
- call("imod");
- break;
- case MULOP:
+ break;
+ case MODOP:
+ call("imod");
+ break;
+ case MULOP:
#ifdef I8088
- call("imul_");
+ call("imul_");
#else
- call("imul");
+ call("imul");
#endif
- break;
- case SLOP:
- call("isl");
- break;
- case SROP:
- call("isr");
- break;
+ break;
+ case SLOP:
+ call("isl");
+ break;
+ case SROP:
+ call("isr");
+ break;
+ }
+ if (uflag)
+ outbyte('u');
+ outnl();
}
- if (uflag)
- outbyte('u');
- outnl();
target->type = iscalartotype(resultscalar);
poplist(regpushed);
reguse = regmark;
diff --git a/bcc/state.c b/bcc/state.c
index 6a83963..9fdb224 100644
--- a/bcc/state.c
+++ b/bcc/state.c
@@ -28,7 +28,7 @@ struct loopstruct
struct symstruct *exprmark; /* expression symbols built during loop */
struct symstruct *locmark; /* local variables built during loop */
struct loopstruct *prevloop; /* previous active for, switch or while */
- offset_t spmark; /* stack value for continue and break */
+ offset_T spmark; /* stack value for continue and break */
};
struct switchstruct
@@ -105,7 +105,7 @@ PRIVATE void deleteloop()
PRIVATE void evalexpression(exp)
struct nodestruct *exp;
{
- offset_t spmark;
+ offset_T spmark;
spmark = sp;
makeleaf(exp);
@@ -172,13 +172,13 @@ PUBLIC void compound() /* have just seen "{" */
struct symstruct *locmark;
store_t regmark;
#ifdef FRAMEPOINTER
- offset_t framepmark;
- offset_t softspmark;
+ offset_T framepmark;
+ offset_T softspmark;
#else
/* softsp == sp here unless level == ARGLEVEL so mark is unnec */
/* this is also true if funcsaveregsize != 0 but the tests are too messy */
#endif
- offset_t spmark;
+ offset_T spmark;
locmark = locptr;
regmark = reguse;
@@ -249,7 +249,7 @@ PRIVATE void doasm()
PRIVATE void dobreak()
{
- offset_t spmark;
+ offset_T spmark;
if (loopnow == NULL)
badloop();
@@ -312,7 +312,7 @@ ts_s_case_tot += GROWCASES * sizeof (struct casestruct);
PRIVATE void docont()
{
struct loopstruct *contloop;
- offset_t spmark;
+ offset_T spmark;
struct switchstruct *switchthen;
for (contloop = loopnow, switchthen = switchnow; ;
@@ -472,7 +472,7 @@ PRIVATE void doif()
PRIVATE void doreturn()
{
- offset_t spmark;
+ offset_T spmark;
spmark = sp;
if (sym != SEMICOLON) /* returning expression */
@@ -485,7 +485,7 @@ PRIVATE void doswitch()
{
struct switchstruct *sw;
struct loopstruct switchloop;
- offset_t spmark = 0; /* for -Wall */
+ offset_T spmark = 0; /* for -Wall */
label_no sdecidelab;
sw = (struct switchstruct *) ourmalloc(sizeof *sw);
@@ -590,7 +590,7 @@ PRIVATE void jumptocases()
while (caseptr <= casetop)
{
outsub();
- outimadj((offset_t) (caseptr->casevalue - basevalue), targreg);
+ outimadj((offset_T) (caseptr->casevalue - basevalue), targreg);
basevalue = caseptr->casevalue;
for (case1ptr = caseptr; case1ptr < casetop; ++case1ptr)
if (case1ptr->casevalue < (case1ptr + 1)->casevalue - 10)
@@ -604,7 +604,7 @@ PRIVATE void jumptocases()
{
lbranch(lowcondition, dfaultlab);
outcmp();
- outimadj((offset_t) (case1ptr->casevalue - basevalue), targreg);
+ outimadj((offset_T) (case1ptr->casevalue - basevalue), targreg);
lbranch(HI, zjtablelab = getlabel());
if (charselector)
ctoi();
@@ -657,7 +657,7 @@ PRIVATE void jumptocases()
}
PUBLIC void outswoffset (offset)
-offset_t offset;
+offset_T offset;
{
#ifdef FRAMEPOINTER
outoffset(offset - softsp - framep);
diff --git a/bcc/type.c b/bcc/type.c
index fe66b33..97d88d7 100644
--- a/bcc/type.c
+++ b/bcc/type.c
@@ -13,12 +13,12 @@
#define EXTERN
#include "type.h"
-PUBLIC uoffset_t ctypesize = 1;
-PUBLIC uoffset_t dtypesize = 8;
-PUBLIC uoffset_t ftypesize = 0;
-PUBLIC uoffset_t itypesize = 2;
-PUBLIC uoffset_t ptypesize = 2;
-PUBLIC uoffset_t stypesize = 2;
+PUBLIC uoffset_T ctypesize = 1;
+PUBLIC uoffset_T dtypesize = 8;
+PUBLIC uoffset_T ftypesize = 0;
+PUBLIC uoffset_T itypesize = 2;
+PUBLIC uoffset_T ptypesize = 2;
+PUBLIC uoffset_T stypesize = 2;
PRIVATE char skey0;
PRIVATE char skey1;
@@ -79,7 +79,7 @@ PUBLIC struct typestruct *newtype()
++ts_n_type;
ts_s_type += sizeof *type;
#endif
- type->typesize = /* (uoffset_t) */
+ type->typesize = /* (uoffset_T) */
type->scalar = /* (scalar_t) */
type->constructor = /* (constr_t) */
type->structkey[0] = 0;
@@ -105,7 +105,7 @@ struct typestruct *type;
PUBLIC struct typestruct *prefix(constructor, size, type)
constr_pt constructor;
-uoffset_t size;
+uoffset_T size;
struct typestruct *type;
{
register struct typestruct *searchtype;
@@ -121,7 +121,7 @@ struct typestruct *type;
searchtype->alignmask = type->alignmask;
break;
case FUNCTION:
- searchtype->alignmask = ~(uoffset_t) 0;
+ searchtype->alignmask = ~(uoffset_T) 0;
break;
case POINTER:
searchtype->alignmask = ~(ptypesize - 1) | alignmask;
@@ -190,7 +190,7 @@ PUBLIC void typeinit()
uitype->alignmask =
ltype->alignmask =
ultype->alignmask =
- itype->alignmask = ~(uoffset_t) (4 - 1);
+ itype->alignmask = ~(uoffset_T) (4 - 1);
ltype->scalar = LONG; /* not DLONG */
ultype->scalar = UNSIGNED | LONG;
}
diff --git a/bcc/type.h b/bcc/type.h
index c451283..61f89cf 100644
--- a/bcc/type.h
+++ b/bcc/type.h
@@ -63,12 +63,12 @@
/* type sizes */
/* default sizes and long and float sizes are hard-coded into type data */
-extern uoffset_t ctypesize;
-extern uoffset_t dtypesize;
-extern uoffset_t ftypesize;
-extern uoffset_t itypesize;
-extern uoffset_t ptypesize;
-extern uoffset_t stypesize;
+extern uoffset_T ctypesize;
+extern uoffset_T dtypesize;
+extern uoffset_T ftypesize;
+extern uoffset_T itypesize;
+extern uoffset_T ptypesize;
+extern uoffset_T stypesize;
/* basic scalar types */
diff --git a/bcc/types.h b/bcc/types.h
index da34a3a..effcfcd 100644
--- a/bcc/types.h
+++ b/bcc/types.h
@@ -13,14 +13,14 @@ typedef long value_t; /* target ints, longs and offsets */
typedef unsigned long uvalue_t; /* target unsigned ints, longs and offsets */
#ifdef I8088
-typedef long offset_t; /* target machine offset */
-typedef unsigned long uoffset_t; /* target unsigned machine offset */
+typedef long offset_T; /* target machine offset */
+typedef unsigned long uoffset_T; /* target unsigned machine offset */
#define outuvalue outhex
#define outvalue outshex
#endif
#ifdef MC6809
-typedef int offset_t;
-typedef unsigned uoffset_t;
+typedef int offset_T;
+typedef unsigned uoffset_T;
#endif
@@ -146,7 +146,7 @@ struct symstruct
union
{
double *offd; /* value for double constants */
- offset_t offi; /* offset for register or global storage */
+ offset_T offi; /* offset for register or global storage */
label_no offlabel; /* label number for strings */
char *offp; /* to string for macro definitions */
sym_pt offsym; /* symbol code for keywords */
@@ -173,8 +173,8 @@ struct typestruct
char structkey[2]; /* unique prefix for member names */
/* ranges from "\001\001" to "@\377" */
/* avoiding nulls */
- uoffset_t alignmask; /* alignment mask, typesize - 1 for scalars */
- uoffset_t typesize; /* size of this type */
+ uoffset_T alignmask; /* alignment mask, typesize - 1 for scalars */
+ uoffset_T typesize; /* size of this type */
char *tname; /* name of scalar type or constructor */
struct typelist *listtype; /* list of member types */
struct typestruct *nexttype;
diff --git a/bootblocks/Makefile b/bootblocks/Makefile
index 3f572be..f01c725 100644
--- a/bootblocks/Makefile
+++ b/bootblocks/Makefile
@@ -22,10 +22,14 @@ SSRC=sysboot.s \
encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v
bin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin
-MOBJ=monitor.o i86_funcs.o relocate.o help.o bzimage.o dosfs.o nofs.o
-MSRC=monitor.c i86_funcs.c relocate.c help.c bzimage.c dosfs.c nofs.c
+MOBJ=monitor.o i86_funcs.o relocate.o help.o bzimage.o trk_buf.o unix.o \
+ fs.o fs_tar.o fs_min.o fs_dos.o
+MSRC=monitor.c i86_funcs.c relocate.c help.c bzimage.c trk_buf.c unix.c \
+ fs.c fs_tar.c fs_min.c fs_dos.c
MINC=i86_funcs.h readfs.h
+BOOTBLOCKS=sysboot.v noboot.v skip.v msdos.v tarboot.v minix.v minixhd.v
+
EXTRAS=minix.h elf_info.c elf_info.h standalone.c li86.s
install:
@@ -37,7 +41,7 @@ $(MOBJ): $(MINC) version.h
monitor: $(MSRC) $(MINC)
@rm -f $(MOBJ)
- make 'CFLAGS=-ansi' monitor.out
+ make 'CFLAGS=-ansi -H0x8000' monitor.out
mv monitor.out monitor
@rm -f $(MOBJ)
@@ -47,10 +51,10 @@ minix.s: minix.c
minixhd.s: minix.c
$(BCC) -Mf -DDOTS -DHARDDISK $(MDEFS) -S minix.c -o minixhd.s
-makeboot: makeboot.c sysboot.v noboot.v skip.v msdos.v tarboot.v
+makeboot: makeboot.c $(BOOTBLOCKS)
$(HOSTCC) $(HOSTCCFLAGS) -o makeboot makeboot.c
-makeboot.com: makeboot.c sysboot.v noboot.v skip.v msdos.v tarboot.v
+makeboot.com: makeboot.c $(BOOTBLOCKS)
$(BCC) -Md -o makeboot.com makeboot.c
version.h:
diff --git a/bootblocks/bzimage.c b/bootblocks/bzimage.c
index 2e7c835..baf027b 100644
--- a/bootblocks/bzimage.c
+++ b/bootblocks/bzimage.c
@@ -4,6 +4,7 @@
*/
#include <stdio.h>
+#include <dos.h>
#include "i86_funcs.h"
#include "readfs.h"
@@ -13,9 +14,18 @@ char * append_line = 0; /* A preset append line value */
static char * initrd_name = 0; /* Name of init_ramdisk to load */
static int vga_mode = -1; /* SVGA_MODE = normal */
+static int is_zimage = 0;
+static int image_length; /* Length of image in sectors */
+static long image_size; /* Length of image file in bytes */
+
static char * read_cmdfile();
static char * input_cmd();
+#define ZIMAGE_LOAD_SEG 0x1000 /* Segment that zImage data is loaded */
+#define COMMAND_LINE_POS 0x4000 /* Offset in segment 0x9000 of command line */
+
+int has_command_line = 0;
+
cmd_bzimage(ptr)
char * ptr;
{
@@ -58,12 +68,13 @@ char * command_line;
printf("Loading %s\n", fname);
- if( read_block(buffer) < 0 || check_magics(buffer) < 0 )
+ if( read_block(buffer) < 0 || check_magics(fname, buffer) < 0 )
{
- printf("File %s isn't a bzImage.\n", fname);
+ printf("Cannot execute file %s\n", fname);
return -1;
}
+#ifndef __ELKS__
if( boot_mem_top < 0x9500 )
{
printf("There must be 640k of boot memory to load Linux\n");
@@ -74,7 +85,7 @@ char * command_line;
* I expect we could lookup the size in the gzip header but
* this is probably close enough (3*the size of the bzimage)
*/
- len = file_length() * 3 / 1024;
+ len = (image_size=file_length()) * 3 / 1024;
if( main_mem_top < len )
{
printf("This kernel needs at least %ld.%ldM of main memory\n",
@@ -83,12 +94,29 @@ char * command_line;
}
if( main_mem_top < 3072 )
printf("RTFM warning: Linux really needs at least 4MB of memory.\n");
+#endif
- low_sects = buffer[497] + 1; /* setup sects + boot sector */
+ low_sects = buffer[497] + 1; /* setup sects + boot sector */
+ image_length = (file_length()+511)/512 - low_sects;
address = 0x900;
+#ifndef __ELKS__
+ if( is_zimage )
+ {
+ relocator(8); /* Need space in low memory */
+
+ if( image_length > (__get_cs()>>5) - ZIMAGE_LOAD_SEG/32 )
+ {
+ printf("This zImage file is too large, maximum is %ld bytes\n",
+ ((__get_cs()>>5) - ZIMAGE_LOAD_SEG/32 + low_sects)*512L );
+ return -1;
+ }
+ }
+#endif
+
/* load the blocks */
rewind_file();
+ reset_crc();
for(len = file_length(); len>0; len-=1024)
{
int v;
@@ -109,6 +137,7 @@ char * command_line;
return -1;
}
+ if( len > 1024 ) addcrc(buffer, 1024); else addcrc(buffer, (int)len);
for(v=0; v<1024; v+=512)
{
if( putsect(buffer+v, address) < 0 )
@@ -119,10 +148,15 @@ char * command_line;
if( low_sects )
{
low_sects--;
- if( low_sects == 0 ) address = 0x1000;
+ if( low_sects == 0 )
+ {
+ if( is_zimage ) address = ZIMAGE_LOAD_SEG/16;
+ else address = 0x1000;
+ }
}
}
}
+ display_crc();
/* Yesss, loaded! */
printf("Loaded, "); fflush(stdout);
@@ -135,6 +169,14 @@ char * command_line;
if( load_initrd(address) < 0 )
return -1;
+ check_crc();
+
+ if( is_zimage )
+ {
+ printf("Sorry, zImage's don't seem to be working at the moment.\n");
+ if( !keep_going() ) return -1;
+ }
+
printf("Starting ...\n");
if( x86 < 3 )
@@ -156,9 +198,39 @@ char * command_line;
if( !keep_going() ) return -1;
}
- /* Patch setup to deactivate safety switch */
+#ifdef __ELKS__
+ printf("Cannot start.\n");
+ return -1;
+#endif
+
__set_es(0x9000);
- __poke_es(0x210, 0xFF);
+
+ /* Save pointer to command line */
+ if( has_command_line )
+ {
+ __doke_es(0x0020, 0xA33F);
+ __doke_es(0x0022, COMMAND_LINE_POS);
+ }
+
+#if ZIMAGE_LOAD_SEG != 0x1000
+ if( is_zimage )
+ {
+#if ZIMAGE_LOAD_SEG != 0x100
+ /* Tell setup that we've loaded the kernel somewhere */
+ __poke_es(0x20C, ZIMAGE_LOAD_SEG);
+#else
+ /* Tell setup it's a bzImage _even_ tho it's a _zImage_ because we have
+ * actually loaded it where it's supposed to end up!
+ */
+ __poke_es(0x211, __peek_es(0x211)|1);
+
+ __poke_es(0x210, 0xFF); /* Patch setup to deactivate safety switch */
+#endif
+ }
+#endif
+
+ if( !is_zimage )
+ __poke_es(0x210, 0xFF); /* Patch setup to deactivate safety switch */
/* Set SVGA_MODE if not 'normal' */
if( vga_mode != -1 ) __doke_es(506, vga_mode);
@@ -178,6 +250,8 @@ char * command_line;
mov ax,$9000
mov bx,$4000-12 ! Fix this to use boot_mem_top
mov es,ax
+ mov fs,ax
+ mov gs,ax
mov ds,ax
mov ss,ax
mov sp,bx
@@ -186,51 +260,63 @@ char * command_line;
}
}
-check_magics(buffer)
+check_magics(fname, buffer)
+char * fname;
char * buffer;
{
+ is_zimage = 0;
+
/* Boot sector magic number */
- if( *(unsigned short*)(buffer+510) != 0xAA55 ) return -1;
+ if( *(unsigned short*)(buffer+510) != 0xAA55 ||
/* Setup start */
- if( memcmp(buffer+0x202, "HdrS", 4) != 0 ) return -1;
+ memcmp(buffer+0x202, "HdrS", 4) != 0 ||
/* Setup version */
- if( *(unsigned short*)(buffer+0x206) < 0x200 ) return -1;
-
- /* Check load flags for bzImage */
- if( (buffer[0x211] & 1) == 0 ) return -1;
+ *(unsigned short*)(buffer+0x206) < 0x200 )
+ {
+ printf("File %s is not a linux Image file\n", fname);
+ return -1;
+ }
- /* Code 32 start address */
- if( *(unsigned long*)(buffer+0x214) != 0x100000 ) return -1;
+ /* Code 32 start address for zImage */
+ if( *(unsigned long*)(buffer+0x214) == 0x1000 )
+ {
+ printf("File %s is a zImage file\n", fname);
+ is_zimage = 1;
+ return 0;
+ }
+ else
+ /* Code 32 start address bzImage */
+ if( *(unsigned long*)(buffer+0x214) != 0x100000 )
+ {
+ printf("File %s is not a bzImage file\n", fname);
+ return -1;
+ }
+ printf("File %s is a bzImage file\n", fname);
return 0;
}
+#ifndef __ELKS__
putsect(buffer, address)
char * buffer;
unsigned int address;
{
int rv, tc=3;
+ /* In real mode memory, just put it directly */
+ if( address < 0xA00 )
+ {
+ __movedata(__get_ds(), buffer, address*16, 0, 512);
+ return 0;
+ }
+
retry:
tc--;
#if 1
if( x86_emu )
- {
-static unsigned int last_address = 0;
- if( address <= last_address )
- printf("Problem %d<=%d\n", address, last_address);
- if( address < 0xA00 )
- {
- int i;
- __set_es(address*16);
- for(i=0; i<512; i++)
- __poke_es(i, buffer[i]);
- }
- else
- printf("In EMU can't write to 0x%x\n", address);
- return 0;
- }
+ return 0; /* In an EMU we can't write to high mem but
+ we'll pretend we can for debuggering */
#endif
if( (rv=ext_put(buffer, address, 512)) != 0 )
{
@@ -261,6 +347,7 @@ static unsigned int last_address = 0;
}
return 0;
}
+#endif
static char *
read_cmdfile(iname, extno)
@@ -353,6 +440,8 @@ static char * image_str = "BOOT_IMAGE=";
char * free_app = 0;
char * free_dfl = 0;
+ has_command_line = 0;
+
if( append == 0 )
append = free_app = read_cmdfile(image, 2);
@@ -447,11 +536,18 @@ static char * image_str = "BOOT_IMAGE=";
len = 2048;
}
+#ifdef __ELKS__
+ fprintf(stderr, "Command line: '%s'\n", ptr+1);
+#else
+/*
__set_es(0x9000);
__doke_es(0x0020, 0xA33F);
- __doke_es(0x0022, 0x4000);
+ __doke_es(0x0022, COMMAND_LINE_POS);
+*/
- __movedata(__get_ds(), (unsigned)ptr+1, 0x9000, 0x4000, len);
+ __movedata(__get_ds(), (unsigned)ptr+1, 0x9000, COMMAND_LINE_POS, len);
+ has_command_line = 1;
+#endif
free(ptr);
@@ -555,3 +651,38 @@ unsigned int k_top;
return 0;
}
+
+check_crc()
+{
+ char buffer[512];
+ int low_sects;
+ unsigned int address = 0x900;
+ long len;
+
+ if( !is_zimage ) return;
+
+ reset_crc();
+
+ __movedata(address*16, 0, __get_ds(), buffer, 512);
+ low_sects = buffer[497] + 1; /* setup sects + boot sector */
+
+ for(len=image_size; len>0; len-=512)
+ {
+ if( address >= 0xA00 ) return;
+ __movedata(address*16, 0, __get_ds(), buffer, 512);
+
+ if( len > 512 ) addcrc(buffer, 512); else addcrc(buffer, (int)len);
+
+ address += 2;
+ if( low_sects )
+ {
+ low_sects--;
+ if( low_sects == 0 )
+ {
+ if( is_zimage ) address = ZIMAGE_LOAD_SEG/16;
+ else address = 0x1000;
+ }
+ }
+ }
+ display_crc();
+}
diff --git a/bootblocks/fs.c b/bootblocks/fs.c
new file mode 100644
index 0000000..64a3783
--- /dev/null
+++ b/bootblocks/fs.c
@@ -0,0 +1,81 @@
+
+#ifdef __ELKS__
+#include <stdio.h>
+#endif
+#include "readfs.h"
+
+int fs_type = 0;
+
+open_file(fname)
+char * fname;
+{
+#ifdef __ELKS__
+ fprintf(stderr, "Open file %s\n", fname);
+#endif
+ if( fs_type ) close_file();
+
+ if( tar_open_file(fname) >= 0 ) { fs_type = 1; return 0; }
+ if( min_open_file(fname) >= 0 ) { fs_type = 2; return 0; }
+ if( dos_open_file(fname) >= 0 ) { fs_type = 3; return 0; }
+ return -1;
+}
+
+rewind_file()
+{
+#ifdef __ELKS__
+ fprintf(stderr, "Rewind file (%d)\n", fs_type);
+#endif
+ switch(fs_type)
+ {
+ case 1: return tar_rewind_file();
+ case 2: return min_rewind_file();
+ case 3: return dos_rewind_file();
+ }
+ return -1;
+}
+
+close_file()
+{
+ int rv;
+#ifdef __ELKS__
+ fprintf(stderr, "Close file (%d)\n", fs_type);
+#endif
+ switch(fs_type)
+ {
+ case 1: rv = tar_close_file(); break;
+ case 2: rv = min_close_file(); break;
+ case 3: rv = dos_close_file(); break;
+ }
+ fs_type = 0;
+ return -1;
+}
+
+long
+file_length()
+{
+#ifdef __ELKS__
+ fprintf(stderr, "File length (%d)\n", fs_type);
+#endif
+ switch(fs_type)
+ {
+ case 1: return tar_file_length();
+ case 2: return min_file_length();
+ case 3: return dos_file_length();
+ }
+ return -1;
+}
+
+read_block(buffer)
+char * buffer;
+{
+#ifdef __ELKS__
+ fprintf(stderr, "read block into (%d) (%d)\n", buffer, fs_type);
+#endif
+ switch(fs_type)
+ {
+ case 1: return tar_read_block(buffer);
+ case 2: return min_read_block(buffer);
+ case 3: return dos_read_block(buffer);
+ }
+ return -1;
+}
diff --git a/bootblocks/dosfs.c b/bootblocks/fs_dos.c
index b9a2c04..d2ca5eb 100644
--- a/bootblocks/dosfs.c
+++ b/bootblocks/fs_dos.c
@@ -1,10 +1,11 @@
-#ifdef __STANDALONE__
-
+#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include "readfs.h"
+#define DONT_BUFFER_FAT
+
#define DOS_SECT(P) get_uint(P,0x0B)
#define DOS_CLUST(P) get_byte(P,0x0D)
#define DOS_RESV(P) get_uint(P,0x0E)
@@ -25,23 +26,16 @@
#define get_uint(P,Off) *((unsigned short*)((char*)(P)+(Off)))
#define get_long(P,Off) *((long*)((char*)(P)+(Off)))
-static int alloc_trackbuf();
-static char * read_sector();
static int read_bootblock();
-
-int disk_drive = 0;
-
-static int track_number = -1;
-static char * track_buffer = 0;
-static int track_len = 0;
-static int disk_spt = -1;
-static int disk_heads = 2;
-
static int dir_nentry, dir_sect;
-static int dos_clust0, dos_spc;
+static int dos_clust0, dos_spc, dos_fatpos;
+static int last_serial = 0;
+#ifdef BUFFER_FAT
static char * fat_buf = 0;
+#endif
+static
struct filestatus {
char fname[12];
unsigned short first_cluster;
@@ -51,7 +45,7 @@ struct filestatus {
}
cur_file = { "", 0, 0, 0 };
-open_file(fname)
+dos_open_file(fname)
char * fname;
{
extern union REGS __argr;
@@ -60,7 +54,11 @@ char * fname;
int i;
int dodir = 0;
- if(strcmp(fname, ".") == 0) dodir = 1;
+ /* Get the superblock */
+ if( read_bootblock() < 0 ) return -1;
+
+ if(strcmp(fname, ".") == 0)
+ dodir = 1;
else
{
/* Convert the name to MSDOS directory format */
@@ -83,22 +81,13 @@ char * fname;
/* Already opened ? Then just rewind it */
if( cur_file.first_cluster && strcmp(cur_file.fname, conv_name) == 0 )
- return rewind_file();
+ return dos_rewind_file();
}
memset(&cur_file, '\0', sizeof(cur_file));
- /* Get the superblock */
+#ifdef BUFFER_FAT
s = read_sector(0);
- if( s == 0 ) return -1;
-
- /* Collect important data */
- dir_sect = DOS_RESV(s) + DOS_NFAT(s)*DOS_FATLEN(s);
- dir_nentry = DOS_NROOT(s);
-
- dos_spc = DOS_CLUST(s);
- if( dos_spc < 1 ) dos_spc = 1;
- dos_clust0 = dir_sect + (dir_nentry+15)/16 - 2*dos_spc;
if( !dodir )
{
@@ -119,6 +108,7 @@ char * fname;
}
}
}
+#endif
/* Scan the root directory for the file */
for(i=0; i<dir_nentry; i++)
@@ -129,6 +119,9 @@ char * fname;
if( dodir )
{
char dtime[20];
+ char lbuf[90];
+ *lbuf = 0;
+
sprintf(dtime, " %02d/%02d/%04d %02d:%02d",
(get_uint(d,24)&0x1F),
((get_uint(d,24)>>5)&0xF),
@@ -149,6 +142,7 @@ char * fname;
printf("%-11.11s <LBL> %s\n", d, dtime);
break;
}
+ if( more_strn(lbuf, sizeof(lbuf)) < 0 ) break;
}
else if( memcmp(d, conv_name, 11) == 0 && (d[11]&0x18) == 0 )
{ /* Name matches and is normal file */
@@ -159,6 +153,12 @@ char * fname;
cur_file.cur_cluster = cur_file.first_cluster;
cur_file.sector_no = 0;
+#ifdef __ELKS__
+ fprintf(stderr, "Opened first cluster %d, len %ld\n",
+ cur_file.first_cluster,
+ cur_file.file_length
+ );
+#endif
return 0;
}
@@ -166,7 +166,7 @@ char * fname;
return -1;
}
-rewind_file()
+dos_rewind_file()
{
/* Is there an opened file ? */
if( cur_file.fname[0] == 0 ) return -1;
@@ -176,22 +176,20 @@ rewind_file()
return 0;
}
-close_file()
+dos_close_file()
{
+#ifdef BUFFER_FAT
if( fat_buf ) free(fat_buf);
- if( track_buffer ) free(track_buffer);
- memset(&cur_file, '\0', sizeof(cur_file));
fat_buf = 0;
- track_buffer = 0;
- track_len = 0;
- track_number = -1;
- disk_spt = -1;
- disk_heads = 2;
+#endif
+ memset(&cur_file, '\0', sizeof(cur_file));
+
+ reset_disk();
return 0;
}
long
-file_length()
+dos_file_length()
{
/* Is there an opened file ? */
if( cur_file.fname[0] == 0 ) return -1;
@@ -199,17 +197,30 @@ file_length()
return cur_file.file_length;
}
-read_block(buffer)
+dos_read_block(buffer)
char * buffer;
{
int s;
char * ptr;
/* Is there an opened file ? */
- if( cur_file.fname[0] == 0 ) return -1;
+ if( cur_file.fname[0] == 0 )
+ {
+#ifdef __ELKS__
+ fprintf(stderr, "File is not currently open!\n");
+#endif
+ return -1;
+ }
/* Are we before the EOF ? NB: FAT12 ONLY! */
- if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) return -1;
+ if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 )
+ {
+#ifdef __ELKS__
+ fprintf(stderr, "Hit end of file; cluster 0x%03x\n",
+ cur_file.cur_cluster);
+#endif
+ return -1;
+ }
for(s=0; s<2; s++)
{
@@ -234,16 +245,30 @@ char * buffer;
if( cur_file.sector_no % dos_spc == 0 )
{
int odd = (cur_file.cur_cluster&1);
- unsigned int val;
+ unsigned int val, val2;
val = cur_file.cur_cluster + (cur_file.cur_cluster>>1);
- val = get_uint(fat_buf, val);
+#ifdef BUFFER_FAT
+ val2 = get_uint(fat_buf, val);
+#else
+ ptr = read_sector(dos_fatpos+(val/512));
+ if( ptr == 0 ) return -1;
+ if( val%512 == 511 )
+ {
+ val2 = (ptr[511]&0xFF);
+ ptr = read_sector(dos_fatpos+(val/512)+1);
+ if( ptr == 0 ) return -1;
+ val2 |= (ptr[0]<<8);
+ }
+ else
+ val2 = get_uint(ptr, (val%512));
+#endif
- if( odd ) val>>=4;
+ if( odd ) val2>>=4;
- val &= 0xFFF;
+ val2 &= 0xFFF;
- cur_file.cur_cluster = val;
+ cur_file.cur_cluster = val2;
}
buffer += 512;
@@ -252,167 +277,41 @@ char * buffer;
return 0;
}
-static char * read_sector(sectno)
-int sectno;
-{
- int track_no, track_off, track_start, linsect;
- if( disk_spt == -1 && read_bootblock() < 0 ) return 0;
-
- track_no = sectno / track_len;
- track_off= sectno % track_len;
-
- if( track_no != track_number )
- {
- track_number = -1;
- track_start = track_no * track_len;
-
- for(linsect=0; linsect<track_len; linsect++)
- {
- if( raw_read(disk_drive, track_start+linsect,
- track_buffer+linsect*512) <0 )
- return 0;
- }
- if( raw_read(disk_drive, 0, 0) <0 )
- return 0;
-
- track_number = track_no;
- }
- return track_buffer + 512*track_off;
-}
-
-static int raw_read(drive, linsect, buffer)
-int drive, linsect;
-char * buffer;
-{
-static char * pend_buf = 0, *buf_start = 0;
-static int pend_s, pend_h, pend_c, pend_len = 0;
-
- int phy_s = linsect%disk_spt;
- int phy_h = linsect/disk_spt%disk_heads;
- int phy_c = linsect/disk_spt/disk_heads;
- int tries = 5;
- int rv = 0;
-
- if( buffer != pend_buf ||
- pend_s+pend_len != phy_s ||
- pend_h != phy_h ||
- pend_c != phy_c )
- {
- if( buf_start ) do
- {
- rv = phy_read(drive, pend_c, pend_h, pend_s+1, pend_len, buf_start);
- tries--;
- if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
- drive, pend_c, pend_h, pend_s+1, pend_len, buf_start);
- }
- while(rv && tries > 0);
-
- pend_c = phy_c;
- pend_h = phy_h;
- pend_s = phy_s;
- pend_len = 0;
- pend_buf = buf_start = buffer;
- }
-
- pend_len++;
- pend_buf += 512;
-
- return rv;
-}
-
static int read_bootblock()
{
- char * sptr;
- int rv, media_byte = 0;
- if( alloc_trackbuf(2) ) return -1;
-
- disk_spt = 2;
- sptr = read_sector(1);
- disk_spt = -1;
- if( sptr == 0 ) return -1;
- media_byte = *(unsigned char*)sptr;
-
- /* Valid media byte ? */
- if( (media_byte & 0xF0) != 0xF0 ) return -1;
- disk_spt = 2;
- sptr = read_sector(0);
- disk_spt = -1;
- if( sptr == 0 ) return -1;
-
- if( DOS_MEDIA(sptr) != media_byte ) return -1;
- if( DOS_SPT(sptr) > 63 ) return -1;
- if( DOS_SECT(sptr) != 512 ) return -1;
-
- disk_spt = DOS_SPT(sptr);
- disk_heads = DOS_HEADS(sptr);
-
- rv = alloc_trackbuf(disk_spt*disk_heads); /* Cylinder buffer */
- if( rv < 0 ) rv = alloc_trackbuf(disk_spt); /* Track buffer */
- if( rv < 0 ) rv = alloc_trackbuf(disk_spt/2); /* 1/2 Track buffer */
- if( rv < 0 ) rv = alloc_trackbuf(2); /* Block buffer */
- if( rv < 0 ) disk_spt = -1;
- return rv;
-}
+ char * sptr;
+ int rv, media_byte = 0;
-static int alloc_trackbuf(sectors)
-int sectors;
-{
- char * new_track;
- int seg_start, seg_end;
- if( sectors <= track_len ) return 0;
+ sptr = read_sector(1);
+ if( sptr == 0 ) return -1;
+ media_byte = *(unsigned char*)sptr;
+
+ /* Valid media byte ? */
+ if( (media_byte & 0xF0) != 0xF0 ) return -1;
+ sptr = read_sector(0);
+ if( sptr == 0 ) return -1;
- if( track_buffer ) free(track_buffer);
- track_buffer = 0;
- track_len = 0;
- track_number = -1;
+ if( DOS_MEDIA(sptr) != media_byte ) return -1;
+ if( DOS_SPT(sptr) > 63 ) return -1;
+ if( DOS_SECT(sptr) != 512 ) return -1;
- if( sectors < 1 || sectors > 63 ) /* WTF! */ return -1;
+ if( last_serial != DOS4_SERIAL(sptr) ) dos_close_file();
+ last_serial = DOS4_SERIAL(sptr);
- new_track = malloc(sectors*512);
- if( new_track == 0 ) return -1;
+ /* Collect important data */
+ dir_sect = DOS_RESV(sptr) + DOS_NFAT(sptr)*DOS_FATLEN(sptr);
+ dir_nentry = DOS_NROOT(sptr);
- seg_start = __get_ds() + (unsigned int)new_track / 16;
- seg_end = __get_ds() + (unsigned int)(new_track+sectors*512-1) / 16;
+ dos_fatpos = DOS_RESV(sptr);
+ dos_spc = DOS_CLUST(sptr);
+ if( dos_spc < 1 ) dos_spc = 1;
+ dos_clust0 = dir_sect + (dir_nentry+15)/16 - 2*dos_spc;
- if( (seg_start&0xF000) != (seg_end&0xF000) ) /* Bugger */
+ if( disk_cyls == 0 )
{
- int rv = alloc_trackbuf(sectors);
- free(new_track);
- return rv;
+ disk_spt = DOS_SPT(sptr);
+ disk_heads = DOS_HEADS(sptr);
}
- track_len = sectors;
- track_buffer = new_track;
return 0;
}
-
-#endif
-
-#if defined(__MSDOS__) || defined(__STANDALONE__)
-phy_read(drive, cyl, head, sect, length, buffer)
-{
-#asm
- push bp
- mov bp,sp
-
- push ds
- pop es
-
- mov dl,[bp+2+_phy_read.drive]
- mov ch,[bp+2+_phy_read.cyl]
- mov dh,[bp+2+_phy_read.head]
- mov cl,[bp+2+_phy_read.sect]
- mov al,[bp+2+_phy_read.length]
- mov bx,[bp+2+_phy_read.buffer]
-
- mov ah,#$02
- int $13
- jc read_err
- mov ax,#0
-read_err:
-
- pop bp
-#endasm
-}
-#endif
-
diff --git a/bootblocks/fs_min.c b/bootblocks/fs_min.c
new file mode 100644
index 0000000..78a5fc9
--- /dev/null
+++ b/bootblocks/fs_min.c
@@ -0,0 +1,31 @@
+
+#include "readfs.h"
+
+min_open_file(fname)
+char * fname;
+{
+ return -1;
+}
+
+min_rewind_file()
+{
+ return -1;
+}
+
+min_close_file()
+{
+ return -1;
+}
+
+long
+min_file_length()
+{
+ return -1;
+}
+
+min_read_block(buffer)
+char * buffer;
+{
+ return -1;
+}
+
diff --git a/bootblocks/fs_tar.c b/bootblocks/fs_tar.c
new file mode 100644
index 0000000..278c8c1
--- /dev/null
+++ b/bootblocks/fs_tar.c
@@ -0,0 +1,156 @@
+
+#ifdef __ELKS__
+#include <stdio.h>
+#endif
+
+#include <dos.h>
+#include "readfs.h"
+
+#define HEADER_SIZE 512
+#define NAME_SIZE 100
+#define BLOCK_BOUNDARY 20
+
+typedef union {
+ char hdr_block[HEADER_SIZE];
+ struct m {
+ char m_name[NAME_SIZE];
+ char m_mode[8];
+ char m_uid[8];
+ char m_gid[8];
+ char m_size[12];
+ char m_time[12];
+ char m_checksum[8];
+ char m_linked;
+ char m_link[NAME_SIZE];
+ } member;
+} HEADER;
+
+#ifdef __STANDALONE__
+extern union REGS __argr;
+#endif
+
+tar_open_file(fname)
+char * fname;
+{
+ HEADER * sptr;
+
+#ifdef __STANDALONE__
+ if( disk_drive != __argr.h.dl ) return -1; /* Only the one booted off */
+ if( __argr.x.si < 9 || __argr.x.si > 63 ) return -1; /* SPT good */
+#endif
+
+ sptr = read_sector(0);
+
+ /* Boot sector a volume label ? */
+ if( sptr->member.m_linked != 'V' ) return -1;
+ if( !valid_tar_checksum(sptr) ) return -1;
+
+#ifdef __STANDALONE__
+ disk_spt = __argr.x.si;
+#else
+ disk_spt = 18; /* Testing only */
+#endif
+
+#ifdef __ELKS__
+ fprintf(stderr, "Got vaild tar header\n");
+#endif
+
+ return -1;
+}
+
+tar_rewind_file()
+{
+ return -1;
+}
+
+tar_close_file()
+{
+ return -1;
+}
+
+long
+tar_file_length()
+{
+ return -1;
+}
+
+tar_read_block(buffer)
+char * buffer;
+{
+ return -1;
+}
+
+long
+tar_convert(str, type)
+char str[];
+int type;
+{
+ register long ac = 0L;
+ register int i;
+
+ for (i = 0; i < type; i++)
+ {
+ if (str[i] >= '0' && str[i] <= '7')
+ {
+ ac <<= 3;
+ ac += (long) (str[i] - '0');
+ }
+ }
+ return ac;
+}
+
+valid_tar_checksum(sptr)
+HEADER * sptr;
+{
+ register char *ptr;
+ register int ac = 0;
+
+ ptr = sptr->hdr_block;
+ while (ptr < sptr->hdr_block+sizeof(sptr->hdr_block))
+ if( ptr < sptr->member.m_checksum ||
+ ptr >= sptr->member.m_checksum+sizeof(sptr->member.m_checksum))
+ ac += (*ptr++ & 0xFF);
+ else
+ ptr++, (ac += ' ');
+
+ ac -= tar_convert(sptr->member.m_checksum, sizeof(sptr->member.m_checksum));
+ return ac == 0;
+}
+
+#if 0
+
+#asm
+!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+!
+! These are the number of sectors per track that will be scanned for.
+! For 3.5 inch floppies 36 is 2.88 Mb, 18 is 1.44Mb, 21 is 1.68Mb on
+! a 1.44Mb floppy drive. 15 and 9 are for 5.25 inch floppies.
+
+disksizes: .byte 36,21,18,15,9
+
+! It seems that there is no BIOS call to get the number of sectors. Guess
+! 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
+! 15 if sector 15 can be read. Otherwise guess 9.
+
+export _probe_sectors
+_probe_sectors:
+ mov si,#disksizes ! table of sizes to try
+
+probe_loop:
+ lodsb
+ cbw ! extend to word
+ mov _disk_spt, ax
+ cmp al,#9
+ je got_sectors ! if all else fails, try 9
+ xchg ax, cx ! cx = track and sector
+ xor dx, dx ! drive 0, head 0
+ mov bx,#probe_buf ! address after setup (es = cs)
+ mov ax,#0x0201 ! service 2, 1 sector
+ int 0x13
+ jc probe_loop ! try next value
+got_sectors:
+
+ ret
+#endasm
+
+#endif
diff --git a/bootblocks/i86_funcs.c b/bootblocks/i86_funcs.c
index c17a158..b9ea180 100644
--- a/bootblocks/i86_funcs.c
+++ b/bootblocks/i86_funcs.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <errno.h>
+#include <dos.h>
#include "i86_funcs.h"
int x86 = 0; /* CPU major number */
diff --git a/bootblocks/makeboot.c b/bootblocks/makeboot.c
index 4a036a6..b844ba8 100644
--- a/bootblocks/makeboot.c
+++ b/bootblocks/makeboot.c
@@ -8,6 +8,8 @@
#include "msdos.v"
#include "skip.v"
#include "tarboot.v"
+#include "minix.v"
+#include "minixhd.v"
char buffer[1024];
@@ -16,20 +18,24 @@ char buffer[1024];
#define FS_DOS 2 /* Bootsector needs any DOS FS */
#define FS_TAR 3 /* Bootsector needs GNU-tar volume label */
#define FS_STAT 4 /* DOS bootsector is checked */
+#define FS_ZERO 5 /* Boot sector must be Zapped */
struct bblist {
char * name;
+ char * desc;
char * data;
+ int size;
int fstype;
- char * desc;
} bblocks[] = {
- { "tar", tarboot_data, FS_TAR, "Bootable GNU tar volume lable" },
- { "dosfs", msdos_data, FS_ADOS, "Boots file BOOTFILE.SYS from dosfs" },
- { "none", noboot_data, FS_DOS, "No OS bookblock, just message" },
- { "skip", skip_data, FS_DOS, "Bypasses floppy boot with message" },
- { "stat", 0, FS_STAT, "Display dosfs superblock" },
- { "copy", 0, FS_STAT, "Copy boot block to makeboot.sav" },
- { "Zap", 0, FS_NONE, "Clear boot block to NULs" },
+{ "tar", "Bootable GNU tar volume lable", tarboot_data, tarboot_size, FS_TAR},
+{ "dosfs","Boot file BOOTFILE.SYS from dosfs", msdos_data, msdos_size, FS_ADOS},
+{ "none", "No OS bootblock, just message", noboot_data, noboot_size, FS_DOS},
+{ "skip", "Bypasses floppy boot with message", skip_data, skip_size, FS_DOS},
+{ "minix","Minix floppy FS booter", minix_data, minix_size, FS_ZERO},
+{ "hdmin","Minix Hard disk FS booter", minixhd_data, minixhd_size, FS_ZERO},
+{ "stat", "Display dosfs superblock", 0, 0, FS_STAT},
+{ "copy", "Copy boot block to makeboot.sav", 0, 0, FS_STAT},
+{ "Zap", "Clear boot block to NULs", 0, 1024, FS_NONE},
0
};
@@ -43,6 +49,9 @@ 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 */
main(argc, argv)
int argc;
@@ -70,6 +79,9 @@ char ** argv;
exit(1);
read_sector(1, buffer+512);
+ write_zero = (ptr->size >= 512);
+ write_one = (ptr->size >= 1024);
+
switch(ptr->fstype)
{
case FS_NONE: /* override */
@@ -84,6 +96,9 @@ char ** argv;
case FS_TAR:
check_tar();
break;
+ case FS_ZERO:
+ check_zapped();
+ break;
default:
fprintf(stderr, "Program error, unknown filesystem requirement\n");
@@ -114,11 +129,23 @@ char ** argv;
if( ptr->data )
memcpy(buffer, ptr->data, 512);
else
- memset(buffer, '\0', 512);
+ {
+ memset(buffer, '\0', 1024);
+ write_one = 1;
+ }
break;
}
- write_sector(0, buffer);
+ 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);
+ }
close_disk();
exit(0);
}
@@ -310,6 +337,22 @@ write_err:
/**************************************************************************/
+check_zapped()
+{
+ int i;
+ for(i=0; i<512; i++)
+ if( buffer[i] )
+ break;
+
+ if( i != 512 )
+ {
+ fprintf(stderr, "Boot block isn't empty, zap it first\n");
+ if(!force) exit(1);
+ }
+}
+
+/**************************************************************************/
+
struct tar_head {
char name[100];
char mode[8];
@@ -363,6 +406,9 @@ not_zapped:
{
fprintf(stderr, "TAR file checksum failed, this isn't a tar file.\n");
if(!force) exit(9);
+
+ write_one = 1;
+ memset(buffer, '\0', 1024);
}
if( buff_tar.linkflag != 'V' )
{
@@ -577,6 +623,28 @@ check_msdos()
disk_head = dosflds[DOS_HEADS].value;
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 ) )
+ {
+ printf("Bad 2nd boot block - reloading first\n");
+ if( read_sector(0, buffer) != 0 )
+ exit(1);
+ }
+ check_msdos();
+ }
+#endif
return;
}
if(!force) exit(2);
@@ -620,3 +688,263 @@ check_simpledos()
}
/**************************************************************************/
+
+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
+};
+
+do_2m_write()
+{
+ int i;
+ if( !force && ( disk_trck != 82 || disk_sect != 22 ))
+ {
+ fprintf(stderr, "A bootable 2M disk must be 22 sectors 82 tracks\n");
+ exit(1);
+ }
+ write_sector(bs_offset, buffer);
+
+ /* This needs to be altered to allow for the disk format description to
+ be cpied from the old boot sector */
+
+ for(i=0; i<sysboot_dosfs_stat; i++)
+ buffer[i] = boot_sector_2m_22_82[i];
+ for(i=sysboot_codestart; i<512; i++)
+ buffer[i] = boot_sector_2m_22_82[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);
+ }
+}
diff --git a/bootblocks/mbr.s b/bootblocks/mbr.s
index f6a8048..ddd406f 100644
--- a/bootblocks/mbr.s
+++ b/bootblocks/mbr.s
@@ -14,6 +14,11 @@ preboot=0 ! Include the pre-boot loader ?
org ORGADDR
include sysboot.s
+public partition_1
+public partition_2
+public partition_3
+public partition_4
+
org ORGADDR+$3
.ascii "ELKS MBR Copyright 1996, Robert de Bath"
diff --git a/bootblocks/monitor.c b/bootblocks/monitor.c
index 5c78aaf..084f301 100644
--- a/bootblocks/monitor.c
+++ b/bootblocks/monitor.c
@@ -44,12 +44,20 @@ static char minibuf[2] = " ";
struct t_cmd_list * cptr;
#ifdef __STANDALONE__
- printf("\n\n");
+ printf("\r");
#else
if( argc > 1 && strcmp(argv[1], "-t") == 0 ) x86_test=0; else x86_test=1;
#endif
init_prog();
+ if( __get_ds() != 0x1000 )
+ {
+ relocator(-1);
+ relocator(1);
+ if( __get_ds() > 0x1000 ) relocator(2);
+ printf("Relocated to CS=$%04x DS=%04x\n", __get_cs(), __get_ds());
+ }
+
#ifdef __STANDALONE__
if( (__argr.x.dx & 0xFF) == 0 )
#endif
@@ -254,6 +262,38 @@ unsigned int * valptr;
return flg;
}
+more_char(ch)
+int ch;
+{
+static int line_number = 0;
+
+ if( ch == -1 ) { line_number = 0; return 0; }
+
+ if( (ch & 0xE0 ) || ch == '\n' )
+ putchar(ch);
+ if( ch == '\n' && ++line_number == 24)
+ {
+ char buf[4];
+ printf("More ?"); fflush(stdout);
+ if( read(0, buf, 1) <= 0 ) return -1;
+ if( buf[0] == 3 || buf[0] == '\033'
+ || buf[0] == 'q' || buf[0] == 'Q' ) return -1;
+ if( buf[0] == '\r' ) line_number--;
+ if( buf[0] == ' ' ) line_number=2;
+ printf("\r \r");
+ }
+ return 0;
+}
+
+more_strn(str, len)
+char * str;
+int len;
+{
+ for(; len>0 && *str ; len--,str++)
+ if( more_char( *str & 0xFF ) < 0 ) return -1;
+ return 0;
+}
+
/****************************************************************************/
int cmd_quit(args)
@@ -337,13 +377,15 @@ int cmd_rel(ptr)
char * ptr;
{
int nseg = 0xFFFF;
+ int cs = __get_cs();
getnum(&ptr, &nseg);
- printf("Monitor code seg from 0x%04x ", __get_cs());
- fflush(stdout);
relocator(nseg);
- printf("to 0x%04x\n", __get_cs());
+ if( __get_cs() == cs )
+ printf("Didn't relocate; CS=$%04x DS=%04x\n", __get_cs(), __get_ds());
+ else
+ printf("Relocated to CS=$%04x DS=%04x\n", __get_cs(), __get_ds());
}
int cmd_dir(ptr)
@@ -373,7 +415,38 @@ char * ptr;
write(1, buffer, len);
}
else
- printf("Cannout open file '%s'\n", fname);
+ printf("Cannot open file '%s'\n", fname);
+ close_file();
+ return 0;
+}
+
+int cmd_more(ptr)
+char * ptr;
+{
+ char * fname;
+ char buffer[1024];
+ long len;
+ int cc;
+ char * sptr;
+
+ while(*ptr == ' ') ptr++;
+ if( (fname=ptr) == 0 ) return 0;
+ while(*ptr & *ptr != ' ') ptr++;
+
+ more_char(-1);
+
+ if( open_file(fname) >= 0 ) for(len=file_length(); len>0; len-=1024)
+ {
+ if( read_block(buffer) < 0 ) break;
+ if( len > 1024 ) cc = 1024; else cc = len;
+ for(sptr=buffer; cc>0 ; cc--,sptr++)
+ {
+ if( more_char(*sptr & 0xFF) < 0 ) goto break_break;
+ }
+ }
+ else
+ printf("Cannot open file '%s'\n", fname);
+break_break:;
close_file();
return 0;
}
@@ -395,8 +468,8 @@ struct t_cmd_list cmd_list[] =
{"bzimage",cmd_bzimage}, /* Load and run 386 bzimage file */
{"=", cmd_bzimage}, /* Load and run 386 bzimage file */
{"dir", cmd_dir}, /* Display directory */
- {"type", cmd_type}, /* Cat/Type a file to the screen */
{"cat", cmd_type}, /* Cat/Type a file to the screen */
+ {"more", cmd_more}, /* More a file to the screen */
/* Debugger/monitor commands */
{"memdump",cmd_memdump}, {"mem",cmd_memdump}, {"m", cmd_memdump},
diff --git a/bootblocks/msdos.s b/bootblocks/msdos.s
index fdded78..a48718c 100644
--- a/bootblocks/msdos.s
+++ b/bootblocks/msdos.s
@@ -65,29 +65,31 @@ bios_disk: .blkb 12
cont:
sti ! Let the interrupts back in.
-! Need to fix BPB for fd0 to correct sectors (Like linux bootblock does)
- mov di,#bios_disk
- mov bp,#0x78
-! 0:bx is parameter table address
- push ds
- lds si,[bp]
-
-! ds:si is source
-
- mov cx,#6
-! copy 12 bytes
- push di
- rep
- movsw
- pop di
- pop ds
-
-! New BPB is 0:di
- mov [bp],di
- mov 2[bp],ax
-
- mov al,[dos_spt] ! Finally, correct spt.
- mov 4[di],al
+! DONT Need to fix BPB for fd0 to correct sectors (Like linux bootblock does)
+! as we only ever read one sector at a time.
+
+! mov di,#bios_disk
+! mov bp,#0x78
+!! 0:bx is parameter table address
+! push ds
+! lds si,[bp]
+!
+!! ds:si is source
+!
+! mov cx,#6
+!! copy 12 bytes
+! push di
+! rep
+! movsw
+! pop di
+! pop ds
+!
+!! New BPB is 0:di
+! mov [bp],di
+! mov 2[bp],ax
+!
+! mov al,[dos_spt] ! Finally, correct spt.
+! mov 4[di],al
! For each sector in root dir
! For each dir entry
diff --git a/bootblocks/nofs.c b/bootblocks/nofs.c
deleted file mode 100644
index e671a69..0000000
--- a/bootblocks/nofs.c
+++ /dev/null
@@ -1,55 +0,0 @@
-
-#ifndef __STANDALONE__
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "readfs.h"
-
-static int fd = -1;
-
-open_file(fname)
-char * fname;
-{
- if( fd >= 0 ) close(fd);
- fd = open(fname, 0);
- if( fd >= 0 ) return 0;
- return -1;
-}
-
-rewind_file()
-{
- if( fd == -1 ) return -1;
- lseek(fd, 0L, 0);
- return 0;
-}
-
-close_file()
-{
- if( fd >= 0 ) close(fd);
- fd = -1;
-}
-
-long
-file_length()
-{
- struct stat st;
- if( fd == -1 ) return -1;
- if( fstat(fd, &st) < 0 ) return -1;
-
- return st.st_size;
-}
-
-read_block(buffer)
-char * buffer;
-{
- int rv;
- if( fd == -1 ) return -1;
-
- rv = read(fd, buffer, 1024);
- if( rv <= 0 ) return -1;
- if( rv < 1024 )
- memset(buffer+rv, '\0', 1024-rv);
- return 0;
-}
-
-#endif
diff --git a/bootblocks/readfs.h b/bootblocks/readfs.h
index aa6b87c..5a52bbb 100644
--- a/bootblocks/readfs.h
+++ b/bootblocks/readfs.h
@@ -15,3 +15,30 @@ int close_file P((void));
long file_length P((void));
int read_block P((char * buffer));
+int tar_open_file P((char * fname));
+int tar_rewind_file P((void));
+int tar_close_file P((void));
+long tar_file_length P((void));
+int tar_read_block P((char * buffer));
+
+int min_open_file P((char * fname));
+int min_rewind_file P((void));
+int min_close_file P((void));
+long min_file_length P((void));
+int min_read_block P((char * buffer));
+
+int dos_open_file P((char * fname));
+int dos_rewind_file P((void));
+int dos_close_file P((void));
+long dos_file_length P((void));
+int dos_read_block P((char * buffer));
+
+#define read_sector(__sect) read_lsector((unsigned long)(__sect))
+char * read_lsector P((long sector));
+void reset_disk P((void));
+
+extern char * track_buffer;
+extern int disk_drive;
+extern int disk_cyls;
+extern int disk_heads;
+extern int disk_spt;
diff --git a/bootblocks/relocate.c b/bootblocks/relocate.c
index 6101296..7f8b124 100644
--- a/bootblocks/relocate.c
+++ b/bootblocks/relocate.c
@@ -1,10 +1,22 @@
-#include <i86_funcs.h>
+#include <stdio.h>
+#include <dos.h>
+#include "i86_funcs.h"
static unsigned memseg = 0, memlen = 0;
char buf[1];
+/* If newseg == 0x0000 => Lowest address CS=$50
+ * If newseg == 0x0001 => DS to 64k position
+ * If newseg == 0x0002 => DS to 128k position
+ * ...
+ * If newseg == 0x0009 => DS to 576k position
+ * If newseg == 0xFFFF => Highest address leaving Linux-i386 clear.
+ *
+ * All others are literal, will fail if would overlap with something important.
+ */
+
void
relocator(newseg)
unsigned newseg;
@@ -27,12 +39,17 @@ unsigned newseg;
__set_es(es);
}
+ if( newseg == 0 ) newseg = 0x50;
+ if( newseg > 0 && newseg < 10 )
+ {
+ newseg = (newseg<<12) - (__get_ds() - __get_cs());
+ }
if( newseg < 0x50 ) return;
if( newseg == 0xFFFF )
{
newseg = boot_mem_top;
- if( newseg > 0x90000 ) newseg = 0x90000;
+ if( newseg > 0x9000 ) newseg = 0x9000;
newseg -= memlen;
}
@@ -44,16 +61,14 @@ unsigned newseg;
for(moved=0; moved < memlen; )
{
unsigned int lump;
- if( memlen <= 0x800 ) lump = memlen; else lump = 0x800;
+ if( memlen-moved <= 0x800 ) lump = memlen-moved; else lump = 0x800;
__movedata(memseg+moved, 0, newseg+moved, 0, (lump<<4));
moved += lump;
}
/* re-link int 0x80, this one is only an example (used by 'standalone.c') */
- /*
- __set_es(0); __doke_es(0x80*4+2, newseg); __set_es(es);
- */
+ /* __set_es(0); __doke_es(0x80*4+2, newseg); __set_es(es); */
/* The actual jump ... */
memseg = newseg;
diff --git a/bootblocks/standalone.c b/bootblocks/standalone.c
index 57634d4..3fb0e28 100644
--- a/bootblocks/standalone.c
+++ b/bootblocks/standalone.c
@@ -1,4 +1,5 @@
+#include <dos.h>
#include <errno.h>
#asm
entry _int_80 ! Tell ld86 we really do need this file.
diff --git a/bootblocks/sysboot.s b/bootblocks/sysboot.s
index ee62e69..c7be509 100644
--- a/bootblocks/sysboot.s
+++ b/bootblocks/sysboot.s
@@ -53,10 +53,6 @@ codestart:
j codestart
! Partition table
-public partition_1
-public partition_2
-public partition_3
-public partition_4
public bootblock_magic
.blkb sysboot_start+0x1BE-*
diff --git a/bootblocks/tarboot.s b/bootblocks/tarboot.s
index be68ecd..2e31570 100644
--- a/bootblocks/tarboot.s
+++ b/bootblocks/tarboot.s
@@ -148,9 +148,7 @@ blk_link: .byte 'V
block blk_mode
public sectors
-sectors: .blkw 1 ! POSITION OF THIS FIELD IS MAGIC!
- ! other programs know it's at pos 100
-
+sectors: .blkw 1 !
bios_disk: .blkb 12 ! BPB for FD0
head: .word 0 ! current head
track: .word 0 ! current track
diff --git a/bootblocks/trk_buf.c b/bootblocks/trk_buf.c
new file mode 100644
index 0000000..3039169
--- /dev/null
+++ b/bootblocks/trk_buf.c
@@ -0,0 +1,275 @@
+
+#include <stdio.h>
+#include <dos.h>
+#include <ctype.h>
+#include <malloc.h>
+#include "readfs.h"
+
+int disk_drive = 0;
+int disk_spt = 7;
+int disk_heads = 2;
+int disk_cyls = 0;
+
+static int last_drive = 0;
+static int data_len = 0;
+static long data_trk1 = 0;
+static char * data_buf1 = 0;
+static long data_trk2 = 0;
+static char * data_buf2 = 0;
+
+static long bad_track = -1; /* Track number of last unsuccesful read */
+
+static long get_dpt();
+
+void reset_disk()
+{
+ if( data_buf1 ) free(data_buf1);
+ if( data_buf2 ) free(data_buf2);
+ data_buf1 = data_buf2 = 0;
+ last_drive = disk_drive;
+
+ if( !(disk_drive & 0x80 ) )
+ {
+ disk_spt = 7; /* Defaults for reading Boot area. */
+ disk_heads = 2;
+ disk_cyls = 0;
+ }
+#if defined(__MSDOS__) || defined(__STANDALONE__)
+ else
+ {
+ /* Hard disk, get parameters from bios */
+ long dpt;
+ int v;
+
+ disk_spt = 17; /* Defaults for reading Boot area. */
+ disk_heads = 1;
+ disk_cyls = 0;
+
+ dpt = get_dpt(disk_drive);
+ v = ((dpt>>16) & 0xFF);
+ if( v == 0xFF || v <= (disk_drive&0x7F) ) return; /* Bad dpt */
+
+ disk_spt = (dpt & 0x3F); /* Max sector number 1-63 */
+ if( disk_spt == 0 ) disk_spt = 64; /* 1-64 ? */
+ disk_heads = ((dpt>>24) & 0xFF) + 1; /* Head count 1-256 */
+ disk_cyls = ((dpt>>8) & 0xFF) + ((dpt<<2) & 0x300) + 1;
+
+ /* Cyls count, unchecked, only needs != 0, if AMI 386 bios can be
+ * upto 4096 cylinder, otherwise BIOS limit is 1024 cyl.
+ */
+ }
+#endif
+}
+
+char * read_lsector(sectno)
+long sectno;
+{
+ int tries = 6;
+ int rv;
+
+ int phy_s = 1;
+ int phy_h = 0;
+ int phy_c = 0;
+
+ if( disk_drive != last_drive ) reset_disk();
+
+ if( disk_spt < 0 || disk_spt > 63 || disk_heads < 1 )
+ {
+ phy_s = sectno;
+ reset_disk();
+
+#ifdef __ELKS__
+ fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n",
+ sectno, phy_c, phy_h, phy_s+1);
+#endif
+ }
+ else
+ {
+ phy_s = sectno%disk_spt;
+ phy_h = sectno/disk_spt%disk_heads;
+ phy_c = sectno/disk_spt/disk_heads;
+
+#ifdef __ELKS__
+ fprintf(stderr, "read_sector(%ld = %d,%d,%d)\n",
+ sectno, phy_c, phy_h, phy_s+1);
+#endif
+
+ if( fetch_track_buf(phy_c, phy_h, phy_s) >= 0 )
+ return data_buf1 + (phy_s % data_len) * 512;
+ }
+
+ data_len = -1; /* Zap the cache */
+ if( data_buf1 == 0 )
+ data_buf1 = malloc(512);
+ if( data_buf1 == 0 )
+ {
+ printf("Cannot allocate memory for disk read!!!\n");
+ return 0;
+ }
+
+#ifdef __ELKS__
+ fprintf(stderr, "WARNING: Single sector read\n");
+#endif
+
+ do
+ {
+ rv = phy_read(disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
+ tries--;
+ if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
+ disk_drive, phy_c, phy_h, phy_s+1, 1, data_buf1);
+ }
+ while(rv && tries > 0);
+
+ if(rv) return 0; else return data_buf1;
+}
+
+fetch_track_buf(phy_c, phy_h, phy_s)
+int phy_c, phy_h, phy_s;
+{
+ long trk_no, t;
+ char * p;
+ int tries = 3;
+ int rv, nlen;
+
+ /* Big tracks get us short of memory so limit it. */
+ nlen = (disk_spt-1)/22;
+ nlen = (disk_spt+nlen)/(nlen+1);
+ trk_no = (long)phy_c*disk_heads*4+phy_h*4+phy_s/nlen+1;
+
+ if( data_len != nlen )
+ {
+ if( data_buf1 ) free(data_buf1);
+ if( data_buf2 ) free(data_buf2);
+ data_buf1 = data_buf2 = 0;
+ data_len = disk_spt;
+ }
+ if( trk_no == bad_track ) return -1;
+
+ if( data_buf1 && trk_no == data_trk1 ) return 0;
+
+ /* Two cases:
+ * 1) buffer2 has the one we want, need to swap to make it most recent
+ * 2) Neither has it, need to swap to overwrite least recent.
+ */
+
+ /* So we always swap */
+ p = data_buf1; data_buf1 = data_buf2; data_buf2 = p;
+ t = data_trk1; data_trk1 = data_trk2; data_trk2 = t;
+
+ /* The other one right ? */
+ if( data_buf1 && trk_no == data_trk1 ) return 0;
+
+ /* If we get here we have to do a physical read ... */
+ /* into data_buf1. */
+
+ if( data_buf1 == 0 )
+ {
+ data_buf1 = malloc(disk_spt*512);
+
+#ifdef __ELKS__
+ fprintf(stderr, "Allocated buffer to %d\n", data_buf1);
+#endif
+ }
+ if( data_buf1 == 0 )
+ {
+ /* Is buf2 allocated ? Yes take it! */
+ data_buf1 = data_buf2; data_buf2 = 0; data_trk2 = -1;
+ }
+
+ bad_track = -1;
+ data_trk1 = -1;
+
+ /* Not enough memory for track read. */
+ if( data_buf1 == 0 ) return -1;
+
+ do /* the physical read */
+ {
+ rv = phy_read(disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len,
+ data_buf1);
+ tries--;
+ if( rv ) printf("Error in phy_read(%d,%d,%d,%d,%d,%d);\n",
+ disk_drive, phy_c, phy_h, phy_s/data_len+1, data_len, data_buf1);
+ }
+ while(rv && tries > 0);
+
+ /* Disk error, it'll try one at a time, _very_ slowly! */
+ if(rv)
+ {
+ bad_track = trk_no;
+ return -1;
+ }
+
+ /* Yes! */
+ data_trk1 = trk_no;
+ return 0;
+}
+
+#if defined(__MSDOS__) || defined(__STANDALONE__)
+phy_read(drive, cyl, head, sect, length, buffer)
+{
+#asm
+ push bp
+ mov bp,sp
+
+ push es
+ push ds
+ pop es
+
+ mov dl,[bp+2+_phy_read.drive]
+ mov ch,[bp+2+_phy_read.cyl]
+ mov dh,[bp+2+_phy_read.head]
+ mov bx,[bp+2+_phy_read.buffer]
+
+ mov ax,[bp+2+_phy_read.cyl] ! Bits 10-11 of cylinder, AMI BIOS.
+ mov cl,#4
+ sar ax,cl
+ and al,#$C0
+ xor dh,al
+
+ mov cl,[bp+2+_phy_read.sect]
+ and cl,#$3F
+ mov ax,[bp+2+_phy_read.cyl] ! Bits 8-9 of cylinder.
+ sar ax,#1
+ sar ax,#1
+ and al,#$C0
+ or cl,al
+
+ mov al,[bp+2+_phy_read.length]
+ mov ah,#$02
+ int $13
+ jc read_err
+ mov ax,#0
+read_err:
+
+ pop es
+ pop bp
+#endasm
+}
+
+long
+get_dpt(drive)
+{
+#asm
+ push bp
+ mov bp,sp
+
+ push di
+ push es
+
+ mov dl,[bp+2+_get_dpt.drive]
+
+ mov ah,#$08
+ int $13
+ jnc func_ok
+ mov cx,ax
+ mov dx,#-1
+func_ok:
+ mov ax,cx
+
+ pop es
+ pop di
+ pop bp
+#endasm
+}
+#endif
+
diff --git a/bootblocks/unix.c b/bootblocks/unix.c
new file mode 100644
index 0000000..ec8ee89
--- /dev/null
+++ b/bootblocks/unix.c
@@ -0,0 +1,137 @@
+
+#ifdef __ELKS__
+
+#include <stdio.h>
+
+bios_khit() {
+ return 0;
+}
+
+bios_getc() {
+ return 0;
+}
+
+static int phy_fd = -1;
+
+static open_fd()
+{
+ phy_fd = open("/dev/fd0", 0);
+ if( phy_fd < 0 )
+ fprintf(stderr, "Cannot open /dev/fd0\n");
+}
+
+phy_read(drive, cyl, head, sect, len, buffer)
+int drive, cyl, head, sect, len;
+char *buffer;
+{
+extern long lseek();
+ int rv = 0;
+ long offset;
+ int i;
+
+ if( phy_fd == -1 ) open_fd();
+
+ offset = (((cyl*2 + head)*18L + sect-1)*512L);
+
+ fprintf(stderr, "PHY_READ(d%d, c%d, h%d, s%d, l%d, b%d) (Sect=%ld)\n",
+ drive, cyl, head, sect, len, buffer, offset/512);
+
+ if( lseek(phy_fd, offset, 0) < 0 )
+ perror("Phyread lseek error\n");
+
+
+ for(i=0; i< len; i++)
+ {
+ rv = read(phy_fd, buffer, 512);
+ if( rv < 0 )
+ perror("Phyread read error\n");
+ buffer+=512;
+ }
+
+ if( rv < 0 ) return -1;
+ return 0;
+}
+
+putsect(buffer, address)
+char * buffer;
+int address;
+{
+ fprintf(stderr, "Sector write from DS:%04x to 0000:%04x00\n",
+ buffer, address);
+ return 0;
+}
+#endif
+
+/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
+static unsigned short crctab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+/*
+ * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
+ * NOTE: First srgument must be in range 0 to 255.
+ * Second argument is referenced twice.
+ *
+ * Programmers may incorporate any or all code into their programs,
+ * giving proper credit within the source. Publication of the
+ * source routines is permitted so long as proper credit is given
+ * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
+ * Omen Technology.
+ */
+
+#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
+
+static unsigned short crc = 0;
+
+reset_crc()
+{
+ crc = 0;
+}
+
+addcrc(buffer, len)
+unsigned char * buffer;
+int len;
+{
+ while(len>0)
+ {
+ crc = updcrc((*buffer++), crc);
+ len--;
+ }
+}
+
+display_crc()
+{
+ printf("Image CRC value = %u\n", crc);
+}
+
diff --git a/copt/copt.c b/copt/copt.c
index 83ee18f..6cef964 100644
--- a/copt/copt.c
+++ b/copt/copt.c
@@ -302,13 +302,6 @@ static void readinfile(char *filename, char comment)
(void)fclose(fp);
}
-
-
-/*
- * Eval an expression into an integer number
- */
-static long eval(char *str, int len)
-{
#define NO_OP 0
#define ADD_OP 1
#define SUB_OP 2
@@ -317,39 +310,52 @@ static long eval(char *str, int len)
#define SHL_OP 5
#define SHR_OP 6
- char *oldcp, *cp, c;
long retval = 0;
long num = 0;
int sign = 1;
int base = 10;
- int state = 0;
int op = NO_OP;
+
+/* Apply operation to current numeric value */
+static void doretval(void)
+{
+ switch (op) {
+ case NO_OP: retval = num * sign;
+ break;
+ case ADD_OP: retval += num * sign;
+ break;
+ case SUB_OP: retval -= num * sign;
+ break;
+ case MUL_OP: retval *= num * sign;
+ break;
+ case DIV_OP: retval /= num * sign;
+ break;
+ case SHL_OP: retval <<= num;
+ break;
+ case SHR_OP: retval >>= num;
+ break;
+ }
+ op = NO_OP;
+ num = 0;
+ sign = 1;
+ base = 10;
+}
+
+
+/*
+ * Eval an expression into an integer number
+ */
+static long eval(char *str, int len)
+{
+ char *oldcp, *cp, c;
+ int state = 0;
int i, varnum;
- /* Apply operation to current numeric value */
- static void doretval(void)
- {
- switch (op) {
- case NO_OP: retval = num * sign;
- break;
- case ADD_OP: retval += num * sign;
- break;
- case SUB_OP: retval -= num * sign;
- break;
- case MUL_OP: retval *= num * sign;
- break;
- case DIV_OP: retval /= num * sign;
- break;
- case SHL_OP: retval <<= num;
- break;
- case SHR_OP: retval >>= num;
- break;
- }
- op = NO_OP;
- num = 0;
- sign = 1;
- base = 10;
- }
+ retval = 0;
+ num = 0;
+ sign = 1;
+ base = 10;
+ op = NO_OP;
/* Scan through whole string and decode it */
for (cp = str, i = 0; *cp && i < len; cp++, i++) {
diff --git a/copt/copt.diff b/copt/copt.diff
deleted file mode 100644
index 89d3686..0000000
--- a/copt/copt.diff
+++ /dev/null
@@ -1,72 +0,0 @@
-diff -rc linux-86.orig/copt/copt.c linux-86/copt/copt.c
-*** linux-86.orig/copt/copt.c Tue Feb 18 21:31:34 1997
---- linux-86/copt/copt.c Tue Apr 22 14:11:05 1997
-***************
-*** 303,314 ****
- }
-
-
--
-- /*
-- * Eval an expression into an integer number
-- */
-- static long eval(char *str, int len)
-- {
- #define NO_OP 0
- #define ADD_OP 1
- #define SUB_OP 2
---- 303,308 ----
-***************
-*** 317,330 ****
- #define SHL_OP 5
- #define SHR_OP 6
-
-! char *oldcp, *cp, c;
-! long retval = 0;
-! long num = 0;
-! int sign = 1;
-! int base = 10;
-! int state = 0;
-! int op = NO_OP;
-! int i, varnum;
-
- /* Apply operation to current numeric value */
- static void doretval(void)
---- 311,321 ----
- #define SHL_OP 5
- #define SHR_OP 6
-
-! static int op = NO_OP;
-! static long retval = 0;
-! static long num = 0;
-! static int sign = 1;
-! static int base = 10;
-
- /* Apply operation to current numeric value */
- static void doretval(void)
-***************
-*** 350,355 ****
---- 341,363 ----
- sign = 1;
- base = 10;
- }
-+
-+
-+ /*
-+ * Eval an expression into an integer number
-+ */
-+ static long eval(char *str, int len)
-+ {
-+
-+ char *oldcp, *cp, c;
-+ int state = 0;
-+ int i, varnum;
-+
-+ op = NO_OP;
-+ retval = 0;
-+ num = 0;
-+ sign = 1;
-+ base = 10;
-
- /* Scan through whole string and decode it */
- for (cp = str, i = 0; *cp && i < len; cp++, i++) {
diff --git a/copt/rules.86 b/copt/rules.86
index b4030cd..239ebde 100644
--- a/copt/rules.86
+++ b/copt/rules.86
@@ -68,7 +68,6 @@ inc %[si|di]*
mov al,-1[si]
mov -1[di],al
=
-cld
lodsb
stosb
@@ -77,7 +76,6 @@ inc %[si|di]*
mov al,-1[di]
mov -1[si],al
=
-cld
xchg si,di
lodsb
stosb
@@ -86,13 +84,11 @@ xchg si,di
inc si
mov al,-1[si]
=
-cld
lodsb
inc di
mov -1[di],al
=
-cld
stosb
dec %[si|di]*
@@ -103,6 +99,7 @@ mov 1[di],al
std
lodsb
stosb
+cld
dec %[si|di]*
dec %[si|di]*
@@ -114,18 +111,21 @@ xchg si,di
lodsb
stosb
xchg si,di
+cld
dec si
mov al,1[si]
=
std
lodsb
+cld
dec di
mov 1[di],al
=
std
stosb
+cld
# Rules for manipulating short values
diff --git a/copt/rules.end b/copt/rules.end
index cd93d4e..feda08b 100644
--- a/copt/rules.end
+++ b/copt/rules.end
@@ -1,6 +1,6 @@
# Rules to optimize BCC assembler output
-# Redo the changes done in rules.start
+# Undo the changes done in rules.start
proc_start
=
diff --git a/elksemu/elks.c b/elksemu/elks.c
index c31e94f..ddcf549 100644
--- a/elksemu/elks.c
+++ b/elksemu/elks.c
@@ -19,6 +19,10 @@
#include <sys/mman.h>
#include "elks.h"
+#ifdef __BCC__
+#define OLD_LIBC_VERSION
+#endif
+
volatile struct vm86_struct elks_cpu;
unsigned char *elks_base; /* Paragraph aligned */
@@ -114,13 +118,33 @@ static int load_elks(int fd)
return 0;
}
+#ifndef OLD_LIBC_VERSION
+ /*
+ * recent versions of libc have changed the proto for vm86()
+ * for now I'll just override ...
+ */
+#define OLD_SYS_vm86 113
+#define NEW_SYS_vm86 166
+
+static inline int vm86_mine(struct vm86_struct* v86)
+{
+ int __res;
+ __asm__ __volatile__("int $0x80\n"
+ :"=a" (__res):"a" ((int)OLD_SYS_vm86), "b" ((int)v86));
+ return __res;
+}
+#endif
void run_elks()
{
/*
* Execute 8086 code for a while.
*/
+#ifndef OLD_LIBC_VERSION
+ int err=vm86_mine((struct vm86_struct*)&elks_cpu);
+#else
int err=vm86((struct vm86_struct*)&elks_cpu);
+#endif
switch(VM86_TYPE(err))
{
/*
diff --git a/elksemu/elks_sys.c b/elksemu/elks_sys.c
index 4cc4368..16a3cec 100644
--- a/elksemu/elks_sys.c
+++ b/elksemu/elks_sys.c
@@ -40,7 +40,7 @@ static int elks_enosys(int bx,int cx,int dx,int di,int si);
DIR * dirtab[DIRCOUNT];
int diropen = 0;
static int elks_opendir(char * dname);
-static int elks_readdir(int bx, int cx, int dx);
+static int elks_readdir(int bx,int cx,int dx,int di,int si);
static int elks_closedir(int bx);
/*
@@ -109,7 +109,7 @@ static int elks_read(int bx,int cx,int dx,int di,int si)
dbprintf(("read(%d, %d, %d)\n",
bx,cx,dx));
if( bx >= 10000 && bx < 10000+DIRCOUNT)
- return elks_readdir(bx, cx, dx);
+ return elks_readdir(bx, cx, dx, di, si);
if( dx < 0 || dx > 1024 ) dx = 1024;
return read(bx, ELKS_PTR(void, cx), dx);
}
@@ -297,8 +297,8 @@ static int elks_getuid(int bx,int cx,int dx,int di,int si)
#define sys_alarm elks_alarm
static int elks_alarm(int bx,int cx,int dx,int di,int si)
{
- dbprintf(("alarm(%d)\n",bx<<16|cx));
- return alarm(bx<<16|cx);
+ dbprintf(("alarm(%d)\n",bx&0xFFFF));
+ return alarm(bx&0xFFFF);
}
#define sys_fstat elks_fstat
@@ -403,8 +403,8 @@ static int elks_getgid(int bx,int cx,int dx,int di,int si)
*
* Of course with the Patch in the Linux kernel we could just run the exe.
*/
-#define sys_exec elks_exec
-static int elks_exec(int bx,int cx,int dx,int di,int si)
+#define sys_execve elks_execve
+static int elks_execve(int bx,int cx,int dx,int di,int si)
{
int fd;
int arg_ct,env_ct;
@@ -512,6 +512,18 @@ static int elks_fcntl(int bx,int cx,int dx,int di,int si)
return -1;
}
+#define sys_dup elks_dup
+static int elks_dup(int bx,int cx,int dx,int di,int si)
+{
+ return dup(bx);
+}
+
+#define sys_dup2 elks_dup2
+static int elks_dup2(int bx,int cx,int dx,int di,int si)
+{
+ return dup2(bx, cx);
+}
+
#define sys_rename elks_rename
static int elks_rename(int bx,int cx,int dx,int di,int si)
{
@@ -651,13 +663,13 @@ elks_opendir(char * dname)
return 10000+rv;
}
-static int
-elks_readdir(int bx, int cx, int dx)
+#define sys_readdir elks_readdir
+static int elks_readdir(int bx,int cx,int dx,int di,int si)
{
struct dirent * ent;
/* Only read _ONE_ _WHOLE_ dirent at a time */
- if( dx != 266 )
+ if( dx != 266 && dx != 1 )
{
errno=EINVAL; return -1;
}
diff --git a/ld/Makefile b/ld/Makefile
index 985008c..6dad38a 100644
--- a/ld/Makefile
+++ b/ld/Makefile
@@ -13,12 +13,12 @@ DEFS =-DREL_OUTPUT -DBUGCOMPAT
# An alternative file for a non-standard a.out.h (eg i386 linux on an Alpha)
#
-# NATIVE= -DA_OUT_INCL='"a_out_local.h"'
+# NATIVE=-DA_OUT_INCL='"a_out_local.h"'
OBJS= dumps.o io.o ld.o readobj.o table.o typeconv.o linksyms.o \
writex86.o writebin.o writerel.o
-all: ld86 objchop catimage
+all: ld86 objchop catimage objdump86
ld86: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
@@ -28,7 +28,7 @@ install: ld86
install -m 755 ld86 $(LIBDIR)
clean realclean:
- rm -f *.o ld86 ld86r objchop catimage
+ rm -f *.o ld86 ld86r objchop catimage objdump86
$(OBJS): align.h ar.h bindef.h byteord.h config.h const.h globvar.h obj.h \
syshead.h type.h x86_aout.h
diff --git a/ld/dumps.c b/ld/dumps.c
index c9a40d4..a969123 100644
--- a/ld/dumps.c
+++ b/ld/dumps.c
@@ -12,11 +12,26 @@
PUBLIC void dumpmods()
{
struct modstruct *modptr;
+ char *s, *d;
+ int i;
for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
{
- putstr(modptr->loadflag ? "L " : " ");
- putbstr(20, modptr->modname);
+ for(s=d=modptr->filename; *s ; s++)
+ if( *s == '/' ) d=s+1;
+ if( memcmp(d, "libc", 4) == 0 && !modptr->loadflag ) continue;
+
+ putstr(modptr->modname);
+ i = strlen(modptr->modname);
+ while(i<16) putbyte(' '),i++;
+ putbyte( modptr->loadflag ? '+':'-' );
+ putstr(d);
+ if( modptr->archentry )
+ {
+ putbyte('(');
+ putstr(modptr->archentry);
+ putbyte(')');
+ }
putbyte('\n');
}
}
@@ -55,7 +70,10 @@ PUBLIC void dumpsyms()
#else
put08x(symptr->value);
#endif
- putstr(flags & A_MASK ? " A" : " R");
+ if( flags & (E_MASK|C_MASK) )
+ putstr(flags & A_MASK ? " A" : " R");
+ else
+ putstr(flags & A_MASK ? " a" : " r");
if (uflag)
putstr(" U");
if (flags & C_MASK)
diff --git a/ld/io.c b/ld/io.c
index a21ecd3..e56a474 100644
--- a/ld/io.c
+++ b/ld/io.c
@@ -22,6 +22,7 @@ PRIVATE char *drelbuftop; /* data relocation output buffer top */
PRIVATE char *errbuf; /* error buffer (actually uses STDOUT) */
PRIVATE char *errbufptr; /* error buffer ptr */
PRIVATE char *errbuftop; /* error buffer top */
+PRIVATE int errfil = STDOUT_FILENO;
PRIVATE char *inbuf; /* input buffer */
PRIVATE char *inbufend; /* input buffer top */
PRIVATE char *inbufptr; /* end of input in input buffer */
@@ -56,6 +57,7 @@ FORWARD void outputerror P((char *message));
FORWARD void put04x P((unsigned num));
FORWARD void putstrn P((char *message));
FORWARD void refer P((void));
+FORWARD void stderr_out P((void));
PUBLIC void ioinit(progname)
char *progname;
@@ -65,6 +67,10 @@ char *progname;
refname = progname; /* name must be static (is argv[0]) */
else
refname = "link";
+ for(progname=refname; *progname; progname++)
+ if(*progname=='/')
+ refname=progname+1;
+
#ifdef REL_OUTPUT
drelbuf = malloc(DRELBUFSIZE);
drelbuftop = drelbuf + DRELBUFSIZE;
@@ -129,10 +135,20 @@ PUBLIC void executable()
PUBLIC void flusherr()
{
- write(STDOUT_FILENO, errbuf, (unsigned) (errbufptr - errbuf));
+ if( errbufptr != errbuf )
+ write(errfil, errbuf, (unsigned) (errbufptr - errbuf));
errbufptr = errbuf;
}
+PRIVATE void stderr_out()
+{
+ if( errfil != STDERR_FILENO )
+ {
+ flusherr();
+ errfil = STDERR_FILENO;
+ }
+}
+
PRIVATE void flushout()
{
unsigned nbytes;
@@ -287,7 +303,7 @@ char *message;
{
putstr(message);
putbyte('\n');
- flusherr();
+ flusherr(); errfil = STDOUT_FILENO;
}
PUBLIC int readchar()
@@ -525,11 +541,32 @@ char *defarchentry;
putstr(defarchentry);
putbyte(')');
}
- putbyte('\n');
+ putstrn("");
+}
+
+PUBLIC void interseg(fname, aname, name)
+char *fname, *aname, *name;
+{
+ ++errcount;
+ refer();
+ putstr("error in ");
+ putstr(fname);
+ if( aname )
+ {
+ putstr("(");
+ putstr(aname);
+ putstr(")");
+ }
+ putstr(" intersegment jump to ");
+ if( name ) putstr(name);
+ else putstr("same file");
+
+ putstrn("");
}
PRIVATE void refer()
{
+ stderr_out();
putstr(refname);
putstr(": ");
}
@@ -538,6 +575,7 @@ PUBLIC void reserved(name)
char *name;
{
++errcount;
+ stderr_out();
putstr("incorrect use of reserved symbol: ");
putstrn(name);
}
@@ -554,19 +592,21 @@ bin_off_t size;
outhexdigs(count);
putstr(", supposed to be ");
outhexdigs(size);
- errexit("\n");
+ errexit("");
}
PUBLIC void undefined(name)
char *name;
{
++errcount;
+ stderr_out();
putstr("undefined symbol: ");
putstrn(name);
}
PUBLIC void usage()
{
+ stderr_out();
putstr("usage: ");
putstr(refname);
#ifdef REL_OUTPUT
diff --git a/ld/objchop.c b/ld/objchop.c
index c5a81e4..8defc13 100644
--- a/ld/objchop.c
+++ b/ld/objchop.c
@@ -61,7 +61,7 @@ long bsize;
FILE * ofd;
ofd = fopen(fname, "w");
- if( ofd == 0 ) fatal("Cannout open output file");
+ if( ofd == 0 ) fatal("Cannot open output file");
while(bsize>0)
{
diff --git a/ld/objdump86.c b/ld/objdump86.c
new file mode 100644
index 0000000..a5dbf44
--- /dev/null
+++ b/ld/objdump86.c
@@ -0,0 +1,681 @@
+/*
+ * This is a combination of three tools for decoding information from
+ * Dev86/ELKS object files and executables.
+ *
+ * This executable can be given the names:
+ *
+ * objdump86: Dumps detailed information about a binary file.
+ * size86: Summary sizes of the data in a binary file.
+ * nm86: The symbol table of the binary file.
+ *
+ * None of these programs have any options, neither can they currently deal
+ * with archive files. This may be a minor problem with nm86.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+
+FILE * ifd = stdin;
+char * ifname;
+
+#ifdef __STDC__
+#define _(x) x
+#else
+#define _(x) ()
+#endif
+
+long get_long _((void));
+long get_sized _((int sz));
+unsigned int get_word _((void));
+int main _((int argc, char**argv));
+void do_file _((char * fname));
+int error _((char * str));
+int read_objheader _((void));
+int read_sectheader _((void));
+int read_syms _((void));
+void read_databytes _((void));
+void hex_output _((int ch));
+void fetch_aout_hdr _((void));
+void dump_aout _((void));
+void size_aout _((void));
+void nm_aout _((void));
+
+int sections;
+long segsizes[16];
+long textoff, textlen;
+long str_off, str_len;
+
+char ** symnames;
+char * symtab;
+
+int display_mode = 0;
+int multiple_files = 0;
+int byte_order = 0;
+
+long size_text, size_data, size_bss;
+
+int
+main(argc, argv)
+int argc;
+char ** argv;
+{
+ int ar;
+ char * p;
+
+ p = strrchr(argv[0], '/');
+ if(p) p++; else p=argv[0];
+
+ if( p[0] == 's' ) display_mode = 1;
+ if( p[0] == 'n' ) display_mode = 2;
+
+ if( display_mode == 1 )
+ printf("text\tdata\tbss\tdec\thex\tfilename\n");
+
+ multiple_files = (argc>2);
+
+ for(ar=1; ar<argc; ar++)
+ do_file(argv[ar]);
+
+ return (argc<=1);
+}
+
+void
+do_file(fname)
+char * fname;
+{
+ int modno, i, ch;
+
+ size_text = size_data = size_bss = 0;
+ byte_order = 0;
+
+ if( !display_mode )
+ printf("OBJECTFILE '%s'\n", fname);
+
+ ifname = fname;
+ if( (ifd=fopen(fname, "rb")) == 0 )
+ {
+ error("Cannot open file");
+ return;
+ }
+
+ switch( read_objheader() )
+ {
+ case 0: /* as86 object file */
+
+ for(modno=1; modno<=sections; modno++)
+ {
+ if( modno != 1 && !display_mode )
+ printf("OBJECTSECTION %d\n", modno);
+ if( read_sectheader() < 0 ) break;
+
+ for(i=0; i<16; i++)
+ {
+ if( i<3 ) size_text += segsizes[i];
+ else size_data += segsizes[i];
+ }
+
+ if( read_syms() < 0 ) break;
+
+ if( display_mode == 0 )
+ printf("text\tdata\tbss\tdec\thex\tfilename\n");
+ if( display_mode != 2 )
+ printf("%ld\t%ld\t%ld\t%ld\t%lx\t%s\n",
+ size_text, size_data, size_bss,
+ size_text+ size_data+ size_bss,
+ size_text+ size_data+ size_bss,
+ ifname);
+
+ if( sections == 1 && display_mode != 0 )
+ break;
+
+ read_databytes();
+ }
+ if( !display_mode )
+ {
+ i=0;
+ while( (ch=getc(ifd)) != EOF )
+ {
+ if( i == 0 )
+ {
+ printf("TRAILER\n");
+ i=1;
+ }
+ hex_output(ch);
+ }
+ hex_output(EOF);
+ }
+ break;
+
+ case 1: /* ELKS executable */
+ fseek(ifd, 0L, 0);
+
+ switch(display_mode)
+ {
+ case 0: dump_aout(); break;
+ case 1: size_aout(); break;
+ case 2: nm_aout(); break;
+ }
+ break;
+ }
+ fclose(ifd);
+
+ if( symtab ) free(symtab);
+ if( symnames ) free(symnames);
+ symtab = 0;
+ symnames = 0;
+}
+
+int
+error(str)
+char * str;
+{
+ switch( display_mode )
+ {
+ case 1: fprintf(stderr, "size: %s: %s\n", ifname, str); break;
+ case 2: fprintf(stderr, "nm: %s: %s\n", ifname, str); break;
+ default:
+ printf("Error: %s\n", str);
+ break;
+ }
+ return -1;
+}
+
+int
+read_objheader()
+{
+ unsigned char buf[5];
+
+ if( fread(buf, 1, 5, ifd) != 5 )
+ return error("Cannot read object header");
+
+ if( buf[0] != 0xA3 || buf[1] != 0x86 )
+ {
+ if( buf[0] == 1 && buf[1] == 3 )
+ {
+ sections = 1;
+ return 1;
+ }
+ return error("Bad magic number");
+ }
+
+ if( (unsigned char)(buf[0] + buf[1] + buf[2] + buf[3]) != buf[4] )
+ return error("Bad header checksum");
+
+ sections= buf[2]+256*buf[3];
+
+ return 0;
+}
+
+int
+read_sectheader()
+{
+ long ssenc, cpos;
+ int i, ver;
+
+ textoff = get_long(); textlen = get_long();
+ str_len=get_word(); str_off=textoff-str_len;
+ ver = get_word();
+
+ symtab = malloc((unsigned int)str_len+1);
+ if( symtab == 0 ) return error("Out of memory");
+
+ cpos = ftell(ifd);
+ fseek(ifd, str_off, 0);
+ fread(symtab, 1, (int)str_len, ifd);
+ fseek(ifd, cpos, 0);
+
+ if( !display_mode )
+ {
+ printf("MODULE '%s'\n", symtab);
+ printf("BYTEPOS %08lx\n", textoff);
+ printf("BINLEN %08lx\n", textlen);
+ printf("STRINGS %04lx +%04lx\n", str_off, str_len);
+ printf("VERSION %d.%d\n", ver/256, ver%256);
+ }
+
+ (void)get_long(); /* Ignore fives */
+ ssenc=get_long();
+
+ for(i=0; i<16; i++)
+ {
+ int ss;
+ ss = (i^3);
+ ss = ((ssenc>>(2*(15-ss)))&3);
+ segsizes[i] = get_sized(ss);
+ if( segsizes[i] && !display_mode )
+ printf("SEG%x %08lx\n", i, segsizes[i]);
+ }
+ if( !display_mode )
+ printf("\n");
+
+ return 0;
+}
+
+int
+read_syms()
+{
+ int syms, i;
+
+ syms=get_word();
+
+ if( !display_mode ) printf("SYMS %u\n", syms);
+ if( syms < 0 ) return error("Bad symbol table");
+
+ symnames = malloc(syms*sizeof(char*)+1);
+ if( symnames == 0 ) return error("Out of memory");
+
+ if(display_mode == 2 && multiple_files)
+ printf("\n%s:\n", ifname);
+
+ for(i=0; i<syms; i++)
+ {
+ long offset=0;
+ unsigned int nameoff, symtype;
+
+ nameoff = get_word();
+ symtype = get_word();
+ offset = get_sized((symtype>>14)&3);
+ symtype &= 0x3FFF;
+ symnames[i] = symtab+nameoff;
+
+ if( !display_mode )
+ {
+ printf("SYM %-4d %08lx ", i, offset);
+
+ printf("%s", (symtype&0x2000)?"C":".");
+ printf("%s", (symtype&0x0100)?"N":".");
+ printf("%s", (symtype&0x0080)?"E":".");
+ printf("%s", (symtype&0x0040)?"I":".");
+ printf("%c", "T12D456789abcdeUAhijklmnopqrstuv"[symtype&0x1F]);
+ if( symtype &0x1E20 )
+ printf(" %04x", symtype);
+ printf(" %s\n", symnames[i]);
+ }
+ if( display_mode == 2 )
+ {
+ if( symtype == 0x004f || symtype == 0x0040 )
+ printf(" ");
+ else
+ printf("%08lx ", offset);
+ switch(symtype)
+ {
+ case 0x004F: putchar('U'); break;
+ case 0x0000: putchar('t'); break;
+ case 0x0003: putchar('d'); break;
+ case 0x2003: putchar('b'); break;
+ case 0x0043: putchar('C'); break;
+ case 0x0083: putchar('D'); break;
+ case 0x0080: putchar('T'); break;
+ case 0x0040: putchar('T'); break;
+ case 0x0180: putchar('N'); break;
+ case 0x0010: putchar('a'); break;
+ case 0x0090: putchar('A'); break;
+ default: putchar('?'); break;
+ }
+ printf(" %s\n", symnames[i]);
+ }
+
+ if( symtype == 0x43 || symtype == 0x2003 )
+ size_bss += offset;
+ }
+ if( !display_mode )
+ printf("\n");
+
+ return 0;
+}
+
+void
+read_databytes()
+{
+static char * relstr[] = {"ERR", "DB", "DW", "DD"};
+ long l;
+ int ch, i;
+ int curseg = 0;
+ int relsize = 0;
+ fseek(ifd, textoff, 0);
+
+ printf("\nBYTECODE\n");
+ for(;;)
+ {
+ if( (ch=getc(ifd)) == EOF ) break;
+
+ if( ch == 0 ) break;
+
+ switch( ch & 0xC0 )
+ {
+ case 0x00: switch(ch & 0xF0)
+ {
+ case 0x00: /* Relocator size */
+ printf("RELSZ %d\n", relsize= (ch&0xF));
+ if(relsize>3) relsize=3;
+ break;
+ case 0x10: /* Skip bytes */
+ printf("SKP %ld\n", get_sized(ch&0xF));
+ break;
+ case 0x20: /* Segment */
+ printf("SEG %x\n", curseg= (ch&0xF));
+ break;
+ default: printf("CODE %02x - unknown\n", ch);
+ return ;
+ }
+ break;
+ case 0x40: /* Raw bytes */
+ {
+ int abscnt = (ch&0x3F);
+ if( abscnt == 0 ) abscnt = 64;
+ for( i=0; i<abscnt; i++ )
+ {
+ if( (ch=getc(ifd)) == EOF ) break;
+ hex_output(ch);
+ }
+ hex_output(EOF);
+
+ if( ch == EOF ) return;
+ }
+ break;
+ case 0x80: /* Relocator - simple */
+ l = get_sized(relsize);
+ printf("%s SEG%x%s%s", relstr[relsize],
+ (ch&0xF),
+ (ch&0x20)?"-PC":"",
+ (ch&0x10)?"+?":"");
+ if(l)
+ printf("+0x%04lx", l);
+ putchar('\n');
+ break;
+ case 0xC0: /* Relocator - symbol relative */
+ if( ch & 0x18 )
+ {
+ printf("CODE %02x - unknown\n", ch);
+ return;
+ }
+ if( ch & 4 ) i = get_word();
+ else i = getc(ifd);
+ l = get_sized(ch&3);
+
+ printf("%s %s%s%s", relstr[relsize],
+ symnames[i],
+ (ch&0x20)?"-PC":"",
+ (ch&0x18)?"+?":"");
+ if(l)
+ printf("+0x%04lx", l);
+ putchar('\n');
+ break;
+ }
+ }
+ printf("\n");
+}
+
+long
+get_sized(sz)
+int sz;
+{
+ switch(sz)
+ {
+ case 0: return 0;
+ case 1: return getc(ifd);
+ case 2: return get_word();
+ case 3: return get_long();
+ }
+ return -1;
+}
+
+long
+get_long()
+{
+ long retv = 0;
+ int i;
+ for(i=0; i<32; i+=16)
+ {
+ unsigned int v = get_word();
+ if( byte_order & 2 )
+ retv += ((long)v<<(16-i));
+ else
+ retv += ((long)v<<i);
+ }
+ return retv;
+}
+
+unsigned int
+get_word()
+{
+ long retv = 0;
+ int i;
+ for(i=0; i<16; i+=8)
+ {
+ int v = getc(ifd);
+ if( v == EOF ) return -1;
+ if( byte_order & 1 )
+ retv += (v<<(8-i));
+ else
+ retv += (v<<i);
+ }
+ return retv;
+}
+
+void
+hex_output(ch)
+int ch;
+{
+static char linebuf[80];
+static char buf[20];
+static int pos = 0;
+
+ if( ch == EOF )
+ {
+ if(pos)
+ printf(": %.66s\n", linebuf);
+ pos = 0;
+ }
+ else
+ {
+ if(!pos)
+ memset(linebuf, ' ', sizeof(linebuf));
+ sprintf(buf, "%02x", ch&0xFF);
+ memcpy(linebuf+pos*3+(pos>7), buf, 2);
+ if( ch > ' ' && ch <= '~' ) linebuf[50+pos] = ch;
+ else linebuf[50+pos] = '.';
+ pos = ((pos+1) & 0xF);
+ if( pos == 0 )
+ {
+ printf(": %.66s\n", linebuf);
+ memset(linebuf, ' ', sizeof(linebuf));
+ }
+ }
+}
+
+/************************************************************************/
+/* ELKS a.out versions
+ */
+
+long header[12];
+int h_len, h_flgs, h_cpu;
+
+void
+fetch_aout_hdr()
+{
+ int i;
+
+ header[0] = get_long();
+ header[1] = get_long();
+ byte_order = ((header[0]>>24) & 3);
+
+ h_len = (header[1] & 0xFF);
+ h_flgs = ((header[0]>>16) & 0xFF);
+ h_cpu = ((header[0]>>24) & 0xFF);
+
+ for(i=2; i<8; i++)
+ {
+ if( i*4 <= h_len )
+ header[i] = get_long();
+ else
+ header[i] = 0;
+ }
+}
+
+void
+dump_aout()
+{
+static char * cpu[] = { "unknown", "8086", "m68k", "ns16k", "i386", "sparc" };
+static char * byteord[] = { "LITTLE_ENDIAN", "(2143)","(3412)","BIG_ENDIAN" };
+ int i;
+ long l;
+
+ if( display_mode == 0 ) fetch_aout_hdr();
+
+ if( h_cpu > 0x17 ) h_cpu &= 3;
+
+ printf("HLEN %d\n", h_len);
+ printf("CPU %s %s\n", cpu[h_cpu>>2], byteord[h_cpu&3]);
+
+ printf("FLAGS:");
+ if( h_flgs & 0x01 ) printf(" A_UZP");
+ if( h_flgs & 0x02 ) printf(" A_PAL");
+ if( h_flgs & 0x04 ) printf(" A_NSYM");
+ if( h_flgs & 0x08 ) printf(" FLG-08");
+ if( h_flgs & 0x10 ) printf(" A_EXEC");
+ if( h_flgs & 0x20 ) printf(" A_SEP");
+ if( h_flgs & 0x40 ) printf(" A_PURE");
+ if( h_flgs & 0x80 ) printf(" A_TOVLY");
+ printf("\n");
+
+ if( header[5] )
+ printf("a_entry = 0x%08lx\n", header[5]);
+ printf("a_total = 0x%08lx\n", header[6]);
+ if( header[7] )
+ printf("a_syms = 0x%08lx\n", header[7]);
+
+ if( h_len >= 36 )
+ printf("a_trsize = 0x%08lx\n", header[8]);
+ if( h_len >= 40 )
+ printf("a_drsize = 0x%08lx\n", header[9]);
+ if( h_len >= 44 )
+ printf("a_tbase = 0x%08lx\n", header[10]);
+ if( h_len >= 48 )
+ printf("a_dbase = 0x%08lx\n", header[11]);
+ printf("\n");
+
+ size_aout();
+ printf("\n");
+
+ if( header[7] )
+ {
+ printf("SYMBOLS\n");
+ nm_aout();
+ }
+ else
+ printf("NO SYMBOLS\n");
+ printf("\n");
+
+ printf("TEXTSEG\n");
+ fseek(ifd, (long)h_len, 0);
+ for(l=0; l<header[2]; l++)
+ {
+ if( (i=getc(ifd)) == EOF ) break;
+ hex_output(i);
+ }
+ hex_output(EOF);
+
+ printf("DATASEG\n");
+ fseek(ifd, (long)h_len+header[2], 0);
+ for(l=0; l<header[3]; l++)
+ {
+ if( (i=getc(ifd)) == EOF ) break;
+ hex_output(i);
+ }
+ hex_output(EOF);
+}
+
+void
+size_aout()
+{
+ if( display_mode == 1 ) fetch_aout_hdr();
+
+ if( display_mode == 0 )
+ printf("text\tdata\tbss\tdec\thex\tfilename\n");
+
+ printf("%ld\t%ld\t%ld\t%ld\t%lx\t%s\n",
+ header[2], header[3], header[4],
+ header[2]+ header[3]+ header[4],
+ header[2]+ header[3]+ header[4],
+ ifname);
+}
+
+void
+nm_aout()
+{
+ char n_name[10];
+ long n_value;
+ int n_sclass, n_numaux, n_type;
+ long bytes_left;
+
+ if( display_mode == 2 ) fetch_aout_hdr();
+
+ fseek(ifd, h_len+header[2]+header[3]+header[8]+header[9], 0);
+
+ if( h_flgs & 4 ) { error("Executable has new format symtab\n"); return; }
+
+ bytes_left = header[7];
+
+ if( bytes_left == 0 )
+ printf("No symbols in '%s'\n", ifname);
+ else if(multiple_files)
+ printf("\n%s:\n", ifname);
+
+ while(bytes_left > 16)
+ {
+ if( fread(n_name, 1, 8, ifd) != 8 ) return;
+ n_name[8] = 0;
+ n_value = get_long();
+ if( (n_sclass = getc(ifd)) == EOF ) return;
+ if( (n_numaux = getc(ifd)) == EOF ) return;
+ n_type = get_word();
+
+ printf("%08lx ", n_value);
+ switch(n_sclass)
+ {
+ case 0x01: printf("a "); break;
+ case 0x12: printf("T "); break;
+ case 0x13: printf("D "); break;
+ case 0x14: printf("C "); break;
+ case 0x1a: printf("t "); break;
+ case 0x1b: printf("d "); break;
+ case 0x1c: printf("b "); break;
+ default: if( display_mode )
+ {
+ printf("? "); break;
+ }
+
+ printf("n_sclass=");
+ switch(n_sclass>>3)
+ {
+ case 0: printf("C_NULL,"); break;
+ case 2: printf("C_EXT,"); break;
+ case 3: printf("C_STAT,"); break;
+ default: printf("%04o,", n_sclass&0xF8);
+ }
+ switch(n_sclass&7)
+ {
+ case 0: printf("N_UNDF "); break;
+ case 1: printf("N_ABS "); break;
+ case 2: printf("N_TEXT "); break;
+ case 3: printf("N_DATA "); break;
+ case 4: printf("N_BSS "); break;
+ case 5: printf("N_COMM "); break;
+ default: printf("%o ", n_sclass&7); break;
+ }
+ break;
+ }
+
+ if( display_mode == 0 )
+ {
+ if( n_numaux )
+ printf("n_numaux=%02x ", n_numaux);
+ if( n_type )
+ printf("n_type=%04x ", n_type);
+ }
+
+ printf("%s\n", n_name);
+ }
+}
diff --git a/ld/syshead.h b/ld/syshead.h
index 5eeda82..fa5c23a 100644
--- a/ld/syshead.h
+++ b/ld/syshead.h
@@ -24,6 +24,7 @@
#define mode_t unsigned short
#define SEEK_SET 0
#define STDOUT_FILENO 0
+#define STDERR_FILENO 0
#endif
/******************************************************************************/
@@ -54,6 +55,7 @@ void *memset P((void *s, int c, unsigned n));
int access P((const char *path, int amode));
#define SEEK_SET 0
#define STDOUT_FILENO 0
+#define STDERR_FILENO 2
#define mode_t unsigned short
#define off_t long
diff --git a/ld/type.h b/ld/type.h
index 217d6a9..a4c16aa 100644
--- a/ld/type.h
+++ b/ld/type.h
@@ -114,6 +114,7 @@ void outofmemory P((void));
void prematureeof P((void));
void redefined P((char *name, char *message, char *archentry,
char *deffilename, char *defarchentry));
+void interseg P((char *fname, char *aname, char *name));
void reserved P((char *name));
void size_error P((int seg, bin_off_t count, bin_off_t size));
void undefined P((char *name));
diff --git a/ld/writex86.c b/ld/writex86.c
index 5dd3e8d..b2bab23 100644
--- a/ld/writex86.c
+++ b/ld/writex86.c
@@ -13,10 +13,8 @@
#define bdataoffset (data_base_value)
#define page_size() ((bin_off_t)4096)
-#ifdef __ELF__
#ifndef ELF_SYMS
-#define ELF_SYMS 1
-#endif
+#define ELF_SYMS 0
#endif
# define FILEHEADERLENGTH (headerless?0:A_MINHDR)
@@ -130,13 +128,21 @@ bool_pt arguzp;
symres(segboundary); /* __segXCL */
segboundary[7] = 'H';
symres(segboundary); /* __segXCH */
+#ifndef DATASEGS
+ if( curseg > 3 )
+ {
+ segboundary[6] = 'S';
+ segboundary[7] = 'O';
+ symres(segboundary); /* __segXSO */
+ }
+#endif
}
curseg = 3;
symres("__edata");
symres("__end");
curseg = 0; /* text seg, s.b. variable */
symres("__etext");
- if( headerless ) symres("__segoff");
+ symres("__segoff");
/* calculate segment and common sizes (sum over loaded modules) */
/* use zero init of segsz[] */
@@ -186,8 +192,13 @@ bool_pt arguzp;
}
/* calculate seg positions now their sizes are known */
- /* temp use fixed order 0D 0C 1D 1C 2D 2C ... */
- /* assume seg 0 is text and rest are data */
+ /*
+#ifdef DATASEGS
+ * Assume seg 0 is text and rest are data
+#else
+ * Assume seg 1..3 are data, Seg 0 is real text, seg 4+ are far text
+#endif
+ */
segpos[0] = segbase[0] = spos = btextoffset;
combase[0] = segbase[0] + segsz[0];
segadj[1] = segadj[0] = -btextoffset;
@@ -201,9 +212,23 @@ bool_pt arguzp;
bdataoffset = etextpadoff;
segpos[1] = segbase[1] = edataoffset = bdataoffset;
combase[1] = segbase[1] + segsz[1];
+#ifndef DATASEGS
+ for (seg = 4; seg < NSEG; ++seg)
+ {
+ segpos[seg] = segbase[seg] = 0;
+ combase[seg] = segbase[seg] + segsz[seg];
+ segadj[seg] = etextpadoff;
+
+ etextpadoff += ld_roundup(segsz[seg] + comsz[seg], 0x10, bin_off_t);
+ segadj[1] += ld_roundup(segsz[seg] + comsz[seg], 0x10, bin_off_t);
+ }
+ for (seg = 2; seg < 4; ++seg)
+#else
for (seg = 2; seg < NSEG; ++seg)
+#endif
{
segpos[seg] = segbase[seg] = combase[seg - 1] + comsz[seg - 1];
+#ifdef MC6809
if (seg == DPSEG)
{
/* temporarily have fixed DP seg */
@@ -216,6 +241,7 @@ bool_pt arguzp;
segpos[seg] = segbase[seg] = (segbase[seg] + 0xFF)
& ~(bin_off_t) 0xFF;
}
+#endif
combase[seg] = segbase[seg] + segsz[seg];
segadj[seg] = segadj[seg - 1];
}
@@ -241,8 +267,12 @@ bool_pt arguzp;
/* adjust special symbols */
for (seg = 0; seg < NSEG; ++seg)
{
+#ifdef DATASEGS
if (segsz[seg] != 0)
/* only count data of nonzero length */
+#else
+ if (segsz[seg] != 0 && seg < 4)
+#endif
edataoffset = segbase[seg] + segsz[seg];
segboundary[5] = hexdigit[seg]; /* to __segX?H */
segboundary[6] = 'D';
@@ -256,11 +286,24 @@ bool_pt arguzp;
segboundary[7] = 'H';
setsym(segboundary, tempoffset + comsz[seg]);
/* __segXCH */
+#ifndef DATASEGS
+ if( seg > 3 )
+ {
+ segboundary[6] = 'S';
+ segboundary[7] = 'O';
+ setsym(segboundary, (bin_off_t)(segadj[seg]-segadj[0])/0x10);
+ /* __segXSO */
+ }
+#endif
}
setsym("__etext", etextoffset);
setsym("__edata", edataoffset);
+#ifdef DATASEGS
setsym("__end", endoffset = combase[NSEG - 1] + comsz[NSEG - 1]);
- if( headerless ) setsym("__segoff", (bin_off_t)(segadj[1]-segadj[0])/0x10);
+#else
+ setsym("__end", endoffset = combase[3] + comsz[3]);
+#endif
+ setsym("__segoff", (bin_off_t)(segadj[1]-segadj[0])/0x10);
if( !bits32 )
{
if( etextoffset > 65536L )
@@ -322,11 +365,20 @@ bool_pt arguzp;
flags & C_MASK)
switch (flags & (A_MASK | SEGM_MASK))
{
+#ifdef DATASEGS
case 0:
+#else
+ default:
+#endif
extsym.n_sclass |= N_TEXT;
case A_MASK:
break;
+#ifdef DATASEGS
default:
+#else
+ case 1: case 2: case 3:
+ case A_MASK|1: case A_MASK|2: case A_MASK|3:
+#endif
if (flags & (C_MASK | SA_MASK))
extsym.n_sclass |= N_BSS;
else
@@ -414,7 +466,14 @@ struct modstruct *modptr;
case CM_OFFSET_RELOC:
offset = readsize(relocsize);
if (modify & R_MASK)
+ {
+#ifndef DATASEGS
+ int m = (modify & SEGM_MASK);
+ if( curseg != m && m != SEGM_MASK )
+ interseg(modptr->filename, modptr->archentry, (char*)0);
+#endif
offset -= (spos + relocsize);
+ }
offtocn(buf, segbase[modify & SEGM_MASK] + offset, relocsize);
writeout(buf, relocsize);
spos += relocsize;
@@ -424,7 +483,14 @@ struct modstruct *modptr;
(modify & S_MASK ? 2 : 1))];
offset = readconvsize((unsigned) modify & OF_MASK);
if (modify & R_MASK)
+ {
+#ifndef DATASEGS
+ int m = (symptr->flags & SEGM_MASK);
+ if( curseg != m && m != SEGM_MASK )
+ interseg(modptr->filename, modptr->archentry, symptr->name);
+#endif
offset -= (spos + relocsize);
+ }
offset += symptr->value;
offtocn(buf, offset, relocsize);
writeout(buf, relocsize);
diff --git a/ld/x b/ld/x
new file mode 100644
index 0000000..90d943e
--- /dev/null
+++ b/ld/x
@@ -0,0 +1 @@
+PUBLIC void interseg(fname, aname, name)
diff --git a/libc/Config_sh b/libc/Config_sh
index 5b72652..9446f5d 100644
--- a/libc/Config_sh
+++ b/libc/Config_sh
@@ -46,7 +46,7 @@ main()
do
display
echo
- echon 'Option to flip [or quit] >'
+ echon 'Select config option to flip [or quit] >'
read n
v=""
case "$n" in
@@ -76,8 +76,6 @@ main()
display()
{
clear
- echo 'Configuration options'
- echo
awk -F: < .config.lst '{
if( $3 == "+" ) next;
if( $2 == "+" ) { flags[$1] = 1; next; }
diff --git a/libc/Makefile b/libc/Makefile
index 5ddea9a..efd21e5 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -11,18 +11,13 @@ endif
VERMAJOR=0
VERMINOR=13
-VERPATCH=0
+VERPATCH=5
VER=$(VERMAJOR).$(VERMINOR).$(VERPATCH)
CC=bcc
CCFLAGS=-I -I$(TOP)/include
DEFS=-D__LIBC__
-ifeq ($(ELKSSRC),)
-ELKSSRC=/usr/src/elks
-endif
-export ELKSSRC
-
include Make.defs
CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
diff --git a/libc/bios/Makefile b/libc/bios/Makefile
index 57128e0..b617e50 100644
--- a/libc/bios/Makefile
+++ b/libc/bios/Makefile
@@ -10,7 +10,7 @@ AOBJ=bios_start.o bios_isatty.o \
BSRC=bios_vid.c
BOBJ=bios_putc.o bios_getc.o bios_khit.o bios_rdline.o
-OBJ=$(AOBJ) $(BOBJ)
+OBJ=$(AOBJ) $(BOBJ) time.o
CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS)
diff --git a/libc/bios/bios_vid.c b/libc/bios/bios_vid.c
index db2e91d..ec3c603 100644
--- a/libc/bios/bios_vid.c
+++ b/libc/bios/bios_vid.c
@@ -410,6 +410,13 @@ int len;
int ch;
int pos=0;
+ if( len < 0 ) { errno = EINVAL; return -1; }
+ if( len == 0 )
+ {
+ if( bios_khit() == 0 ) return 0;
+ errno = EINTR;
+ return -1;
+ }
if( len == 1 )
{
buf[0]=((ch=bios_getc())&0xFF?ch&0xFF:((ch>>8)&0xFF|0x80));
diff --git a/libc/bios/time.c b/libc/bios/time.c
new file mode 100644
index 0000000..9bc63e5
--- /dev/null
+++ b/libc/bios/time.c
@@ -0,0 +1,127 @@
+/*
+ * Time functions for standalone mode, on the first call to time() it tries
+ * to query the RTC, on success it sets it's own day counter an the PC's
+ * ticks since midnight clock. From the second call on it uses the day
+ * counter and ticks clock.
+ *
+ * NOTES:
+ * DOS's midnight bug is here too, it's actually in the bios.
+ * If there's no RTC the clock will fall to Jan 3 1970.
+ */
+
+#include <time.h>
+
+static int mdays[13] = { 0,31,31+28,31+28+31,31+28+31+30,
+ 31+28+31+30+31,31+28+31+30+31+30,31+28+31+30+31+30+31,
+ 31+28+31+30+31+30+31+31,31+28+31+30+31+30+31+31+30,
+ 31+28+31+30+31+30+31+31+30+31,31+28+31+30+31+30+31+31+30+31+30,
+ 365 };
+
+#define SECSPERHOUR (60*60)
+#define SECSPERDAY (SECSPERHOUR*24L)
+
+/****************************************
+ * Return the number of seconds that have elapsed since the start
+ * of 1970.
+ * Input:
+ * timer pointer to where to store result (or NULL)
+ * Output:
+ * *timer = result (unless timer == NULL)
+ * Returns:
+ * time
+ */
+
+static int xt_days = 0, ax_val, huns = 0;
+
+static long get_time(ah)
+{
+#asm
+#if !__FIRST_ARG_IN_AX__
+ mov bx,sp
+ mov ax,[bx+2]
+#endif
+ mov ah,al
+ int $1A
+ jnc intok
+ mov cx,#-1
+ mov dx,cx
+intok:
+ mov [_ax_val],ax
+ mov ax,dx
+ mov dx,cx
+#endasm
+}
+
+static int
+unbcd(bcdval)
+int bcdval;
+{
+ return (bcdval&0xF) + 10*((bcdval>>4)&0xF);
+}
+
+time_t time(timer)
+time_t *timer;
+{
+ unsigned day,month,year;
+ long rv;
+ time_t t;
+
+ if( xt_days ) goto XT_time;
+
+ rv = get_time(0x02);
+ if(rv == -1) goto XT_time;
+ huns = unbcd(rv & 0xFF); /* Save for stime */
+ rv >>= 8; t = unbcd(rv & 0xFF);
+ rv >>= 8; t += unbcd(rv & 0xFF)*60;
+ rv >>= 8; t += unbcd(rv & 0xFF)*3600;
+
+ rv = get_time(0x04);
+ if(rv == -1) goto XT_time;
+ day = unbcd(rv & 0xFF);
+ rv >>= 8; month = unbcd(rv & 0xFF) -1;
+ rv >>= 8; year = unbcd(rv & 0xFF);
+ rv >>= 8; year += unbcd(rv & 0xFF)*100;
+ year -= 1970;
+ if( year < 1950 && year >= 1900 )
+ year += 100; /* Century is not updated on RTC */
+
+ if (month <= 1 || year & 3) /* if before Feb or not a leap year */
+ day--; /* don't add day for leap year */
+ day += mdays[month]; /* day in year */
+ day += (year + 3) >> 2; /* add a day for each leap year */
+ t += ((year * 365L) + day) * SECSPERDAY;
+
+ stime(t);
+
+ if(0)
+ {
+XT_time:
+ rv = get_time(0);
+ xt_days += (ax_val&0xFF);
+ rv = xt_days*SECSPERDAY + rv * 1080 / 19663;
+ }
+
+ if (timer)
+ *timer = t;
+ return t;
+}
+
+static long ticks;
+
+stime(timer)
+time_t timer;
+{
+ xt_days = (timer/SECSPERDAY);
+
+ ticks = ((timer%SECSPERDAY) * 19663L + huns*196) / 1080;
+ huns = 0;
+
+#asm
+ mov cx,[_ticks+2]
+ mov dx,[_ticks]
+ mov ah,#1
+ int $1A
+#endasm
+
+ return 0;
+}
diff --git a/libc/error/sys_errlist.c b/libc/error/sys_errlist.c
index 79a40bf..48aa6a3 100644
--- a/libc/error/sys_errlist.c
+++ b/libc/error/sys_errlist.c
@@ -10,7 +10,7 @@
* Of course the best of all is to use strerror().
*/
-#ifdef __AS386_16__
+#if defined(__AS386_16__) || defined(__AS386_32__)
#define NR_ERRORS 128
extern char **__sys_errlist;
@@ -19,12 +19,21 @@ extern int __sys_nerr;
char *sys_errlist[NR_ERRORS];
int sys_nerr = NR_ERRORS;
+#ifdef __AS386_16__
#asm
loc 1 ! Make sure the pointer is in the correct segment
auto_func: ! Label for bcc -M to work.
.word _init_vars ! Pointer to the autorun function
.text ! So the function after is also in the correct seg.
#endasm
+#else
+#asm
+ loc 1 ! Make sure the pointer is in the correct segment
+auto_func: ! Label for bcc -M to work.
+ .long _init_vars ! Pointer to the autorun function
+ .text ! So the function after is also in the correct seg.
+#endasm
+#endif
static void init_vars()
{
@@ -71,4 +80,4 @@ static void init_vars()
__sys_nerr = sys_nerr = NR_ERRORS;
}
-#endif /* __AS386_16__ */
+#endif /* __AS386_??__ */
diff --git a/libc/getent/pwent.c b/libc/getent/pwent.c
index fd65db2..738c87a 100644
--- a/libc/getent/pwent.c
+++ b/libc/getent/pwent.c
@@ -53,6 +53,8 @@ endpwent(void)
struct passwd *
getpwent(void)
{
+ if (pw_fd==-1)
+ setpwent();
if (pw_fd!=-1)
return __getpwent(pw_fd);
return NULL;
diff --git a/libc/include/asm/limits.h b/libc/include/asm/limits.h
index 54b48bc..531ea41 100644
--- a/libc/include/asm/limits.h
+++ b/libc/include/asm/limits.h
@@ -10,9 +10,9 @@
#define MB_LEN_MAX 1 /* Longest multi-byte character */
#define CHAR_BIT 8 /* number of bits in a char */
#define SHRT_MAX 32767 /* maximum (signed) short value */
-#define SHRT_MIN (-32767) /* minimum (signed) short value */
+#define SHRT_MIN (-32768) /* minimum (signed) short value */
#define LONG_MAX 2147483647 /* maximum (signed) long value */
-#define LONG_MIN (-2147483647) /* minimum (signed) long value */
+#define LONG_MIN (-2147483648) /* minimum (signed) long value */
#define UCHAR_MAX 255 /* maximum unsigned char value */
#define USHRT_MAX 0xffff /* maximum unsigned short value */
#define ULONG_MAX 0xffffffff /* maximum unsigned long value */
@@ -23,26 +23,26 @@
#ifdef __AS386_32__
#define INT_MAX 2147483647 /* maximum (signed) int value */
-#define INT_MIN (-2147483647) /* minimum (signed) int value */
+#define INT_MIN (-2147483648) /* minimum (signed) int value */
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#else
#define INT_MAX 32767 /* maximum (signed) int value */
-#define INT_MIN (-32767) /* minimum (signed) int value */
+#define INT_MIN (-32768) /* minimum (signed) int value */
#define UINT_MAX 0xffff /* maximum unsigned int value */
#endif
/* BCC doesn't have signed char */
/* #define SCHAR_MAX 127 /* maximum signed char value */
-/* #define SCHAR_MIN (-127) /* minimum signed char value */
+/* #define SCHAR_MIN (-128) /* minimum signed char value */
#endif
#if defined(__GNUC__) && defined(__i386__)
#define CHAR_MAX 127 /* maximum char value */
-#define CHAR_MIN (-127) /* mimimum char value */
+#define CHAR_MIN (-128) /* mimimum char value */
#define SCHAR_MAX 127 /* maximum signed char value */
-#define SCHAR_MIN (-127) /* minimum signed char value */
+#define SCHAR_MIN (-128) /* minimum signed char value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
-#define INT_MIN (-2147483647) /* minimum (signed) int value */
+#define INT_MIN (-2147483648) /* minimum (signed) int value */
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#endif
diff --git a/libc/include/dos.h b/libc/include/dos.h
index 1e2b11e..d67e27f 100644
--- a/libc/include/dos.h
+++ b/libc/include/dos.h
@@ -24,6 +24,7 @@ void __setvect __P((int i, long j));
long __getvect __P((int vecno));
#endif
+unsigned int __get_cs __P((void));
unsigned int __get_ds __P((void));
unsigned int __get_es __P((void));
void __set_es __P((unsigned int seg));
diff --git a/libc/kinclude/Config b/libc/kinclude/Config
index 6c9970d..bd58ab7 100644
--- a/libc/kinclude/Config
+++ b/libc/kinclude/Config
@@ -1 +1 @@
-kinc: Example kernel include files
+kinc: Example kernel include files and syscall.dat
diff --git a/libc/misc/Makefile b/libc/misc/Makefile
index 50d31b7..6634f18 100644
--- a/libc/misc/Makefile
+++ b/libc/misc/Makefile
@@ -12,7 +12,7 @@ GOBJ=atoi.o atol.o ltoa.o ltostr.o \
ctype.o qsort.o bsearch.o rand.o lsearch.o getopt.o \
itoa.o cputype.o strtol.o crypt.o
-UOBJ=getenv.o putenv.o popen.o system.o setenv.o getcwd.o
+UOBJ=getenv.o putenv.o popen.o system.o setenv.o getcwd.o tmpnam.o
SSRC=syslib.c
SOBJ=time.o abort.o wait.o wait3.o waitpid.o killpg.o setpgrp.o sleep.o \
diff --git a/libc/misc/crypt.c b/libc/misc/crypt.c
index 906dea2..db69325 100644
--- a/libc/misc/crypt.c
+++ b/libc/misc/crypt.c
@@ -1,42 +1,65 @@
-#include <features.h>
-#include <stdlib.h>
/* TEA based crypt(), version 0.0 <ndf@linux.mit.edu>
* It looks like there are problems with key bits carrying through
* to the encryted data, and I want to get rid of that libc call..
* This is just so rob could see it ;) */
+
+/*
+ * I've:
+ * Compared the TEA implementation to a reference source - OK
+ * Noted the cycles count at 64 is twice the suggested value.
+ * Changed the types of 'n' and 'i' for better code with bcc.
+ * Removed a possible overrun of rkey by looping the values, it's now
+ * possible to _choose_ every bit of the 128bit PW with a 32 character word.
+ * Corrected the output transformation, it lost bits between words.
+ * Cleaned out all trace of the uncrypted PW from rkey.
+ *
+ * RDB.
+ */
+
+#include <stdlib.h>
+
char *
crypt(const char * key, const char * salt)
{
- /* n is the number of rounds, delta is a golden # derivative,
- k is the key, v is the data to be encrypted. */
- unsigned long v[2], sum=0, delta=0x9e3779b9, n=64, k[4];
+ /* n is the number of cycles (2 rounds/cycle),
+ delta is a golden # derivative,
+ k is the key, v is the data to be encrypted. */
+
+ unsigned long v[2], sum=0, delta=0x9e3779b9, k[4];
+ int n=64, i, j;
static char rkey[16];
- unsigned char i;
/* Our constant string will be a string of zeros .. */
v[0]=v[1]=k[0]=k[1]=k[2]=k[3]=0;
for(i=0;i<16;i++) rkey[i]=0;
+
rkey[0]=*salt;
rkey[1]=salt[1];
- for (i=0;key[i];i++) rkey[i+1]=key[i];
+ for (j=2,i=0;key[i];i++,j=((j+1)&15))
+ rkey[j]=(rkey[j]<<4)+(rkey[j]>>4)+ key[i];
+
memcpy(k, rkey, 4*sizeof(long));
- while (n-->0) {
+ while (n-->0) {
sum += delta;
v[0] += (v[1]<<4)+k[0] ^ v[1]+sum ^ (v[1]>>5)+k[1];
v[1] += (v[0]<<4)+k[2] ^ v[0]+sum ^ (v[0]>>5)+k[3];
}
+ /* Remove any trace of key */
+ for(i=0;i<16;i++) rkey[i]=0;
*rkey=*salt; rkey[1]=salt[1];
/* Now we need to unpack the bits and map it to "A-Za-z0-9./" for printing
in /etc/passwd */
+ sum=v[0];
for (i=2;i<13;i++)
{
/* This unpacks the 6 bit data, each cluster into its own byte */
- if (i==8) v[0]|=v[1]>>28;
- rkey[i]=v[(i-2)/6]&0x3F;
- v[(i-2)/6]>>=6;
+ rkey[i]=(sum&0x3F);
+ sum>>=6;
+ if(i==0+2) sum |= (v[1]<<26);
+ if(i==5+2) sum |= (v[1]>>4);
/* Now we map to the proper chars */
if (rkey[i]>=0 && rkey[i]<12) rkey[i]+=46;
diff --git a/libc/misc/tmpnam.c b/libc/misc/tmpnam.c
new file mode 100644
index 0000000..5bb72c5
--- /dev/null
+++ b/libc/misc/tmpnam.c
@@ -0,0 +1,50 @@
+/*
+ * (C) Shane Kerr <kerr@wizard.net> under terms of LGPL
+ */
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#ifndef P_tmpdir
+#define P_tmpdir "/tmp"
+#endif
+
+#ifndef L_tmpnam
+#define L_tmpnam 20
+#endif
+
+char *tmpnam(s)
+char *s;
+{
+ static char ret_val[L_tmpnam];
+ static char c1 = 0;
+ static char c2 = 0;
+ static char c3 = 0;
+ static char uniq_ch[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ struct stat stbuf;
+
+ do {
+ sprintf(ret_val, "%s/%05d%c%c%c", P_tmpdir, getpid(),
+ uniq_ch[c1], uniq_ch[c2], uniq_ch[c3]);
+ if (++c1 >= 62) {
+ c1 = 0;
+ if (++c2 >= 62) {
+ c2 = 0;
+ if (++c3 >= 62) {
+ errno = EEXIST;
+ return 0;
+ }
+ }
+ }
+ } while (stat(ret_val, &stbuf) == 0);
+
+ if (s != 0) {
+ strcpy(s, ret_val);
+ return s;
+ } else {
+ return ret_val;
+ }
+}
+
diff --git a/libc/msdos/Makefile b/libc/msdos/Makefile
index d929ee8..d4bc49a 100644
--- a/libc/msdos/Makefile
+++ b/libc/msdos/Makefile
@@ -10,7 +10,7 @@ AOBJ= dos_start.o __mkargv.o __mkenvp.o dos__fconv.o dos_read.o \
BSRC=i86.c
BOBJ= __seg_regs.o __peek_es.o __poke_es.o __deek_es.o __doke_es.o \
- __strchr_es.o
+ __strnget_es.o __strchr_es.o __strlen_es.o
ifeq ($(LIB_CPU),i86)
ifeq ($(LIB_OS),DOS)
diff --git a/libc/msdos/i86.c b/libc/msdos/i86.c
index 44de3e3..6c613b2 100644
--- a/libc/msdos/i86.c
+++ b/libc/msdos/i86.c
@@ -173,20 +173,48 @@ got_it:
}
#endif
-#ifdef L___strchr_es
+#ifdef L___strnget_es
char *
__strnget_es(d, s, c)
-char *d, *s;
-int c;
+char *d;
+char *s;
+register int c;
{
- int ds, es;
- char *p = __strchr_es(s, '\0');
- if(p != 0 && p-s < c)
- c = p-s+1;
- ds = __get_ds();
- es = __get_es();
-
- __movedata(es, s, ds, d, c);
+ register int i = __strlen_es(s);
+ if(i < c) c = i+1;
+ /* else s[--c] = 0; ?? */
+ /* else return -E2BIG; ?? */
+
+ __movedata(__get_es(), s, __get_ds(), d, c);
+}
+#endif
+
+#ifdef L___strlen_es
+int __strlen_es(str)
+char * str;
+{
+#asm
+#if !__FIRST_ARG_IN_AX__
+ mov bx,sp
+#endif
+ push di
+ cld
+
+#if __FIRST_ARG_IN_AX__
+ mov di,ax
+#else
+ mov di,[bx+2]
+#endif
+ mov cx,#-1
+ xor ax,ax
+ repne
+ scasb ! Scans [ES:DI]
+ not cx
+ dec cx
+ mov ax,cx
+
+ pop di
+#endasm
}
#endif
diff --git a/libc/msdos/time.c b/libc/msdos/time.c
index 0a66da8..271ea05 100644
--- a/libc/msdos/time.c
+++ b/libc/msdos/time.c
@@ -24,7 +24,7 @@ static int mdays[13] = { 0,31,31+28,31+28+31,31+28+31+30,
static long get_time(ah)
{
#asm
-#if !__FIST_ARG_IN_AX__
+#if !__FIRST_ARG_IN_AX__
mov bx,sp
mov ax,[bx+2]
#endif
diff --git a/libc/msdos/xxx/KEYTEST.C b/libc/msdos/xxx/KEYTEST.C
new file mode 100644
index 0000000..6627647
--- /dev/null
+++ b/libc/msdos/xxx/KEYTEST.C
@@ -0,0 +1,575 @@
+
+#include <stdio.h>
+#include <dos.h>
+#include <bios.h>
+#include <signal.h>
+
+#define KEY_SPECIAL 0x8000
+#define KEY_PAD 0x4000
+#define KEY_OTHER 0x2000
+#define KEY_DIRECT 0x1000
+#define KEY_ALT 0x0800
+#define KEY_ALTGR 0x0400
+#define KEY_CTRL 0x0200
+#define KEY_SHIFT 0x0100
+
+#ifndef OBJ_FILE
+
+#define KEYBD 0x09
+#define cprintf printf
+
+int get_key(void);
+void ( interrupt far *orig_keybd)();
+void interrupt far keybd();
+
+int scrcol = 0;
+int keymode = 1;
+
+int bios_key = -1, bios_flags = -1;
+
+#ifdef __BORLANDC__
+static int kbd_type = -1;
+#else
+static int kbd_type = 0;
+#endif
+
+main(argc, argv)
+int argc;
+char ** argv;
+{
+ int ch, by;
+ union REGS regs;
+ short far * ptr = (short far * ) 0x0040001AL;
+ int i;
+
+ if( argc > 1 ) keymode = atoi(argv[1]);
+
+ if( keymode & 4 ) { keymode &= -5; kbd_type = 0 ; }
+
+ signal(SIGINT, SIG_IGN);
+
+ cprintf("Keyboard testing: Press Escape to exit\r\n");
+ orig_keybd = _dos_getvect(KEYBD);
+ _dos_setvect(KEYBD, keybd);
+
+ do
+ {
+ ch = get_key();
+
+ if( (ch&0xFF00) == KEY_SPECIAL + KEY_DIRECT + KEY_OTHER )
+ {
+ if( bios_flags != -1 )
+ {
+ cprintf(">\r\n");
+ if( bios_key != -1 )
+ cprintf( "BIOS %04x, FLGS: %04x\n", bios_key, bios_flags);
+ else if( bios_flags != -1 )
+ cprintf( "BIOS ----, FLGS: %04x\n", bios_flags);
+ scrcol=2;
+ cprintf(" <");
+ }
+ if( scrcol > 76 ) { cprintf("\r\n"); scrcol = 0; }
+ if( scrcol == 0 ) { cprintf("<"); scrcol += 1; }
+ write_scan(ch&0xFF);
+ }
+ else if( ch != -1 )
+ {
+ cprintf(">\r\n");
+ if( bios_key != -1 )
+ cprintf( "BIOS %04x, FLGS: %04x: ", bios_key, bios_flags);
+ else if( bios_flags != -1 )
+ cprintf( "BIOS ----, FLGS: %04x: ", bios_flags);
+ else
+ cprintf( "BIOS ----, FLGS: ----: ");
+ cprintf("Got key = 0x%04x is: ", ch);
+
+ if( ch & KEY_SPECIAL )
+ {
+ cprintf("Special-");
+ if( ch & KEY_CTRL ) cprintf("Ctrl-");
+ if( ch & KEY_SHIFT ) cprintf("Shift-");
+ if( ch & KEY_ALT ) cprintf("Alt-");
+ if( ch & KEY_ALTGR ) cprintf("AltGr-");
+ if( ch & KEY_DIRECT ) cprintf("Scan-");
+ by = (ch & 0xFF);
+ }
+ else
+ {
+ cprintf("ASCII-");
+ by = (ch & 0xFFF);
+ if( ch & KEY_DIRECT ) cprintf("Code-");
+ }
+ if( ch & KEY_PAD ) cprintf("KeyPad-");
+ if( ch & KEY_OTHER ) cprintf("Other-");
+
+ switch( ch & KEY_SPECIAL )
+ {
+ case KEY_SPECIAL:
+ if( ch & KEY_DIRECT )
+ cprintf("0x%02x\r\n", by);
+ else if((by&0xF0)==0x80 )
+ cprintf("F%d\r\n", by&0xF);
+ else if((by&0xF0)==0x90 )
+ cprintf("K%d\r\n", by&0xF);
+ else
+ {
+ case 0:
+ if( by >= ' ' && by <= '~' )
+ cprintf("'%c'\r\n", by);
+ else
+ cprintf("0x%02x\r\n", by);
+ }
+ }
+
+ scrcol=5;
+ cprintf(": ");
+ if( keymode ) write_dosemu(ch); else write_xenix(ch);
+ cprintf(" <");
+ }
+ }
+ while( (ch &0x80FF) != '\033' );
+
+ _dos_setvect(KEYBD, orig_keybd);
+
+ while( get_key() != -1 ) ;
+
+ if( scrcol ) { cprintf("\r\n"); scrcol = 0; }
+}
+
+void interrupt far keybd()
+{
+#ifdef __BORLANDC__
+register int i;
+
+ i = inp(0x60);
+
+ _CX = 0xFE00 + (i&0xFF);
+ _AH = 0x05; geninterrupt(0x16);
+
+ if( keymode&2 )
+ {
+ _AH = 0x12; geninterrupt(0x16); i = _AX;
+ _CX = 0xFF00 + (i&3) + ((i&0xF00)>>6) + ((i>>9)&0x40);
+ _AH = 0x05; geninterrupt(0x16);
+ }
+#endif
+
+ _chain_intr(orig_keybd);
+}
+#endif
+
+xmit(ch)
+{
+ ch &= 0xFF;
+ if( ch < ' ' )
+ {
+ cprintf("^%c", ch+'@');
+ scrcol++;
+ }
+ else
+ cprintf("%c", ch);
+ scrcol++;
+}
+
+static int bioskeydecode[] = {
+ 0x0000, 0x3280, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136,
+ 0x3137, 0x3138, 0x3139, 0x3130, 0x312d, 0x313d, 0x3308, 0x1209,
+ 0x3171, 0x3177, 0x3165, 0x3172, 0x3174, 0x3179, 0x3175, 0x3169,
+ 0x316f, 0x3170, 0x315b, 0x315d, 0x330d, 0x0000, 0x3161, 0x3173,
+ 0x3164, 0x3166, 0x3167, 0x3168, 0x316a, 0x316b, 0x316c, 0x313b,
+ 0x0100, 0x0100, 0x0000, 0x0400, 0x317a, 0x3178, 0x3163, 0x3176,
+ 0x3162, 0x316e, 0x316d, 0x312c, 0x312e, 0x312f, 0x0000, 0x0700,
+ 0x0000, 0x3520, 0x0000, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485,
+ 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x0000, 0x0000, 0x0697,
+ 0x0698, 0x0699, 0x0700, 0x0694, 0x0695, 0x0696, 0x0700, 0x0691,
+ 0x0692, 0x0693, 0x0690, 0x069a, 0x1481, 0x1482, 0x1483, 0x1484,
+ 0x1485, 0x1486, 0x1487, 0x1488, 0x1489, 0x148a, 0x2481, 0x2482,
+ 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, 0x2488, 0x2489, 0x248a,
+ 0x3481, 0x3482, 0x3483, 0x3484, 0x3485, 0x3486, 0x3487, 0x3488,
+ 0x3489, 0x348a, 0x0000, 0x2694, 0x2696, 0x2691, 0x2693, 0x2697,
+ 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138,
+ 0x3139, 0x3130, 0x002d, 0x003d, 0x2699, 0x048b, 0x048c, 0x148b,
+ 0x148c, 0x248b, 0x248c, 0x348b, 0x348c, 0x2698, 0x2700, 0x2695,
+ 0x2700, 0x2692, 0x2690, 0x269a, 0x2009, 0x2700, 0x2700, 0x3697,
+ 0x3698, 0x3699, 0x0000, 0x3694, 0x3695, 0x3696, 0x0000, 0x3691,
+ 0x3692, 0x3693, 0x3690, 0x369a, 0x3700, 0x3009, 0x3700, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+int get_key()
+{
+static int last_flgs = 0;
+static int force_flgs[] = {0, 2, 4, 8};
+static int this_flags = -1;
+
+ int ch, flgs, scan, flgs2;
+ int scand;
+ int i;
+
+ bios_key = bios_flags = -1;
+try_again:; /* If we get a scan generator */
+
+#ifdef __BORLANDC__
+ if( kbd_type < 0 )
+ {
+ kbd_type = 0;
+
+ for(i=0; i<16;i++)
+ {
+ _AH = 0x01; geninterrupt(0x16); if((_FLAGS&0x40)) break;
+ _AH = 0x00; geninterrupt(0x16);
+ }
+ _AH = 0x05; _CX= 0xFFFF; geninterrupt(0x16);
+ for(i=0; i<16;i++)
+ {
+ _AH = 0x11; geninterrupt(0x16); if((_FLAGS&0x40)) break;
+ _AH = 0x10; geninterrupt(0x16);
+ if( _AX == 0xFFFF )
+ {
+ kbd_type = 0x10;
+ break;
+ }
+ }
+ cprintf("Keyboard is %sT\n", kbd_type?"A":"X");
+ }
+
+ _AH = kbd_type+1; geninterrupt(0x16);
+ i = (_FLAGS&0x40);
+
+ _AH = kbd_type+2; geninterrupt(0x16); flgs = _AX;
+ if( !kbd_type ) flgs &= 0xFF;
+
+#else
+ i = !_bios_keybrd(_KEYBRD_READY);
+
+ flgs = _bios_keybrd(_KEYBRD_SHIFTSTATUS);
+#endif
+
+ if( keymode == 3 ) { flgs = 0; this_flags= -1; }
+
+ if(!(flgs&0x8)) flgs &= ~0x0A00;
+
+ if(i)
+ {
+ if( flgs != last_flgs )
+ {
+ ch = 0;
+ last_flgs = flgs;
+ i=0;
+ if( (flgs & 0x500) == 0x500 ) ch |= KEY_CTRL;
+ if( (flgs & 0xA00) == 0xA00 ) ch |= KEY_ALT|KEY_ALTGR;
+ if(!i)
+ {
+ if( (flgs & 0x001) ) i++;
+ if( (flgs & 0x002) ) i++;
+ if( (flgs & 0x004) ) i++;
+ if( (flgs & 0x008) ) i++;
+ }
+
+ if( i>1 )
+ {
+ if( flgs & 0x4 ) ch |= KEY_CTRL;
+ if( flgs & 0x3 ) ch |= KEY_SHIFT;
+ if( (flgs & 0x0A00) )
+ ch |= ((flgs&0x0200)?KEY_ALT:0) + ((flgs&0x0800)?KEY_ALTGR:0) ;
+ else
+ ch |= ((flgs&0x08)?KEY_ALT:0);
+ }
+
+ if( ch )
+ {
+ bios_key = -1; bios_flags = flgs;
+ return (ch + KEY_SPECIAL);
+ }
+ }
+ return -1;
+ }
+ else
+ {
+#ifdef __BORLANDC__
+ _AH = kbd_type; geninterrupt(0x16);
+ ch = (unsigned) _AX;
+#else
+ ch = _bios_keybrd(_KEYBRD_READ);
+#endif
+ }
+
+ if( this_flags != -1 )
+ {
+ flgs = ( flgs & 0x70F0 )
+ + ( this_flags & 3 )
+ + ((this_flags & 0x3C) << 6 )
+ + ((this_flags & 0x40) << 9 );
+ if( flgs & 0x500 ) flgs |= 0x04;
+ if( flgs & 0xA00 ) flgs |= 0x08;
+ this_flags = -1;
+ }
+
+ if( ( ch & 0xFF00 ) == 0xFF00 ) { this_flags = ch; goto try_again; }
+ if( ( ch & 0xFF00 ) == 0xFE00 )
+ return KEY_SPECIAL + KEY_DIRECT + KEY_OTHER + (ch&0xFF);
+
+ last_flgs = flgs;
+ bios_key = ch; bios_flags = flgs;
+
+ flgs &= 0x0A0F;
+ if( ch == 0 ) return KEY_OTHER + 0x03;
+
+ scan = ((ch>>8)&0xFF);
+ ch &= 0xFF;
+
+ if( scan == 0 ) return ch + KEY_DIRECT;
+ if( scan == 0xE0 ) scan = 0xA4 + 2*(ch < ' ');
+
+ flgs2 = 0;
+ if( ch == 0xE0 ) { flgs2 |= KEY_PAD; ch = 0; }
+
+ /* Check for forced flags */
+ if( ch == 0 && (flgs&0xF) == 0 )
+ flgs |= force_flgs[(bioskeydecode[scan]>>12)&3];
+
+ if( flgs & 0x4 ) flgs2 |= KEY_CTRL;
+ if( flgs & 0x3 ) flgs2 |= KEY_SHIFT;
+
+ if( (flgs & 0x0A00) )
+ flgs2 |= ((flgs&0x0200)?KEY_ALT:0) + ((flgs&0x0800)?KEY_ALTGR:0) ;
+ else
+ flgs2 |= ((flgs&0x08)?KEY_ALT:0);
+
+ if( ch ) switch(flgs2)
+ {
+ case 0: case KEY_CTRL: case KEY_SHIFT:
+ switch((bioskeydecode[scan]>>8)&7)
+ {
+ case 1:
+ return ch;
+ case 2:
+ if( flgs2 == 0 ) return ch + KEY_OTHER;
+ break;
+ case 3:
+ if( (flgs2 & ~KEY_CTRL) == 0 ) return ch + KEY_OTHER;
+ break;
+ case 4:
+ if( (flgs2 & ~KEY_SHIFT) == 0 ) return ch;
+ if( flgs2 == KEY_CTRL ) return (ch&0x1F);
+ break;
+ case 5:
+ if( flgs2 == 0 ) return ch;
+ break;
+ case 6:
+ if( flgs2 == 0 ) return ch + KEY_PAD;
+ break;
+ case 7: return ch + KEY_PAD;
+ }
+ }
+
+ flgs2 |= KEY_SPECIAL;
+
+ if( ((bioskeydecode[scan]>>8)&6) == 6 && (flgs&0x08) == 0 && kbd_type )
+ flgs2 ^= KEY_PAD;
+
+ if( ((bioskeydecode[scan]>>8)&7) == 4 && ch )
+ ;
+ else if(bioskeydecode[scan]&0xFF)
+ return flgs2 + (bioskeydecode[scan]&0xFF);
+
+ return flgs2 + KEY_DIRECT + scan;
+}
+
+unsigned char scan_desc[] = {
+ 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 0,
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 10, 'C', 'a', 's',
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 0, 0, 'S', 0, 'z', 'x', 'c', 'v',
+ 'b', 'n', 'm', ',', '.', '/', 'T', 0, 'A', ' ', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 'E', 'F', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+char hextbl[] = "0123456789abcdef";
+
+/* Write scancodes, in this mode you really need a compatible program on
+ * the host, but you can just about type 'reset<cr>' and have it work
+ */
+write_scan(scan)
+int scan;
+{
+static int lastscan = -1;
+ int by;
+
+ scan &= 0xFF;
+
+ if( scan == lastscan+0x80 )
+ { xmit('~'); xmit('\b'); }
+ else if( scan == 0xE0 || scan == 0xE1 )
+ xmit('E'+scan-0xE0);
+ else if( by = scan_desc[scan&0x7F] )
+ {
+ if( scan & 0x80 )
+ { xmit('!'); xmit(by); }
+ else
+ xmit(by);
+ }
+ else
+ { xmit('~'); xmit(hextbl[scan>>4]); xmit(hextbl[scan&0xF]); }
+ lastscan = scan;
+}
+
+/*
+ * This keyboard gives a pattern of control sequences that makes just about
+ * every keypress distinct. It does need a compatible host program but its
+ * useable as a generic terminal type unlike the scancodes.
+ */
+write_dosemu(ch)
+int ch;
+{
+#define CT_KEY 0x1E
+ int by = (ch & 0xFF);
+
+ /* First we swap round ^M and Return, likewise BS, Tab and Esc */
+ if( ( ch & 0xFF00 ) == KEY_OTHER || ( ch & 0xFF00 ) == 0 )
+ {
+ /* Make it so we can detect the 'other' keys */
+ if( strchr("\b\t\r\n\033\003\177", by) )
+ {
+ if( ch & KEY_OTHER )
+ ch ^= KEY_OTHER;
+ else
+ by = ((ch = KEY_SPECIAL+KEY_CTRL+tolower(by+'@')) & 0xFF);
+ }
+ }
+
+ if( ch & 0xFF00 )
+ {
+ if( ch & KEY_SPECIAL )
+ {
+ if( by == 0 ) return;
+
+ if( ch & KEY_ALT ) { xmit(CT_KEY); xmit('a'); }
+ if( ch & KEY_CTRL ) { xmit(CT_KEY); xmit('c'); }
+ if( ch & KEY_SHIFT ) { xmit(CT_KEY); xmit('s'); }
+ if( ch & KEY_ALTGR ) { xmit(CT_KEY); xmit('g'); }
+ if( ch & KEY_PAD ) { xmit(CT_KEY); xmit('k'); }
+ /* if( ch & KEY_OTHER ) { xmit(CT_KEY); xmit('o'); } */
+
+ if( ch & KEY_DIRECT )
+ {
+ xmit(CT_KEY); xmit('~');
+ xmit(hextbl[by>>4]); xmit(hextbl[by&0xF]);
+ }
+ else if((by&0xF0)==0x80 )
+ {
+static char fkeys[] = "01234567890-=..";
+ if( by == 0x80 )
+ {
+ xmit('\033');
+ xmit('\033');
+ }
+ else
+ {
+ xmit(CT_KEY);
+ xmit(fkeys[by&0xF]);
+ }
+ }
+ else if((by&0xF0)==0x90 )
+ {
+ xmit(CT_KEY);
+ xmit('K');
+ xmit(hextbl[by&0xF]);
+ }
+ else
+ xmit(by);
+ }
+ else
+ {
+ if( ch & KEY_PAD ) { xmit(CT_KEY); xmit('k'); }
+ if( ch & KEY_OTHER ) { xmit(CT_KEY); xmit('o'); }
+ if( ch & KEY_DIRECT ) { xmit(CT_KEY); xmit('z'); }
+ xmit(by);
+ }
+ }
+ else if( by == CT_KEY )
+ {
+ xmit(CT_KEY); xmit('c'); xmit(tolower(CT_KEY+'@'));
+ }
+ else
+ {
+ xmit(by);
+ if( by == '\033' )
+ xmit(by);
+ }
+}
+
+/*
+ * This generates key sequences compatible with the SCO-Xenix console.
+ * In addition many extra key combinations generate distinct codes.
+ * But there are normally several ways of generating each standard key.
+ *
+ * This key mapping is designed for easy use with terminfo nevertheless
+ * it has potentially 96 function key + 104 alt/ctrl/shift&letter codes.
+ */
+write_xenix(ch)
+int ch;
+{
+ int by;
+ /* 012345678901234567890123456 789012 */
+static char normal[] = " MNOPQRSTUVWX LFBGDECHAI\177 ";
+static char shift [] = " YZabcdefghij 0123456789\177 ";
+static char ctrl [] = " klmnopqrstuv \177 ";
+static char ctrshf[] = " wxyz@[\\]^_`{ \177 ";
+
+ /* This seems to be a pain if it stays */
+ if( ch == KEY_SPECIAL+KEY_SHIFT+'\r' ) ch = '\r';
+ if( ch == KEY_SPECIAL+KEY_SHIFT+' ' ) ch = ' ';
+
+ if( ch & KEY_SPECIAL )
+ {
+ if( ch & (KEY_ALT|KEY_ALTGR|KEY_DIRECT) )
+ write_dosemu(ch);
+ else if( (ch & 0xE0) != 0x80 )
+ write_dosemu(ch);
+ else
+ {
+ char * keys;
+ if( ch&KEY_SHIFT )
+ {
+ if( ch&KEY_CTRL ) keys = ctrshf; else keys = shift;
+ }
+ else
+ {
+ if( ch&KEY_CTRL ) keys = ctrl; else keys = normal;
+ }
+ by = keys[ch&0x1F];
+ if( by == ' ' ) write_dosemu(ch);
+ else if( by == '\177' || by >= '0' && by <= '9' )
+ xmit(by);
+ else
+ {
+ xmit('\033');
+ xmit('[');
+ xmit(by);
+ }
+ }
+ }
+ else
+ xmit(ch&0xFF);
+}
diff --git a/libc/msdos/xxx/KEYTEST.EXE b/libc/msdos/xxx/KEYTEST.EXE
new file mode 100644
index 0000000..1dd6553
--- /dev/null
+++ b/libc/msdos/xxx/KEYTEST.EXE
Binary files differ
diff --git a/libc/msdos/xxx/KEYTEST.OBJ b/libc/msdos/xxx/KEYTEST.OBJ
new file mode 100644
index 0000000..10e5755
--- /dev/null
+++ b/libc/msdos/xxx/KEYTEST.OBJ
Binary files differ
diff --git a/libc/msdos/xxx/TALK.C b/libc/msdos/xxx/TALK.C
new file mode 100644
index 0000000..b84c435
--- /dev/null
+++ b/libc/msdos/xxx/TALK.C
@@ -0,0 +1,3931 @@
+/*
+ * Terminal emulator.
+ *
+ * This program is a terminal emulator for the IBM PC.
+ * It's basic emulation is as very close to the SCO-Xenix ANSI console
+ * but it's had a few additions that seemed a good idea at the time.
+ *
+ * Performance: I use this on a 16Mhz 286 at 115k2 baud with RTS flow
+ * control and experience NO lost characters. The PC cannot
+ * quite keep up if flow control is disabled though.
+ *
+ * This program can run at 19200 on a 4.77 Mhz XT with flow control.
+ * (Upto 57600 is possible if the BIOS doesn't disable interrupts)
+ */
+
+/*
+ * TODO:
+ *
+ * - Add file operations (open, read/write block, close)
+ * - Add dubious hack to attempt to make keyboard & timer RTS-Flow active.
+ * - Adjust extra CSI codes to be in small range (CSI $A .. CSI $Z ?)
+ * - Add ZMODEM challange string.
+ * - Add local echo mode. (Only ascii chars ?)
+ * - Add magic echo mode - like local echo but display tempoary.
+ * - Merge BIOS serial with HW serial.
+ */
+/*****************************************************************************
+
+ ANSI Emulation.
+ ===============
+
+ Special characters
+
+ ^G Beep
+ ^H Backspace
+ ^I Tab
+ ^J Linefeed
+ ^L Clear screen
+ ^M Carriage return
+ ^V Avatar code prefix.
+ ^X Cancel Escape code or string (XXX But ZMODEM)
+ ^[ Escape code prefix
+
+ Escape codes
+
+ ^[ [ CSI code - see below.
+ ^[ P DCS Code, as CSI followed by string and ST
+ ^[ \ ST - String terminator.
+
+ ^[ ( Font select
+ U IBM CP 437
+ u IBM CP 437 with 0x00-0x7f replicated to 0x80-0xFF
+ B ISO 8859-1 + DIRECT FONT 0x00-0x1F in 0x80-0x9F.
+ 0 VT100 Graphics + DIRECT FONT 0x80-0xFF
+ A UK ASCII
+
+ ^[ 7 Save cursor position (XXX Attribute?)
+ ^[ 8 Restore cursor position (XXX Attribute?)
+
+ ^[ M Reverse LF (Not implemented)
+
+ ^[ Q SCO Function key redefinition (Only if !AT_BIOS_KEY)
+
+ ^[ > Keyboard normal (if AT_BIOS_KEY)
+ ^[ = Keyboard in dosemu/keypad mode. (if AT_BIOS_KEY)
+
+ Simple ANSI CSI codes
+
+ CSI A Cursor Up
+ CSI B Cursor Down
+ CSI C Cursor Right
+ CSI D Cursor Left
+ CSI H Cursor to position.
+ CSI J Screen area clear (SCO honours attributes)
+ CSI K Line area clear (SCO honours attributes)
+ CSI m Attributes (See detail)
+ CSI s Save cursor position
+ CSI u Restore cursor position
+
+ SCO ANSI CSI codes
+
+ CSI @ Insert chars
+ CSI E Col 0, Cursor Down
+ CSI F Col 0, Cursor Up
+ CSI H Cursor to (r,c) position.
+ CSI L Insert lines
+ CSI M Delete lines
+ CSI P Delete characters
+ CSI S Scroll up (XXX)
+ CSI T Scroll Down (XXX)
+ CSI X Clear characters
+ CSI Z Back tab
+ CSI a Cursor Right
+ CSI e Col 0, Cursor Down
+ CSI f Cursor to (r,c) position.
+ CSI g Write Specific font char (AM mode always = 0, font always Raw)
+ CSI =B Beep type
+ CSI =C Cursor type
+ CSI =E Background bold or blink.
+ CSI =F Default foreground colour (NB Colour is in IBM VGA order)
+ CSI =G Default background colour (NB Colour is in IBM VGA order)
+ CSI =H Reverse foreground colour (NB Colour is in IBM VGA order)
+ CSI =I Reverse background colour (NB Colour is in IBM VGA order)
+ CSI =J Graphic foreground colour (NB Colour is in IBM VGA order)
+ CSI =K Graphic background colour (NB Colour is in IBM VGA order)
+
+ Additional ANSI CSI codes
+
+ CSI } Page flipping & Macros.
+ CSI ?lh Set/reset mode (am if arg == 7)
+ CSI i Printer control.
+ DCS $| Message line (DCS code)
+
+ DCS for full setup (Keyboard, font, am, zapmsg, default attrs)
+ - (This page or all pages and default)
+
+ CSI&DCS for open/read/write/close file.
+ CSI for inquire session hash key.
+
+ Dangerous codes to have 4 digit PIN number (generated for session)
+
+
+ VT 52 codes - (Not implemented)
+
+ if c in "ABCDHJK" do_ansi of same code.
+ if c == Y -> cursor position.
+ if c == I -> ^[M
+ if c == Z -> xmits("\033\\Z") or something
+
+ if c == .. -> Add attribute and charset extras.
+
+
+*****************************************************************************
+
+*****************************************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <dos.h>
+#include <bios.h>
+#include <process.h>
+#include <signal.h>
+#include <string.h>
+#include <malloc.h>
+#include <stdlib.h>
+
+#define LINUX_DEFAULTS
+
+#define RS8250 /* Hardware RS-232 driver */
+#define BEEPER /* Interrupt driven beeper */
+#define MEM_SCR /* Use Hardware screen memory */
+#define KBDRTS /* Flow control on keyboard interrupt */
+#define AT_BIOS_KEY /* AT keyboard + DOSemu keymapping */
+#define SCO_KEYMAP /* Make keyboard look SCOish */
+
+#define XFORKDOS /* Key to spawn shell */
+#define XPRINTER /* Almost useless but does (just) work */
+#define XZMODEM /* Beware DSZ has an 16bit for the speed! */
+#define XAVATAR /* Decode dos 'AVATAR' screen codes */
+
+#ifdef MEM_SCR /* All the following are possible only if MEM_SCR is set */
+
+#define SCO_ANSI /* Decode SCO ansi control codes. */
+#define MAXPAGE 10 /* Multiple screens */
+#define SAVEBLOCK 3072 /* Screen macros */
+#define XSCO_REMAP /* Allow SCO key remap functions (!AT_BIOS_KEY) */
+
+#define XTSRPROG /* Currently only works with MSC 5.1 */
+#define XAVATAR_PLUS /* More avatar functions */
+#endif
+
+/* Old or non-working stuff */
+#define XOLDBEEPER
+#define XFLDATTR
+
+#if defined(__STDC__) || defined(__BORLANDC__)
+#define _(x) x
+#else
+#define _(x) ()
+#endif
+
+#ifdef OLDBEEPER
+int duration = 0x800;
+int freq = 0x1000;
+int warble = 1;
+
+int soundval = -1;
+int soundcnt = -1;
+int soundfreq= -1;
+int sounddir = -1;
+#endif
+#ifdef BEEPER
+int duration = 5;
+int freq = 0x600;
+int lastfreq;
+
+int soundval = -1;
+int soundcnt = -1;
+
+#define TIMER 0x1C
+void ( interrupt far *orig_timer_int)();
+void interrupt far timer_int();
+#endif
+
+#ifdef KBDRTS
+#define KBDINT 0x09
+void ( interrupt far *orig_kbd_int) _((void));
+void interrupt far kbd_int _((void));
+#endif
+
+#ifdef PRINTER
+int in_transprt = 0;
+int print_dev = 0;
+#endif
+
+#define FALSE 0
+#define TRUE !FALSE
+
+#define RS232 0x14
+#define INITRS 0
+#define WRITECH 1
+#define READCH 2
+#define STATUS 3
+#define FOSINIT 4
+
+#define DTARDY 0x100
+#define ZFLAG 0x40
+
+#define CHAROUT 2
+#define CHARIN 6
+
+#ifdef AT_BIOS_KEY
+#define KEY_SPECIAL (int)0x8000
+#define KEY_PAD 0x4000
+#define KEY_OTHER 0x2000
+#define KEY_DIRECT 0x1000
+#define KEY_ALT 0x0800
+#define KEY_ALTGR 0x0400
+#define KEY_CTRL 0x0200
+#define KEY_SHIFT 0x0100
+
+#define DOS_KEY (KEY_SPECIAL+KEY_ALT+'d')
+#define EXITKEY (KEY_SPECIAL+KEY_SHIFT)
+#define SYSLKEY (KEY_SPECIAL+KEY_SHIFT)
+
+int sysline_warn = 0;
+#else
+#define EXITKEY 0x2D00
+#define DOS_KEY 0x2000
+#define SYSLKEY 0x1F00
+#endif
+
+void main _((int argc, char ** argv));
+int keybd _((void));
+int xmit _((int ch));
+void putstr _((char * str));
+void init_vid _((void));
+int test_svga_mode _((void));
+void end_vid _((void));
+void putscrn _((int c));
+
+void init_beep _((void));
+void beep_on _((void));
+void sounder _((void));
+void beep_set _((int f, int p));
+void clear_beep _((void));
+
+#ifdef MEM_SCR
+void putansi _((int c));
+void litput _((int c));
+void rawput _((int c));
+void set_pos _((int line, int col));
+void update_page _((void));
+void updateline _((int to));
+void fetch_page _((void));
+void fetch_line _((int from));
+void do_ansi _((int cmd, int subcmd, int * args, int argc));
+void scroll _((int from, int to, int lines));
+void clrline _((int to));
+int reset_page _((void));
+void clr_eol _((void));
+void clr_sol _((void));
+void delch _((int chars));
+void inch _((int chars));
+void zapch _((int chars));
+void set_blink _((int flg));
+void move_cur _((int row, int col));
+void set_curtype _((int a, int top, int bot));
+#endif
+#ifdef SAVEBLOCK
+void read_block _((int blk));
+void save_block _((int blk));
+#endif
+
+void setup _((int port, int flags));
+void clearup _((void));
+void do_xmit _((void));
+void serial _((void));
+
+#ifndef RS8250
+int chrdy _((void));
+#else
+int get_c _((void));
+void chfetch _((void));
+void setints _((void));
+void clrints _((void));
+void rtsflow _((int stop));
+void init_kbd _((void));
+void clear_kbd _((void));
+#endif
+
+int get_key _((void));
+void write_scan _((int scan));
+void write_dosemu _((int ch));
+void write_unix _((int ch));
+
+/*xYx*/
+void message();
+
+int isfossil = 0;
+int fossilfunc = 0;
+int mnp_fossil = 0;
+
+int mask = 0xFF;
+
+union REGS iregs, oregs;
+
+int nsize = 0;
+char empty[4096];
+#define full (empty+sizeof(empty))
+char * putptr = empty;
+char * getptr = empty;
+
+char xmit_buf[512];
+char *xmit_put=xmit_buf, *xmit_get=xmit_buf;
+
+/***************************************************************************/
+
+#ifdef MEM_SCR
+
+#define intvid(reg) int86(0x10, &reg, &reg)
+#ifndef MAXPAGE
+#define MAXPAGE 1
+#endif
+
+int page_no;
+int dos_cur;
+int dos_mode;
+int dos_line;
+int dos_col;
+int line_len;
+int scr_len;
+int is_ega_plus;
+
+struct physical_scr
+{
+ int far * scrptr;
+ int dumb ;
+ int this_page ;
+ int line;
+ int col;
+}
+ phy_scr;
+
+struct page_descr
+{
+ int ** lines;
+ int col;
+ int line;
+ int charflip;
+ int chartran;
+ int attr;
+ int dirtypg;
+ int * dirty;
+
+ int * page;
+ int scol, sline;
+ int std_col;
+ int rev_col;
+ int gr_col;
+ int clr_col;
+
+#ifdef AT_BIOS_KEY
+ int key_mode; /* 0 = Unix, 1 = dosemu */
+#endif
+#ifdef SCO_ANSI
+ int am; /* 1 = can't use col 80, 2 = no autowrap */
+#endif
+ int honour_attr; /* Area clears honour attribute */
+ int reset_done;
+}
+ pages[MAXPAGE];
+
+#if MAXPAGE == 1
+#define curpage pages
+#else
+struct page_descr * curpage = pages;
+#endif
+
+int args[10];
+int argc;
+int tchar;
+int echar;
+
+char dcs[256], *dcs_ptr;
+
+int sysline[80];
+int syslineno = -1;
+int syslinetmp = 0;
+int syslinedirty = 0;
+int syslineold = -1;
+
+#endif
+
+/***************************************************************************/
+
+#ifdef SCO_REMAP
+extern int kbtab[];
+extern int keyxlate[];
+#define KEYTABSIZE 64
+#endif
+
+#ifdef SAVEBLOCK
+
+#define max_blk 100
+
+int save_flag = 0;
+int read_flag = 0;
+char save_buf[SAVEBLOCK];
+char * save_ptr;
+char * blocks[max_blk];
+
+#endif
+
+/***************************************************************************/
+
+#ifdef TSRPROG
+#define TSR 0x31
+#define KEYBD 0x16
+#define OLDKB 0x65
+
+void ( interrupt far *orig_key_int)();
+void interrupt far key_int();
+int tsrflag = 0;
+char far * dos_screen;
+
+#ifndef __BORLANDC__
+extern
+struct irq_stack
+{
+ int es;
+ int ds;
+ int di;
+ int si;
+ int bp;
+ int sp;
+ int bx;
+ int dx;
+ int cx;
+ int ax;
+ int pc;
+ int cs;
+ int flgs;
+} far * sp_save;
+#endif
+
+#endif
+
+/***************************************************************************/
+
+long speeds[] = { 110, 150, 300, 600,
+ 1200, 2400, 4800, 9600,
+#ifdef RS8250
+ 19200, 38400, 115200, 57600,
+ 28800, 23040, 14400, 75,
+ 50, 134, 200, 1800,
+#endif
+ 0 };
+
+/***************************************************************************
+ * Main, here we go
+ */
+void main(argc, argv)
+int argc;
+char ** argv;
+{
+ int ar;
+#if defined(RS8250) && defined(LINUX_DEFAULTS)
+ int speed = 0x143; /* 115200, np, 1s, 8b */
+#else
+ int speed = 0xE3; /* 9600, np, 1s, 8b */
+#endif
+ int port = 0;
+
+ signal(SIGINT, SIG_IGN); /* Ignore ^C */
+
+ init_vid();
+
+ for(ar=1; ar<argc; ar++)
+ {
+ if(argv[ar][0] == '-' || argv[ar][0] == '/')
+ argv[ar]++;
+
+ if(strcmp(argv[ar], "8") == 0)
+ mask = 0xFF;
+ else if(strcmp(argv[ar], "7") == 0)
+ mask = 0x7F;
+ else if(argv[ar][0] == 's' )
+ {
+ long sp; int i;
+ sp = atol(argv[ar]+1);
+ for(i=0; speeds[i] && speeds[i] != sp ; i++);
+ if( speeds[i] == 0 )
+ {
+ printf("Speed unsupported by BIOS\n");
+ exit(1);
+ }
+ speed = (speed & 0x1F) | (i<<5);
+ }
+#ifdef TSRPROG
+ else if(strcmp(argv[ar], "t") == 0)
+ tsrflag = 1;
+#endif
+#ifdef MEM_SCR
+ else if(strcmp(argv[ar], "d") == 0)
+ phy_scr.dumb = 1;
+#endif
+ else if(argv[ar][0] == 'p')
+ {
+ port = argv[ar][1] - '1';
+ if( port > 3 || port < 0 || argv[ar][2] != '\0' )
+ {
+ printf("Illegal Port number\n");
+ exit(1);
+ }
+ }
+ else
+ {
+ printf("Illegal argument\n");
+ exit(1);
+ }
+ }
+
+#ifdef TSRPROG
+ tsrinit();
+#endif
+
+ setup(port, speed);
+
+#ifdef KBDRTS
+ init_kbd();
+#endif
+#ifdef BEEPER
+ init_beep();
+#endif
+
+#ifdef MEM_SCR
+ fetch_page();
+ for(ar=0; ar<80; ar++) sysline[ar] = 0x7020;
+#endif
+
+ putstr("Terminal emulator.\r\n");
+
+ if( isfossil && mnp_fossil )
+ putstr("Fossil communications driver with MNP support found\r\n");
+ else if( isfossil )
+ putstr("Fossil communications driver found\r\n");
+ putstr("Connected\r\n");
+
+ while(keybd())
+ {
+#ifdef OLDBEEPER
+ sounder();
+#endif
+ serial();
+ }
+
+#ifdef OLDBEEPER
+ clear_beep();
+#endif
+#ifdef TSRPROG
+ tsrexit(0);
+#endif
+#ifdef BEEPER
+ clear_beep();
+#endif
+#ifdef KBDRTS
+ clear_kbd();
+#endif
+ clearup();
+ end_vid();
+ exit(0);
+}
+
+/***************************************************************************/
+
+#ifdef TSRPROG
+
+/***************************************************************************
+ * Check the tsr isn't already running and install our IRQ handler.
+ */
+tsrinit()
+{
+ orig_key_int = _dos_getvect(OLDKB);
+
+ if( orig_key_int != 0 )
+ {
+ printf("ALREADY RUNNING USE HOTKEY\n");
+ exit(0);
+ }
+
+ if( tsrflag )
+ {
+ save_stack(100);
+
+ orig_key_int = _dos_getvect(KEYBD);
+ _dos_setvect(OLDKB, orig_key_int);
+
+ dos_screen = (char far *) malloc(line_len*scr_len*2);
+ movedata( FP_SEG(phy_scr.scrptr), FP_OFF(phy_scr.scrptr),
+ FP_SEG(dos_screen), FP_OFF(dos_screen),
+ scr_len*line_len*2);
+ }
+}
+
+/***************************************************************************
+ * Actually go TSR.
+ */
+tsrexit(rtn)
+int rtn;
+{
+ extern unsigned int _psp;
+ extern unsigned int _abrktb, _asizds, _atopsp, _abrkp;
+ unsigned int pgmsz;
+ struct SREGS srg;
+
+ if( tsrflag )
+ {
+ int i;
+
+ movedata( FP_SEG(dos_screen), FP_OFF(dos_screen),
+ FP_SEG(phy_scr.scrptr), FP_OFF(phy_scr.scrptr),
+ scr_len*line_len*2);
+ move_cur(dos_line, dos_col);
+
+ _dos_setvect(KEYBD, key_int);
+
+ /* pgmsz Should be Data seg size + DS - PSP */
+ segread(&srg);
+ pgmsz = (_asizds>>4);
+ pgmsz += 1;
+ pgmsz += srg.ds;
+ pgmsz -= _psp;
+
+ _dos_keep(rtn, pgmsz);
+ }
+ /* Not tsring return */
+}
+
+/***************************************************************************
+ * Check for keycodes to bring TSR in and out
+ */
+void interrupt far key_int()
+{
+static int c;
+static union REGS regs;
+static int flg = 0;
+
+ set_stack();
+ c = (((sp_save->ax)>>8) & 0xFF);
+ if( c == 0 || c == 0x10 )
+ {
+ regs.h.ah = c;
+ int86(OLDKB, &regs, &regs);
+ c = regs.x.ax;
+ sp_save->ax = c;
+
+ if( flg == 0 && c == EXITKEY )
+ {
+ flg=1;
+ _enable();
+ do_looper();
+ _disable();
+ flg=0;
+ }
+ unset_stack();
+ }
+ else
+ {
+ unset_stack();
+ _chain_intr(orig_key_int);
+ }
+}
+
+/***************************************************************************
+ * This is the routine to run the TSR terminal in the foreground.
+ */
+do_looper()
+{
+ int c;
+ union REGS regs;
+
+ regs.h.ah = 3; regs.h.bh = page_no; intvid(regs);
+ dos_line = regs.h.dh;
+ dos_col = regs.h.dl;
+ movedata( FP_SEG(phy_scr.scrptr), FP_OFF(phy_scr.scrptr),
+ FP_SEG(dos_screen), FP_OFF(dos_screen),
+ scr_len*line_len*2);
+
+ curpage->dirtypg = 1; /* Whole screen will be updated 'soon' */
+ phy_scr.line = -1; /* Cursor probably isn't in the right place */
+
+ while(keybd())
+ {
+#ifdef OLDBEEPER
+ sounder();
+#endif
+ serial();
+ }
+
+#ifdef BEEPER
+ soundcnt = -1; /* Turn off beep asap */
+#endif
+
+ movedata( FP_SEG(dos_screen), FP_OFF(dos_screen),
+ FP_SEG(phy_scr.scrptr), FP_OFF(phy_scr.scrptr),
+ scr_len*line_len*2);
+ move_cur(dos_line, dos_col);
+}
+
+#endif
+
+/***************************************************************************
+ * Beeper routines, standard version
+ */
+
+#ifdef BEEPER
+void
+init_beep()
+{
+ orig_timer_int = _dos_getvect(TIMER);
+ _dos_setvect(TIMER, timer_int);
+}
+
+void
+beep_on()
+{
+ _disable();
+ if(soundval == -1 )
+ {
+ soundval = inp(0x61);
+ lastfreq = freq;
+ }
+ else if( lastfreq > 128 )
+ lastfreq = lastfreq/2;
+ else
+ lastfreq = freq;
+ outp(0x61, soundval|3);
+ outp(0x43, 0xb6);
+ outp(0x42, lastfreq&0xFF);
+ outp(0x42, (lastfreq>>8)&0xFF);
+ soundcnt = duration;
+ _enable();
+}
+
+void interrupt far timer_int()
+{
+ if(soundval != -1)
+ {
+ if(soundcnt <= 0)
+ {
+ outp(0x61, soundval);
+ soundval = -1;
+ }
+ soundcnt--;
+ }
+ _chain_intr(orig_timer_int);
+}
+
+void
+beep_set(f,p)
+int f,p;
+{
+ freq = f;
+ duration = (p%100)*182/100+1;
+}
+
+void
+clear_beep()
+{
+ _dos_setvect(TIMER, orig_timer_int);
+ if( soundval != -1 )
+ outp(0x61, soundval);
+}
+#endif
+
+/***************************************************************************
+ * Beeper routines, older non-interrupt version.
+ */
+#ifdef OLDBEEPER
+void
+beep_on()
+{
+ if(soundval == -1 )
+ soundval = inp(0x61);
+ outp(0x61, soundval|3);
+ outp(0x43, 0xb6);
+ outp(0x42, freq&0xFF);
+ outp(0x42, (freq>>8)&0xFF);
+ soundcnt = duration;
+ soundfreq= freq;
+ sounddir = -warble;
+}
+
+void
+sounder()
+{
+ if( soundcnt > 0 )
+ {
+ soundcnt--;
+ outp(0x42, soundfreq&0xFF);
+ outp(0x42, (soundfreq>>8)&0xFF);
+ soundfreq += sounddir;
+ if( soundfreq < freq-500 || soundfreq > freq )
+ sounddir = -sounddir;
+ }
+ else if( soundcnt == 0 )
+ {
+ soundcnt--;
+ outp(0x61, soundval);
+ soundval = -1;
+ sounddir = -warble;
+ }
+}
+
+void
+beep_set(f,p)
+int f,p;
+{
+ freq = f;
+ duration = (p%100+1)*700;
+ if( p > 99 ) warble=1;
+ else warble = 0;
+}
+
+void
+clear_beep()
+{
+ if( soundval != -1 )
+ outp(0x61, soundval);
+}
+#endif
+
+/***************************************************************************
+ * Fetch a key and forward it to the serial port.
+ * While doing this look for the EXIT key and return FALSE if it is pressed
+ */
+
+int
+keybd()
+{
+ int c;
+ if( (c=get_key()) == -1 ) return TRUE;
+#if SYSLKEY == EXITKEY
+ if( sysline_warn && (c&0xFF) == '\033' )
+ return FALSE;
+#else
+ if( c == EXITKEY )
+ return FALSE;
+#endif
+#ifdef FORKDOS
+#ifdef TSRPROG
+ else if(c == DOS_KEY && !tsrflag)
+#else
+ else if(c == DOS_KEY)
+#endif
+ {
+ int err;
+ char * cmd = getenv("COMSPEC");
+ if( !cmd || !*cmd ) cmd = "command";
+ err = spawnlp(P_WAIT, cmd, "command.com", NULL);
+ fetch_page();
+ if( err == -1 )
+ message("Error trying to run command.com");
+ curpage->dirtypg = 1;
+ return TRUE;
+ }
+#endif
+#ifdef MEM_SCR
+ else if( c == SYSLKEY )
+ {
+#if SYSLKEY == EXITKEY
+ if(syslineno < 0 || syslineno >= scr_len)
+ {
+ syslineno = 0;
+ message("Press Escape to exit terminal emulator");
+ sysline_warn = 1;
+ }
+ else
+ {
+ syslineno = -1;
+ sysline_warn = 0;
+ }
+#else
+ if(syslineno < 0 || syslineno >= scr_len)
+ syslineno = 0;
+ else
+ syslineno = -1;
+#endif
+ }
+#endif
+#ifdef AT_BIOS_KEY
+ else switch(curpage->key_mode)
+ {
+ default: write_unix(c); break;
+ case 1: write_dosemu(c); break;
+ case 2: write_scan(c); break;
+ }
+#else
+#ifdef SCO_KEYMAP
+ else if( bios_keymap(c) )
+ ;
+#endif
+ else if( c&0xFF )
+ xmit(c & mask);
+ else
+ {
+ xmit(0);
+ xmit((c>>8)&mask);
+ }
+#endif
+ return TRUE;
+}
+
+int
+xmit(ch)
+int ch;
+{
+ if( xmit_put >= xmit_buf+sizeof(xmit_buf) && xmit_get != xmit_buf )
+ {
+ int count = xmit_put-xmit_get;
+ memcpy(xmit_buf, xmit_get, count);
+ count = xmit_get - xmit_buf;
+ xmit_put -= count;
+ xmit_get -= count;
+ }
+
+ if( xmit_put >= xmit_buf+sizeof(xmit_buf) )
+ return -1;
+
+ *xmit_put++ = ch;
+
+ do_xmit();
+ return 0;
+}
+
+/***************************************************************************
+ * Simple routine to forward output to LPT1 or the print device set as the
+ * second argument of the '<ESC> [ 5 ; <dev> i'
+ */
+#ifdef PRINTER
+putprnt(ch)
+{
+union REGS prt_regs;
+
+ if( in_transprt )
+ {
+ switch(in_transprt)
+ {
+ case 2: if( ch == '[' ) { in_transprt++; return; }
+ in_transprt = 0;
+ putprnt('\033'); break;
+ case 3: if( ch == '4' ) { in_transprt++; return; }
+ in_transprt = 0;
+ putprnt('\033'); putprnt('['); break;
+ case 4: if( ch == 'i' ) { in_transprt=0; return; }
+ in_transprt = 0;
+ putprnt('\033'); putprnt('['); putprnt('4'); break;
+ }
+ in_transprt = 1;
+ if( ch == '\033' ) { in_transprt++; return; }
+ }
+
+ prt_regs.x.ax = 0x0200;
+ prt_regs.x.dx = print_dev;
+ int86(0x17, &prt_regs, &prt_regs);
+ if( ( prt_regs.x.ax & 0x2A00 ) != 0 )
+ {
+ message("Printer Not Ready ... Please correct");
+ return;
+ }
+ prt_regs.x.ax = ch;
+ prt_regs.x.dx = print_dev;
+ int86(0x17, &prt_regs, &prt_regs);
+}
+#endif
+
+/***************************************************************************
+ * Quick routine to print a string to the screen.
+ */
+void
+putstr(str)
+char * str;
+{
+ while(*str)
+ putscrn(*str++);
+}
+
+
+#ifndef MEM_SCR
+
+/***************************************************************************
+ * Dummy init and end for BIOS screen.
+ */
+void init_vid() { }
+void end_vid() { }
+
+/***************************************************************************
+ * BIOS screen message line; just print the text
+ */
+void
+message(str, val1, val2)
+char * str;
+int val1, val2;
+{
+ static char buf[128];
+ char * p;
+ int i=0;
+
+ sprintf(buf, str, val1, val2);
+ strcat(buf, "\r\n");
+
+ putstr(buf);
+}
+
+/***************************************************************************
+ * BIOS screen put char.
+ */
+void
+putscrn(c)
+int c;
+{
+#ifdef ZMODEM
+static lastchar = ' ';
+#endif
+#ifdef AVATAR
+ extern int avcnt;
+ if( avcnt > 0 || ( avcnt == 0 && ( c == '\026' || c == '\031')))
+ {
+ do_avatar(c);
+ return;
+ }
+ if( c == '\f' )
+ {
+ putstr("\033[2J");
+ return;
+ }
+#endif
+#ifdef OLDBEEPER
+ if( c == '\007' )
+ {
+ beep_on();
+ return;
+ }
+#endif /* OLDBEEPER */
+#ifdef BEEPER
+ if( c == '\007' )
+ {
+ beep_on();
+ return;
+ }
+#endif /* BEEPER */
+#ifdef ZMODEM
+ else if( c == 24 && lastchar == '*' ) /* CTRL-X */
+ {
+#ifdef TSRPROG
+ if( !tsrflag )
+#endif
+ system("dsz d handshake slow rz -rr");
+ }
+
+ lastchar = c;
+#endif
+
+ if( (c&-32)==0
+ && c != '\r'
+ && c != '\n'
+ && c != '\b'
+ && c != '\007'
+ ) return;
+
+ iregs.h.ah = CHAROUT;
+ iregs.h.dl = c;
+ intdos(&iregs, &oregs);
+}
+
+#else
+
+/***************************************************************************
+ * Hardware screen, message line is mobile between TOS and BOS.
+ */
+void
+message(str, val1, val2)
+char * str;
+int val1, val2;
+{
+ static char buf[128];
+ int i;
+ int flg=0;
+
+ memset(buf, '\0', sizeof(buf));
+ sprintf(buf, str, val1, val2);
+
+ for(i=0; i<80; i++)
+ {
+ if( buf[i] == '\0' )
+ {
+ if( sysline[i] == 0x7000 )
+ break;
+ else
+ sysline[i] = 0x7000;
+ }
+ else
+ {
+ if( flg == 1 || buf[i] != ' ' )
+ sysline[i] = buf[i]|(0x7000);
+ else
+ sysline[i] = 0x7000;
+ if( buf[i] != ' ' ) flg = 1;
+ }
+ }
+ syslinedirty = 1;
+ if( syslineno == -1 ) syslinetmp = 1;
+#if SYSLKEY == EXITKEY
+ sysline_warn = 0;
+#endif
+}
+
+/***************************************************************************
+ * Hardware screen, print character.
+ */
+void
+putscrn(c)
+int c;
+{
+#ifdef AVATAR
+ extern int avcnt;
+#endif
+#ifdef ZMODEM
+static lastchar = ' ';
+#endif
+
+#ifdef SAVEBLOCK
+ if( save_flag && c != '\0' )
+ {
+ *save_ptr++ = c;
+ if( save_ptr >= save_buf+sizeof(save_buf) ) save_ptr = save_buf;
+ }
+#endif
+
+ if(0);
+#ifdef AVATAR
+ else if( avcnt > 0 || ( avcnt == 0 && ( c == '\026' || c == '\031')))
+ do_avatar(c);
+#endif
+#ifdef ZMODEM
+ else if( c == 24 && lastchar == '*' ) /* CTRL-X */
+ {
+#ifdef TSRPROG
+ if( !tsrflag )
+#endif
+ {
+ system("dsz d handshake slow rz -rr");
+ fetch_page();
+ curpage->dirtypg = 1;
+ }
+ }
+#endif
+ else
+ putansi(c);
+
+#ifdef ZMODEM
+ lastchar = c;
+#endif
+
+#ifdef SAVEBLOCK
+ if( read_flag == 0 )
+#endif
+ {
+static int cnt = 1000;
+ if( c == '\n' ) cnt -= 80;
+ if( --cnt < 0 )
+ {
+ cnt=1000;
+ update_page();
+ }
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, decode ansi sequence.
+ */
+void
+putansi(c)
+int c;
+{
+static int ansi_state=0;
+ int i;
+ c &= 0xFF;
+
+ if( ansi_state <= 3 ) switch ( c )
+ {
+ case '\t': i = (8 - (curpage->col&7) );
+ curpage->col += i;
+ if( curpage->col > line_len )
+ curpage->col = line_len;
+ return;
+
+ case '\r': curpage->col = 0;
+ return;
+
+ case '\b': if( curpage->col )
+ curpage->col--;
+ return;
+
+ case '\n': curpage->line++;
+ if( curpage->line == scr_len ) scroll(0, scr_len-1, 1);
+ return;
+
+#if defined(SCO_ANSI) || defined(AVATAR)
+ case '\f': scroll( scr_len-1, 0, scr_len);
+ curpage->line=0;
+ curpage->col=0;
+ return;
+#endif
+
+#ifdef OLDBEEPER
+ case '\007':beep_on();
+ return;
+#endif /* OLDBEEPER */
+#ifdef BEEPER
+ case '\007':beep_on();
+ return;
+#endif /* BEEPER */
+
+ case '\030':ansi_state = 0; /* Ctrl-X */
+ return;
+
+ case '\032':ansi_state = 0; /* Ctrl-Z */
+ rawput(0xA8);
+ return;
+
+ case '\033':if( phy_scr.dumb == 0 )
+ {
+ ansi_state = 1;
+
+ for(argc=0; argc<10; argc++) args[argc] = 0;
+ argc = 0;
+ tchar = 0;
+ echar = 0;
+
+ return;
+ }
+ /*FALLTHROUGH*/
+ }
+
+ switch(ansi_state)
+ {
+ default:ansi_state =0;
+
+ case 0: if( c < ' ' && phy_scr.dumb == 0 ) break;
+ litput(c);
+ break;
+
+ case 1: switch(c)
+ {
+ case '\\': /* NO-OP if not in DCS string */
+ ansi_state = 0;
+ break;
+ case 'P':
+ dcs_ptr = dcs;
+ ansi_state = 2;
+ break;
+ case '[':
+ dcs_ptr = 0;
+ ansi_state = 2;
+ break;
+ case '(':
+ ansi_state = 8;
+ break;
+ case '7':
+ curpage->sline = curpage->line;
+ curpage->scol = curpage->col;
+ ansi_state = 0;
+ break;
+ case '8':
+ set_pos(curpage->sline, curpage->scol);
+ ansi_state = 0;
+ break;
+#ifdef AT_BIOS_KEY
+ case '>':
+ curpage->key_mode = 0;
+ ansi_state = 0;
+ break;
+ case '=':
+ curpage->key_mode = 1;
+ ansi_state = 0;
+ break;
+ case '<':
+ curpage->key_mode = 2;
+ ansi_state = 0;
+ break;
+#endif
+#ifdef SCO_REMAP
+ case 'Q':
+ ansi_state = 10;
+ break;
+#endif
+ default:
+ ansi_state = 0;
+ rawput('\033');
+ rawput(c);
+ break;
+ }
+ break;
+
+ case 2: if(( c >= ' ' && c < '0' ) || c == ':' || ( c > ';' && c <= '?' ))
+ {
+ tchar = c;
+ ansi_state = 3;
+ break;
+ }
+ case 3: if( c >= '0' && c <= '9' )
+ {
+ args[argc] = args[argc]*10 + c - '0';
+ break;
+ }
+ else if(c == ';' )
+ {
+ if( ++argc >= 10 )
+ {
+ ansi_state = 0;
+ break;
+ }
+ args[argc] = 0;
+ break;
+ }
+ else if( c >= '@' && c <= '~' )
+ {
+ echar = c;
+ if( dcs_ptr == 0 )
+ {
+ ansi_state = 0;
+ do_ansi( echar, tchar, args, argc+1 );
+ }
+ else
+ {
+ ansi_state = 4;
+ break;
+ }
+ }
+ ansi_state = 0;
+ break;
+
+ /* DCS ... ST processing */
+ case 4: if( c == '\030' || dcs_ptr >= dcs+sizeof(dcs)-1 )
+ ansi_state = 0;
+ else if( c == '\033' )
+ ansi_state = 5;
+ else
+ *dcs_ptr++ = c;
+ break;
+
+ case 5: if( c != '\\' )
+ {
+ if( dcs_ptr >= dcs+sizeof(dcs)-2 || c == '\030' )
+ ansi_state = 0;
+ else
+ {
+ *dcs_ptr++ = '\033';
+ if( c != '\033' ) { *dcs_ptr++ = c; ansi_state = 4; }
+ }
+ break;
+ }
+ *dcs_ptr = '\0';
+ ansi_state = 0;
+
+ if( tchar == '$' && echar == '~' )
+ {
+ dcs[80] = 0;
+ if( *dcs ) message("%s", dcs);
+ else
+ {
+ syslineno = -1;
+ sysline_warn = 0;
+ }
+ }
+ break;
+
+ /* ESC ( <n> Screen language processing */
+ case 8: ansi_state =0;
+ switch(c)
+ {
+ case 'X': curpage->chartran = 0; break;
+ case 'B': curpage->chartran = 1; break;
+ case '0': curpage->chartran = 2; break;
+ case 'A': curpage->chartran = 3; break;
+
+ case 'U': curpage->chartran = 0; break;
+ case 'u': curpage->chartran = 4; break;
+
+ default: curpage->chartran = -1; break;
+ }
+ break;
+
+ /* SCO Function key remapping */
+#ifdef SCO_REMAP
+ case 10: echar = c-'0'; /* FUNCTION KEY NUMBER 0=F1 .. 9=F10 */
+ message("Define function key %d", echar+1);
+ ansi_state = 11;
+ break;
+
+ case 11: tchar = c;
+ ansi_state = 12;
+ break;
+
+ case 12: if( c == tchar ) ansi_state = 0;
+ if( echar >=0 && echar < KEYTABSIZE )
+ {
+ if( c == tchar )
+ {
+ set_key(echar);
+ kbtab[keyxlate[echar]] = (0x300|echar);
+ }
+ else if( c != '^' )
+ add_fnchar(c);
+ else
+ ansi_state = 13;
+ }
+ break;
+ case 13: if( c == tchar ) ansi_state = 0; else ansi_state = 12;
+ if( echar >=0 && echar < KEYTABSIZE )
+ {
+ if( c == tchar )
+ {
+ set_key(echar);
+ kbtab[keyxlate[echar]] = (0x300|echar);
+ }
+ else if( c != '^' )
+ add_fnchar(c& 0x1F);
+ else
+ add_fnchar(c);
+ }
+ break;
+#endif
+
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, Write any byte to screen through the translation table.
+ */
+
+unsigned char iso8859_1[] = {
+ 4, 177, -1, -1, -1, -1, 248, 241, 176, -1, 217, 191, 218, 192, 197, -1,
+ -1, 196, -1, 95, 195, 180, 193, 194, 179, 243, 242, 227, -1, 156, 250, -1,
+
+255, 173, 155, 156, 9, 157, 124, 21, 34, 67, 166, 174, 170, 45, 82, 196,
+248, 241, 253, 51, 39, 230, 20, 250, 44, 49, 167, 175, 172, 171, 51, 168,
+ 65, 65, 65, 65, 142, 143, 146, 128, 69, 144, 69, 69, 73, 73, 73, 73,
+ 68, 165, 79, 79, 79, 79, 153, 120, 237, 85, 85, 85, 154, 89, 80, 225,
+133, 160, 131, 97, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139,
+ 11, 164, 149, 162, 147, 111, 148, 246, 237, 151, 163, 150, 129, 121, 112, 152
+};
+/* Yes I know, a good compiler should complain about that array */
+
+void
+litput(c)
+int c;
+{
+ c &= 0xFF;
+ if( curpage->charflip ) c ^= 0x80;
+ if( curpage->chartran ) switch( curpage->chartran )
+ {
+ case 1:
+ if( (c&0x80) )
+ {
+ if( c&0x60 ) c = iso8859_1[c&0x7F];
+ else c &= 0x1F;
+ }
+ break;
+ case 2:
+ if( c >= 0x60 && c < 0x80 ) c = iso8859_1[c&0x1F];
+ break;
+ case 3:
+ if( c == '#' ) { c = 156; break; }
+ c &= 0x7F;
+ default:
+ if( c < ' ' || c > '~' ) c = -1;
+ break;
+
+ case 4:
+ c &= 0x7F;
+ break;
+ }
+ rawput(c);
+}
+
+void
+rawput(c)
+int c;
+{
+ c &= 0xFF;
+ if( curpage->col >= line_len )
+ {
+ curpage->line++;
+ curpage->col=0;
+ if( curpage->line == scr_len ) scroll(0, scr_len-1, 1);
+ }
+ curpage->lines[curpage->line][curpage->col] = c + (curpage->attr<<8);
+ curpage->dirty[curpage->line] = 1;
+ curpage->col++;
+#ifdef SCO_ANSI
+ if( curpage->am && curpage->col == line_len )
+ {
+ if( curpage->am & 2 )
+ curpage->col--;
+ else
+ {
+ curpage->line++; curpage->col=0;
+ }
+ if( ( curpage->am & 1 ) && curpage->line == scr_len )
+ scroll(0, scr_len-1, 1);
+ }
+#endif
+}
+
+/***************************************************************************
+ * Hardware screen, Set the virtual cursor position.
+ */
+void
+set_pos(line, col)
+int line;
+int col;
+{
+ curpage->line = line;
+ curpage->col = col;
+ if( curpage->line < 0 ) curpage->line = 0;
+ if( curpage->line >= scr_len ) curpage->line = scr_len-1;
+ if( curpage->col < 0 ) curpage->col = 0;
+ if( curpage->col >=line_len ) curpage->col = line_len-1;
+}
+
+/***************************************************************************
+ * Hardware screen, Write screen image to physical screen.
+ */
+void
+update_page()
+{
+ int i;
+
+ if( curpage->col != phy_scr.col || curpage->line != phy_scr.line )
+ {
+ int c;
+ phy_scr.col = curpage->col;
+ phy_scr.line = curpage->line;
+
+ if( curpage->col == line_len )
+ c = line_len-1;
+ else
+ c = curpage->col;
+ move_cur(curpage->line, c);
+ }
+
+ if( syslineno == curpage->line )
+ syslineno = scr_len -1 -syslineno;
+
+ if( curpage->dirtypg )
+ {
+ syslineold = syslineno;
+ syslinedirty = 0;
+ }
+
+ if( syslinetmp && syslineold == -1 )
+ {
+ if( curpage->line == 0 )
+ syslineno = scr_len-1;
+ else
+ syslineno = 0;
+ syslineold = syslineno;
+ }
+
+ if( syslineold != syslineno )
+ {
+ if( syslinetmp )
+ {
+ syslinetmp = 0;
+ syslineno = -1;
+ }
+ if( syslineold != -1 )
+ curpage->dirty[syslineold] = 1;
+ if( syslineno != -1 )
+ syslinedirty = 1;
+ syslineold = syslineno;
+ }
+
+ for(i=0; i<scr_len; i++)
+ if( curpage->dirtypg || curpage->dirty[i] )
+ {
+#ifdef FLDATTR
+ copyattr(i);
+#endif
+ updateline(i);
+ }
+
+ if( syslineno != -1 && syslinedirty )
+ updateline(syslineno);
+ curpage->dirtypg = 0;
+}
+
+#ifdef FLDATTR
+copyattr(lno)
+int lno;
+{
+int i;
+int lastattr = -1;
+
+ for(i=0; i<line_len; i++)
+ {
+ if((curpage->lines[lno][i]&0xFF) == 0xFF)
+ lastattr = (curpage->lines[lno][i]&0xFF00);
+ if( lastattr != -1 )
+ curpage->lines[lno][i] = ((curpage->lines[lno][i]&0xFF)|lastattr);
+ }
+}
+#endif
+
+void
+updateline(to)
+int to;
+{
+ int ll = line_len*2;
+ char far * ptr;
+
+ curpage->dirty[to] = 0;
+ if( to == syslineno )
+ {
+ ptr = (char far *) sysline;
+ syslinedirty = 0;
+ }
+ else
+ ptr = (char far *)(curpage->lines[to]);
+ movedata(FP_SEG(ptr), FP_OFF(ptr),
+ FP_SEG(phy_scr.scrptr), ll*to,
+ ll);
+}
+
+/***************************************************************************
+ * Hardware screen, Fetch physical screen into image memory.
+ */
+void
+fetch_page()
+{
+ int i;
+
+ iregs.h.ah = 3;
+ iregs.h.bh = page_no;
+ intvid(iregs);
+ curpage->line = iregs.h.dh;
+ curpage->col = iregs.h.dl;
+
+ for(i=0; i<scr_len; i++)
+ fetch_line(i);
+}
+
+void
+fetch_line(from)
+int from;
+{
+ int ll = line_len*2;
+ char far * ptr;
+ if( from == syslineno ) return;
+ ptr = (char far *)(curpage->lines[from]);
+ movedata(FP_SEG(phy_scr.scrptr), ll*from,
+ FP_SEG(ptr), FP_OFF(ptr),
+ ll);
+}
+
+/***************************************************************************
+ * Hardware screen, apply an ansi sequence to the current screen image.
+ */
+void
+do_ansi( cmd, subcmd, args, argc )
+int cmd;
+int subcmd;
+int * args;
+int argc;
+{
+ int ar;
+static int colconv[] = { 000, 004, 002, 006, 001, 005, 003, 007,
+ 010, 014, 012, 016, 011, 015, 013, 017 };
+ switch( subcmd )
+ {
+ case 0: switch( cmd )
+ {
+#ifdef SCO_ANSI
+ case '@': inch(args[0]);
+ break;
+#endif
+ case 'A': if( args[0] < 1 ) args[0] = 1;
+ set_pos(curpage->line-args[0], curpage->col);
+ break;
+#ifdef SCO_ANSI
+ case 'E': curpage->col = 0;
+ /* FALLTHROUGH */
+ case 'e':
+#endif
+ case 'B': if( args[0] < 1 ) args[0] = 1;
+ set_pos(curpage->line+args[0], curpage->col);
+ break;
+#ifdef SCO_ANSI
+ case 'a':
+#endif
+ case 'C': if( args[0] < 1 ) args[0] = 1;
+ curpage->col += args[0];
+ if( curpage->col >= line_len )
+ curpage->col = line_len -1;
+ break;
+ case 'D': if( args[0] < 1) args[0] = 1;
+ curpage->col -= args[0];
+ if( curpage->col < 0 )
+ curpage->col = 0;
+ break;
+#ifdef SCO_ANSI
+ case 'F': if( args[0] < 1 ) args[0] = 1;
+ set_pos(curpage->line-args[0], 0);
+ break;
+#endif
+ case 'f':
+ case 'H': set_pos(args[0]-1, args[1]-1);
+ break;
+ case 'J': /* cls */
+ if( args[0] == 2)
+ {
+ scroll( scr_len-1, 0, scr_len);
+ curpage->line=0;
+ curpage->col=0;
+ }
+ else if( args[0] == 0 )
+ {
+ clr_eol();
+ if( curpage->line != scr_len-1 )
+ scroll( scr_len-1, curpage->line+1, scr_len);
+ }
+ else if( args[0] == 1 )
+ {
+ clr_sol();
+ if( curpage->line != 0 )
+ scroll( curpage->line-1, 0, scr_len);
+ }
+ break;
+ case 'K': /* Clear eol */
+ if(args[0] == 0 )
+ clr_eol();
+ else if(args[0] == 1 )
+ clr_sol();
+ else if(args[0] == 2 )
+ clrline(curpage->line);
+ break;
+
+#ifdef SCO_ANSI
+ case 'L': scroll(scr_len-1, curpage->line, args[0]);
+ break;
+
+ case 'M': scroll(curpage->line, scr_len-1, args[0]);
+ break;
+
+ case 'P': delch(args[0]);
+ break;
+
+ case 'S': scroll(0, scr_len-1, args[0]);
+ break;
+
+ case 'T': scroll(scr_len-1, 0, args[0]);
+ break;
+
+ case 'X': zapch(args[0]);
+ break;
+
+ case 'Z': if( args[0] == 0 ) args[0] = 1;
+ set_pos(curpage->line,((curpage->col+7-8*(args[0]))&-8));
+ break;
+#endif
+#ifdef PRINTER
+ case 'i': if( args[0] == 5 )
+ {
+ if( args[1] > 0 && args[1] < 3 ) print_dev = args[1];
+ else print_dev = 0;
+ in_transprt = 1;
+ }
+ break;
+#endif
+
+ case 'm': /* Attributes */
+ for(ar=0; ar<argc; ar++)
+ switch(args[ar])
+ {
+ case 0: curpage->attr = curpage->std_col;
+ break;
+ case 1: curpage->attr |= 0x08;
+ break;
+#ifdef SCO_ANSI
+ case 2: if( dos_mode != 2 && dos_mode != 7 && ar+2<argc )
+ {
+ curpage->std_col = colconv[args[ar+1]&0xF]
+ + (colconv[args[ar+2]&0xF] << 4);
+ curpage->attr = curpage->std_col;
+ if( args[ar+2]&0x8 )
+ set_blink(0);
+ ar+=2;
+ }
+ break;
+ case 3: if( dos_mode != 2 && dos_mode != 7 && ar+1<argc )
+ {
+ set_blink(args[++ar]);
+ }
+ break;
+#endif
+ case 4: if( dos_mode == 7 )
+ curpage->attr = ((curpage->attr & 0xF0)|0x01);
+ break;
+ case 5: curpage->attr |= 0x80;
+ set_blink(1);
+ break;
+ case 7:
+#ifdef SCO_ANSI
+ if( dos_mode != 2 && dos_mode != 7 && ar+2<argc )
+ {
+ curpage->rev_col = colconv[args[ar+1]&0xF]
+ + (colconv[args[ar+2]&0xF] << 4);
+ if( args[ar+2]&0x8 )
+ set_blink(0);
+ ar+=2;
+ }
+#endif
+ curpage->attr = curpage->rev_col;
+ break;
+ case 8: curpage->attr = 0;
+ break;
+#ifdef SCO_ANSI
+ case 10:curpage->charflip = 0;
+ curpage->attr = curpage->std_col;
+ break;
+ case 12:curpage->charflip = 1;
+ curpage->attr = curpage->gr_col;
+ break;
+#endif
+ case 30:case 31:case 32:case 33:
+ case 34:case 35:case 36:case 37:
+ if( dos_mode != 2 && dos_mode != 7 )
+ curpage->attr = ((curpage->attr & 0xF8)
+ |(colconv[args[ar]-30]));
+ break;
+ case 40:case 41:case 42:case 43:
+ case 44:case 45:case 46:case 47:
+ if( dos_mode != 2 && dos_mode != 7 )
+ curpage->attr
+ = ((curpage->attr & 0x8F)
+ |((colconv[args[ar]-40]&0x7)<<4));
+ break;
+ }
+ if( curpage->honour_attr )
+ curpage->clr_col = curpage->attr;
+ break;
+#ifdef SCO_ANSI
+ case 'g': if( curpage->col == line_len )
+ {
+ curpage->line++;
+ curpage->col=0;
+ if( curpage->line == scr_len )
+ scroll(0, scr_len-1, 1);
+ }
+ curpage->lines[curpage->line][curpage->col] =
+ args[0] + (curpage->gr_col<<8);
+ curpage->dirty[curpage->line] = 1;
+ curpage->col++;
+ break;
+#endif
+ case '}':
+#if MAXPAGE != 1
+ if( args[0] == 0 )
+ {
+ args[1] %= MAXPAGE;
+ if( args[1] == phy_scr.this_page ) break;
+ if( pages[args[1]].page == 0 )
+ {
+ phy_scr.this_page = args[1];
+ curpage= pages+phy_scr.this_page;
+ if( reset_page() < 0 )
+ phy_scr.this_page = 0;
+ }
+ else
+ {
+ phy_scr.this_page = args[1];
+ curpage= pages+phy_scr.this_page;
+ curpage->dirtypg = 1;
+ }
+ curpage= pages+phy_scr.this_page;
+ }
+#endif
+#ifdef SAVEBLOCK
+ if(args[0] == 1)
+ {
+ if( read_flag ) break;
+ read_flag = 1; save_flag = 0;
+ read_block(args[1]);
+ read_flag = 0;
+ }
+ else if( args[0] == 2 && argc == 1 )
+ {
+ if( read_flag ) break;
+ save_flag = 1;
+ save_ptr = save_buf;
+ }
+ else if( args[0] == 2)
+ {
+ if( read_flag ) break;
+ save_block(args[1]);
+ }
+#endif
+ break;
+ case 's':
+ curpage->sline = curpage->line;
+ curpage->scol = curpage->col;
+ break;
+ case 'u':
+ set_pos(curpage->sline, curpage->scol);
+ break;
+ }
+ break;
+
+#ifdef SCO_ANSI
+ case '=': switch( cmd )
+ {
+#ifdef OLDBEEPER
+ case 'B': beep_set(args[0], args[1]);
+ break;
+#endif
+#ifdef BEEPER
+ case 'B': beep_set(args[0], args[1]);
+ break;
+#endif
+ case 'C': /* set cursor (0=>norm, 1=>off, 2=>big, x;y=>setit */
+ if( argc <= 1 ) set_curtype(args[0]-1,0,15);
+ if( argc == 2 ) set_curtype(2,args[0],args[1]);
+ break;
+ case 'E': /* set cursor */
+ set_blink(args[0]);
+ break;
+ case 'F': if( dos_mode != 2 && dos_mode != 7 )
+ curpage->std_col = ((curpage->std_col & 0xF0)
+ |(args[0]&0xF));
+ break;
+ case 'G': if( dos_mode != 2 && dos_mode != 7 )
+ curpage->std_col = ((curpage->std_col & 0x0F)
+ |((args[0]&0xF)<<4));
+ break;
+ case 'H': if( dos_mode != 2 && dos_mode != 7 )
+ curpage->rev_col = ((curpage->rev_col & 0xF0)
+ |(args[0]&0xF));
+ break;
+ case 'I': if( dos_mode != 2 && dos_mode != 7 )
+ curpage->rev_col = ((curpage->rev_col & 0x0F)
+ |((args[0]&0xF)<<4));
+ break;
+ case 'J': if( dos_mode != 2 && dos_mode != 7 )
+ curpage->gr_col = ((curpage->gr_col & 0xF0)
+ |(args[0]&0xF));
+ break;
+ case 'K': if( dos_mode != 2 && dos_mode != 7 )
+ curpage->gr_col = ((curpage->gr_col & 0x0F)
+ |((args[0]&0xF)<<4));
+ break;
+ }
+ break;
+
+ case '?': if( cmd == 'l' || cmd == 'h' )
+ {
+ int flg = (cmd == 'h');
+ switch(args[0])
+ {
+ case 7: curpage->am = flg; break;
+ }
+ }
+ break;
+#endif
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, scroll a set of lines on the cur screen.
+ */
+void
+scroll(from, to, lines)
+int from, to, lines;
+{
+ int win, tomove, toclr, dir, line, c;
+ int * tmp;
+
+ if( curpage->line == scr_len) curpage->line--;
+ if( lines <= 0 ) lines = 1;
+
+ dir = 1;
+ if( from > to ) { dir = from ; from = to ; to = dir ; dir = -1 ;}
+ win = to-from+1;
+ if( lines > win ) lines = win;
+ tomove = win - lines;
+ toclr = lines;
+
+ if( dir == 1 )
+ {
+ for(line=from; tomove>0; tomove--, line++)
+ {
+ tmp = curpage->lines[line];
+ curpage->lines[line] = curpage->lines[line+lines];
+ curpage->lines[line+lines] = tmp;
+ curpage->dirty[line] = 1;
+ curpage->dirty[line+lines] = 1;
+ }
+ for(line=to; toclr>0; toclr--, line--)
+ {
+ clrline(line);
+ }
+ }
+ else
+ {
+ for(line=to; tomove>0; tomove--, line--)
+ {
+ tmp = curpage->lines[line];
+ curpage->lines[line] = curpage->lines[line-lines];
+ curpage->lines[line-lines] = tmp;
+ curpage->dirty[line] = 1;
+ curpage->dirty[line+lines] = 1;
+ }
+ for(line=from; toclr>0; toclr--, line++)
+ {
+ clrline(line);
+ }
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, clear one line.
+ */
+void
+clrline(to)
+int to;
+{
+ int * toptr = curpage->lines[to];
+ int chars = line_len;
+ int pattern = ' ' + (curpage->clr_col << 8 );
+
+ curpage->dirty[to] = 1;
+
+ do
+ {
+ *toptr++ = pattern;
+ chars--;
+ }
+ while( chars );
+}
+
+/***************************************************************************
+ * Hardware screen, clear one page, reset dynamic values.
+ */
+int
+reset_page()
+{
+static int *sys_page = 0, **sys_lines, *sys_dirty;
+ int i;
+
+ if( sys_page == 0 )
+ {
+ sys_page = (int*) malloc(scr_len*line_len*2);
+ sys_lines = (int**) malloc(scr_len*sizeof(int*));
+ sys_dirty = (int*) malloc(scr_len*sizeof(int));
+ if( sys_page == 0 || sys_lines == 0 || sys_dirty == 0 )
+ return -1;
+ }
+
+ if( !curpage->reset_done )
+ {
+ curpage->charflip = 0;
+ curpage->chartran = 0;
+ curpage->attr = 0x07;
+ curpage->std_col = 0x07;
+ curpage->rev_col = 0x70;
+ curpage->gr_col = 0x07;
+ curpage->clr_col = 0x07;
+ curpage->line = 0;
+ curpage->col = 0;
+ curpage->dirtypg = 1;
+
+#ifdef AT_BIOS_KEY
+ curpage->key_mode = 0;
+#endif
+ curpage->am = 1;
+ curpage->honour_attr = 1;
+
+#ifdef LINUX_DEFAULTS
+ curpage->honour_attr = 0;
+ curpage->chartran = 1;
+#endif
+ curpage->reset_done = 1;
+ }
+
+#if MAXPAGE != 1
+ if( pages[phy_scr.this_page].page == 0
+ || pages[phy_scr.this_page].lines == 0
+ || pages[phy_scr.this_page].dirty == 0 )
+ {
+ pages[phy_scr.this_page].page = (int*) malloc(scr_len*line_len*2);
+ pages[phy_scr.this_page].lines = (int**) malloc(scr_len*sizeof(int*));
+ pages[phy_scr.this_page].dirty = (int*) malloc(scr_len*sizeof(int));
+ }
+#endif
+
+ /* Out of memory, use the default page */
+ if( pages[phy_scr.this_page].page == 0
+ || pages[phy_scr.this_page].lines == 0
+ || pages[phy_scr.this_page].dirty == 0 )
+ {
+ if(pages[phy_scr.this_page].page ) free(pages[phy_scr.this_page].page);
+ if(pages[phy_scr.this_page].lines) free(pages[phy_scr.this_page].lines);
+ if(pages[phy_scr.this_page].dirty) free(pages[phy_scr.this_page].dirty);
+
+ for(i=0; i<MAXPAGE; i++) if( pages[phy_scr.this_page].page == sys_page )
+ {
+ pages[i].page = 0;
+ pages[i].lines = 0;
+ pages[i].dirty = 0;
+ }
+
+ pages[phy_scr.this_page].page = sys_page;
+ pages[phy_scr.this_page].lines = sys_lines;
+ pages[phy_scr.this_page].dirty = sys_dirty;
+ }
+
+ for(i=0; i<scr_len; i++)
+ pages[phy_scr.this_page].lines[i]
+ = pages[phy_scr.this_page].page+line_len*i;
+
+ scroll( scr_len-1, 0, scr_len);
+
+ return 0;
+}
+
+/***************************************************************************
+ * Hardware screen, clear to end of line
+ */
+void
+clr_eol()
+{
+ int pattern = ' ' +(curpage->clr_col << 8 );
+ int * toptr = curpage->lines[curpage->line]+curpage->col;
+ int x = curpage->col;
+
+ curpage->dirty[curpage->line] = 1;
+ while( x < line_len )
+ {
+ *toptr++ = pattern;
+ x++;
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, clear to start of line
+ */
+void
+clr_sol()
+{
+ int pattern = ' ' +(curpage->clr_col << 8 );
+ int * toptr = curpage->lines[curpage->line]+curpage->col;
+ int x = curpage->col;
+
+ curpage->dirty[curpage->line] = 1;
+ while( x >= 0 )
+ {
+ *toptr-- = pattern;
+ x--;
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, delete some characters.
+ */
+void
+delch(chars)
+int chars;
+{
+ int pattern = ' ' +(curpage->clr_col << 8 );
+ int * toptr = curpage->lines[curpage->line]+curpage->col;
+ int x = curpage->col;
+ int last;
+
+ curpage->dirty[curpage->line] = 1;
+ if( chars <=0 ) chars = 1;
+ last = line_len-chars;
+
+ while( x < last )
+ {
+ *toptr = toptr[chars];
+ toptr++; x++;
+ }
+
+ while( x < line_len )
+ {
+ *toptr++ = pattern;
+ x++;
+ }
+}
+
+#ifdef SCO_ANSI
+/***************************************************************************
+ * Hardware screen, insert some characters.
+ */
+void
+inch(chars)
+int chars;
+{
+ int pattern = ' ' +(curpage->attr << 8 );
+ int * toptr = curpage->lines[curpage->line]+line_len-1;
+ int x = line_len-1;
+ int last;
+
+ curpage->dirty[curpage->line] = 1;
+ if( chars <= 0 ) chars = 1;
+
+ last = curpage->col+chars;
+ chars = -chars;
+
+ while( x >= last )
+ {
+ *toptr = toptr[chars];
+ toptr--; x--;
+ }
+
+ while( x >= curpage->col )
+ {
+ *toptr-- = pattern;
+ x--;
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, clear some characters.
+ */
+void
+zapch(chars)
+int chars;
+{
+ int pattern = ' ' +(curpage->clr_col << 8 );
+ int * toptr = curpage->lines[curpage->line]+curpage->col;
+ int x = curpage->col;
+ int last;
+
+ curpage->dirty[curpage->line] = 1;
+ if( chars <= 0 ) chars = 1;
+
+ last = curpage->col+chars;
+ if( last > line_len ) last = line_len;
+
+ while( x < last )
+ {
+ *toptr++ = pattern;
+ x++;
+ }
+}
+#endif
+
+/***************************************************************************
+ * Hardware screen, init video, detect physical screen size and location
+ * if it's in a graphic mode complain.
+ */
+void
+init_vid()
+{
+ union REGS ioregs;
+ int phy_mode=0;
+ char *p;
+
+ phy_scr.scrptr = (int far *) 0xB0000000;
+ phy_scr.dumb = 0;
+ phy_scr.line = -1;
+ phy_scr.col = -1;
+
+ ioregs.x.ax = 0x0500;
+ intvid(ioregs);
+
+ ioregs.h.ah = 15;
+ intvid(ioregs);
+ dos_mode = ioregs.h.al;
+ line_len = ioregs.h.ah;
+ page_no = ioregs.h.bh;
+
+ ioregs.h.ah = 3;
+ ioregs.h.bh = page_no;
+ intvid(ioregs);
+ dos_cur = ioregs.x.cx;
+ dos_line = ioregs.h.dh;
+ dos_col = ioregs.h.dl;
+
+ ioregs.x.ax = 0x1130; /* EGA bios info */
+ ioregs.x.dx = 0;
+ ioregs.h.bh = 0;
+ intvid(ioregs);
+ if( ioregs.x.dx )
+ {
+ is_ega_plus = 1;
+ scr_len = ioregs.x.dx+1;
+
+ if( ioregs.x.cx < 13 )
+ dos_cur = 0x0405;
+ else if( dos_mode == 7 )
+ dos_cur = 0x0C0D;
+ else
+ dos_cur = 0x0607;
+ }
+ else
+ {
+ is_ega_plus = 0;
+ scr_len = 25;
+ }
+
+ if( dos_mode == 7 )
+ phy_mode=1;
+ else
+ if(dos_mode == 2 || dos_mode == 3)
+ {
+ phy_scr.scrptr = (int far * ) 0xB8000000;
+ phy_mode=1;
+ }
+ else if( dos_mode > 0x13 )
+ phy_mode = test_svga_mode();
+
+ if( line_len < 80 )
+ {
+ printf("Screen needs to be at least 80 cols\r\n");
+ exit(0);
+ }
+ if(phy_mode==0) { printf("Unusable display mode\n"); exit(1); }
+
+ phy_scr.this_page = 0;
+ if( reset_page() < 0 )
+ {
+ printf("Memory failure, cannot allocate screen memory\n");
+ exit(1);
+ }
+
+ putscrn('\r');
+ putscrn('\n');
+ set_curtype(-1,0,0);
+ set_blink(1);
+}
+
+/***************************************************************************
+ * Hardware screen, test for an svga text mode.
+ */
+int
+test_svga_mode()
+{
+ union REGS ioregs;
+ int ch;
+
+ phy_scr.scrptr = (int far * ) 0xB8000000;
+
+ ioregs.h.ah = 8;
+ ioregs.h.bh = page_no;
+ intvid(ioregs);
+
+ ch = phy_scr.scrptr[dos_line*line_len+dos_col];
+ if( ch != ioregs.x.ax ) return 0;
+ phy_scr.scrptr[dos_line*line_len+dos_col] = ~ch;
+
+ ioregs.h.ah = 8;
+ ioregs.h.bh = page_no;
+ intvid(ioregs);
+
+ phy_scr.scrptr[dos_line*line_len+dos_col] = ch;
+ if( ( ~ch ) != ioregs.x.ax ) return 0;
+ return 1;
+}
+
+/***************************************************************************
+ * Hardware screen, reset the physical screen back to normal.
+ */
+void end_vid()
+{
+ move_cur(scr_len-1, 0);
+ set_blink(1);
+ set_curtype(-1,0,0);
+}
+
+/***************************************************************************
+ * Hardware screen, set the screen blink mode (blink or bg bold).
+ */
+void
+set_blink(flg)
+int flg;
+{
+ union REGS regs;
+static int last = -1;
+static int first = 1;
+
+/* This takes far too long (~ 8ms ) on some bioses.
+ * It apparently waits for a screen retrace and even then it isn't reliable.
+ * Will have to go directly to the HW only problem is how to do it
+ */
+
+ if( !is_ega_plus ) return;
+
+ flg = (flg != 0);
+ if( flg == last ) return;
+
+ regs.h.ah = 0x10;
+ regs.h.al = 0x03;
+ regs.h.bl = last = flg;
+
+ int86(0x10, &regs, &regs);
+
+ if( first && flg == 0 ) /* Workaround on some EGA's */
+ {
+ regs.h.ah = 0x06;
+ regs.h.al = 0x00;
+ regs.h.bh = 0x00;
+ regs.h.ch = 1;
+ regs.h.cl = 1;
+ regs.h.dh = 1;
+ regs.h.dl = 1;
+ int86(0x10, &regs, &regs);
+ curpage->dirty[1] = 1;
+ first = 0;
+ }
+}
+
+/***************************************************************************
+ * Hardware screen, set the physical cursor position.
+ */
+void
+move_cur(row, col)
+int row, col;
+{
+ union REGS ioregs;
+ ioregs.h.ah = 2;
+ ioregs.h.bh = page_no;
+ ioregs.h.dh = row;
+ ioregs.h.dl = col;
+ intvid(ioregs);
+}
+
+/***************************************************************************
+ * Hardware screen, set the physical cursor type.
+ */
+void
+set_curtype(a,top,bot)
+int a, top, bot;
+{
+ union REGS ioregs;
+ ioregs.h.ah = 1;
+ ioregs.x.cx = dos_cur;
+ if( a == 0 ) ioregs.h.ch = 0x10;
+ if( a == 1 ) ioregs.h.ch = 0;
+ if( a == 2 ) { ioregs.h.ch = top; ioregs.h.cl = bot; }
+ intvid(ioregs);
+}
+
+#endif
+
+#ifdef SAVEBLOCK
+/***************************************************************************
+ * Routines to save a chunk of data for a screen macro.
+ */
+
+void
+read_block(blk)
+int blk;
+{
+ char * p;
+ if( blk < 0 || blk > max_blk ) return;
+
+ p = blocks[blk];
+ if( p ) while( *p ) putscrn(*p++ & 0xFF);
+}
+
+void
+save_block(blk)
+int blk;
+{
+ if( blk < 0 || blk > max_blk ) return;
+ if( save_flag == 0 ) return;
+ *save_ptr++ = '\0';
+ if( blocks[blk] ) free(blocks[blk]);
+ blocks[blk] = malloc(save_ptr-save_buf);
+ if( blocks[blk] )
+ strcpy(blocks[blk], save_buf);
+}
+
+#endif
+
+#ifndef RS8250
+/***************************************************************************
+ * BIOS serial routines, also fossil driver compatible.
+ */
+
+int port_no;
+
+void
+setup(port, flags)
+int port, flags;
+{
+ int c;
+ port_no = port;
+
+ iregs.h.ah = FOSINIT;
+ iregs.x.dx = port_no;
+ iregs.x.bx = 0;
+ int86(RS232, &iregs, &oregs);
+ if( oregs.x.ax == 0x1954 )
+ {
+ if( oregs.h.bh >= 4 )
+ {
+ isfossil = oregs.h.bh;
+ fossilfunc = oregs.h.bl;
+ }
+ }
+
+ iregs.h.ah = INITRS;
+ iregs.x.dx = port_no;
+ iregs.h.al = flags;
+
+ int86(RS232, &iregs, &oregs);
+}
+
+void
+clearup()
+{
+}
+
+/***************************************************************************
+ * BIOS serial routines, transmit character
+ */
+void
+do_xmit()
+{
+ int ch;
+ ch = *xmit_get++;
+ if( xmit_get == xmit_put ) xmit_get = xmit_put = xmit_buf;
+
+ iregs.h.ah = WRITECH;
+ iregs.x.dx = port_no;
+ iregs.h.al = ch;
+ int86(RS232, &iregs, &oregs);
+
+ if( oregs.h.ah & 0x80 )
+ printf("Write Failed (0x%x)\r\n", oregs.h.ah);
+}
+
+/***************************************************************************
+ * BIOS serial routines, receive character
+ *
+ * Note the _long_ loop for successful collection of bytes so this can
+ * actually work moderatly reliably upto about 9600 bps even with a
+ * bios that doesn't use interrupts.
+ */
+void
+serial()
+{
+ int c;
+ int cnt = 2048; /* Lots but eventually will break */
+
+ do_xmit();
+
+ while((c=chrdy()) >=0)
+ {
+#ifdef PRINTER
+ if( in_transprt )
+ putprnt(c);
+ else
+#endif
+ putscrn(c);
+ if( cnt-- < 0 ) break;
+ }
+#ifdef MEM_SCR
+ update_page();
+#endif
+}
+
+/***************************************************************************
+ * BIOS serial routines, get character from bios is ready.
+ */
+int
+chrdy()
+{
+ iregs.h.ah = STATUS;
+ iregs.x.dx = port_no;
+ int86(RS232, &iregs, &oregs);
+
+ if( oregs.x.ax & DTARDY )
+ {
+ iregs.h.ah = READCH;
+ iregs.x.dx = port_no;
+ int86(RS232, &iregs, &oregs);
+
+ if( oregs.h.ah & 0x80)
+ {
+ message("Read Failed 0x%2x", oregs.h.ah);
+ return -1;
+ }
+ else
+ return oregs.h.al & mask;
+ }
+ return -1;
+}
+#endif
+
+/****************************************************************************/
+
+#ifdef RS8250
+/***************************************************************************
+ * Hardware serial routines.
+ */
+
+int com_phy[] = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
+int com_irq[] = { 4, 3, 4, 3 };
+
+#define IRQ_MASK /* 0x88 */ 0x00
+
+int save_bitflgs;
+int port_no;
+int port_addr;
+int port_int;
+int rtsflag = 2;
+
+/***************************************************************************
+ * Hardware serial routines, setup port and identify fossil port.
+ */
+void
+setup(port, flags)
+int port, flags;
+{
+ long i = -1;
+ port_no = port;
+
+ iregs.h.ah = FOSINIT;
+ iregs.x.dx = port_no;
+ iregs.x.bx = 0;
+ int86(RS232, &iregs, &oregs);
+ if( oregs.x.ax == 0x1954 )
+ {
+ if( oregs.h.bh >= 4 )
+ {
+ isfossil = oregs.h.bh;
+ fossilfunc = oregs.h.bl;
+ iregs.h.ah = 0xE0;
+ iregs.h.al = 6;
+ iregs.x.bx = 0;
+ int86(RS232, &iregs, &oregs);
+ if( oregs.x.bx == 0x4d58 )
+ {
+ mnp_fossil = 1;
+ }
+ }
+ }
+
+ if( isfossil == 0 )
+ {
+ port_addr = com_phy[port];
+ port_int = 8 + com_irq[port];
+
+ save_bitflgs = inp(port_addr+4);
+
+ if(flags > 255)
+ {
+ i = speeds[flags>>5];
+ flags &= 0x1F;
+ flags |= 0xE0;
+ }
+ }
+ /* else possible message about speed problem */
+
+ iregs.h.ah = INITRS;
+ iregs.x.dx = port_no;
+ iregs.h.al = flags;
+
+ int86(RS232, &iregs, &oregs);
+
+ if( isfossil == 0 )
+ {
+ if( i > 0 )
+ {
+ long brd = 115200L / i;
+ outp(port_addr+3, inp(port_addr+3) | 0x80);
+ outp(port_addr+0, brd & 0xFF);
+ outp(port_addr+1, (brd >> 8) & 0xFF);
+ outp(port_addr+3, inp(port_addr+3) & 0x7F);
+ }
+
+ outp(port_addr+2, 0x47); /* 16550A's FIFO cleared & at 4 char timeout */
+ setints();
+ outp(port_addr+4, inp(port_addr+4) | 0xB );
+ }
+}
+
+/***************************************************************************
+ * Hardware serial routines, reset hardware.
+ */
+void
+clearup()
+{
+ if( isfossil == 0 )
+ {
+ outp(port_addr+4, save_bitflgs);
+ clrints();
+ }
+}
+
+/***************************************************************************
+ * Hardware serial routines, get character from buffer.
+ */
+int
+get_c()
+{
+ int c;
+ if( isfossil && putptr == empty)
+ chfetch();
+
+ if(putptr == empty )
+ c = -1;
+ else
+ {
+ _disable();
+ if(getptr >= full) getptr = empty;
+ c = *getptr++;
+ nsize--;
+ if( nsize == 0 )
+ getptr = putptr = empty;
+ _enable();
+ c &= mask;
+ }
+
+ if( isfossil == 0 )
+ {
+ if( rtsflag )
+ {
+ /* if( nsize>sizeof(empty)/2) rtsflow(1) */ ;
+ }
+ else
+ {
+ if( nsize<sizeof(empty)/4) rtsflow(0);
+ }
+ }
+
+ return c;
+}
+
+/***************************************************************************
+ * Hardware serial routines, get characters from FOSSIL driver.
+ */
+void
+chfetch()
+{
+static struct SREGS sregs;
+
+ if( fossilfunc >= 0x18 )
+ {
+ iregs.h.ah = 0x18;
+ iregs.x.cx = sizeof(empty);
+ iregs.x.di = (unsigned) empty;
+ iregs.x.dx = port_no;
+ segread(&sregs);
+ sregs.es = sregs.ds;
+ int86x(RS232, &iregs, &oregs, &sregs);
+ putptr = empty + oregs.x.ax;
+ nsize = oregs.x.ax;
+ return;
+ }
+
+ iregs.h.ah = STATUS;
+ iregs.x.dx = port_no;
+ int86(RS232, &iregs, &oregs);
+
+ if( oregs.x.ax & DTARDY )
+ {
+ iregs.h.ah = READCH;
+ iregs.x.dx = port_no;
+ int86(RS232, &iregs, &oregs);
+
+ if( oregs.h.ah & 0x80)
+ message("Read Failed 0x%2x", oregs.h.ah);
+ else
+ {
+ *putptr++ = oregs.h.al & mask;
+ nsize++;
+ }
+ }
+}
+
+/***************************************************************************
+ * Hardware serial routines, send characters to port.
+ */
+void
+do_xmit()
+{
+ int cnt;
+ int ch;
+ if( xmit_put == xmit_buf ) return;
+
+ if( isfossil )
+ {
+ ch = *xmit_get++;
+ if( xmit_get == xmit_put ) xmit_get = xmit_put = xmit_buf;
+
+ iregs.h.ah = WRITECH;
+ iregs.x.dx = port_no;
+ iregs.h.al = ch;
+ int86(RS232, &iregs, &oregs);
+
+ if( oregs.h.ah & 0x80 )
+ message("Write Failed (0x%x)\r\n", oregs.h.ah);
+ }
+ else
+ {
+ if( !(inp(port_addr+5) & 0x20) ) return;
+
+ ch = *xmit_get++;
+ if( xmit_get == xmit_put ) xmit_get = xmit_put = xmit_buf;
+
+ outp(port_addr+0, ch);
+ }
+}
+
+/***************************************************************************
+ * Hardware serial routines, characters from port to screen.
+ */
+void
+serial()
+{
+ int c;
+
+ do_xmit();
+
+ if( (c= get_c()) >= 0 )
+ {
+#ifdef PRINTER
+ if( in_transprt )
+ putprnt(c);
+ else
+#endif
+ putscrn(c);
+ }
+#ifdef MEM_SCR
+ else
+ update_page();
+#endif
+}
+
+/***************************************************************************
+ * Hardware serial routines, interrupt handling.
+ */
+void ( interrupt far * int_rs_orig) _((void));
+
+void interrupt far int_rs _((void));
+
+void
+setints()
+{
+ int c;
+ int c1;
+
+ int_rs_orig = _dos_getvect(port_int);
+
+ _dos_setvect(port_int, int_rs);
+
+ outp(port_addr+1, 0x01);
+ outp(port_addr+4, inp(port_addr+4)&0xF);
+
+ inp(0x21);
+ outp(0x21, IRQ_MASK);
+
+ inp(port_addr+0);
+}
+
+void
+clrints()
+{
+ int c;
+
+ _disable();
+ c = inp(port_addr+3);
+ outp(port_addr+3, c&0x7F);
+ outp(port_addr+1, 0);
+ outp(port_addr+3, c);
+ _enable();
+
+ _dos_setvect(port_int, int_rs_orig);
+}
+
+/***************************************************************************
+ * Hardware serial routines, interrupt routine.
+ *
+ * Normally this _only_ reads characters from the serial port, flow control
+ * is only asserted if the interrupts are arriving too fast for the main
+ * job to run.
+ */
+void interrupt far int_rs()
+{
+register int lsr, prt_addr = port_addr;
+
+ while( (lsr=inp(prt_addr+5)) & 0x1F )
+ {
+ if( rtsflag )
+ {
+ /* Is buffer too full ? */
+ if( nsize>sizeof(empty)/4*3 )
+ {
+ register int i;
+ rtsflag = 0;
+ i=prt_addr+4;
+ outp(i, inp(i) & ~2 );
+ }
+ }
+ else
+ if( nsize>=sizeof(empty)-2 ) /* It didn't respond to RTS! */
+ break;
+
+ {
+ register char * ptr = putptr;
+ if( lsr & 0x1A )
+ {
+ if(ptr >= full) ptr = empty;
+ if( lsr & 0x10 )
+ *ptr++ = 0x07; /* Flag break */
+ else
+ *ptr++ = '\032'; /* Flag overrun or frame error */
+ nsize++;
+ }
+ if( lsr & 0x01 )
+ {
+ if(ptr >= full) ptr = empty;
+ *ptr++ = inp(prt_addr+0);
+ nsize++;
+ }
+ putptr = ptr;
+ }
+ }
+ outp(prt_addr+1, 0x00);
+ outp(0x20, 0x20); /* Ensure late irq's retrigger */
+
+ if( nsize<sizeof(empty)-2 ) /* But only if we ain't full */
+ outp(prt_addr+1, 0x01);
+}
+
+/***************************************************************************
+ * Hardware serial routines, assert RTS/CTS flow control
+ */
+void
+rtsflow(stop)
+int stop;
+{
+ rtsflag = (stop?0:2);
+
+ if(stop)
+ outp(port_addr+4, inp(port_addr+4) & ~2 );
+ else
+ {
+ outp(port_addr+4, inp(port_addr+4) | 0xB );
+ outp(port_addr+1, 0x01);
+ }
+}
+
+#ifdef KBDRTS
+/***************************************************************************
+ * These routines force the RTS flow control on when in the keyboard
+ * interrupt; this is sometimes needed to deal with nasty TSRs and
+ * bad BIOSes.
+ */
+void
+init_kbd()
+{
+ orig_kbd_int = _dos_getvect(KBDINT);
+ _dos_setvect(KBDINT, kbd_int);
+}
+
+void interrupt far kbd_int()
+{
+register int i;
+ outp(port_addr+4, inp(port_addr+4) & ~2 );
+
+/* Flag overrides */
+#ifdef AT_BIOS_KEY
+#ifdef __BORLANDC__
+ _AH = 0x12; geninterrupt(0x16); i = _AX;
+ _CX = 0xFE00 + (i&3) + ((i&0xF00)>>6) + ((i>>9)&0x40);
+ _AH = 0x05; geninterrupt(0x16);
+#endif
+#endif
+
+ int_rs();
+ orig_kbd_int();
+ outp(port_addr+4, inp(port_addr+4) | rtsflag );
+}
+
+void
+clear_kbd()
+{
+ _dos_setvect(KBDINT, orig_kbd_int);
+}
+#endif
+#endif
+
+/***************************************************************************
+ * AVATAR -> ANSI conversion routines.
+ *
+ * Only the hardware screen version can use the avatar+ codes
+ * (except insert mode which needs large changes)
+ */
+#ifdef AVATAR
+#ifndef MEM_SCR
+
+char avbuf[270];
+int avcnt = 0;
+
+ /* @ A B C D E F G H I J K L M N */
+int avsizes[] = { 0, 3, 2, 2, 2, 2, 2, 2, 4, 2, 7, 7, 5, 6, 2 };
+int avzero [] = { 0, 3, 2, 2, 2, 2, 2, 2, 4 };
+int colconv[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+do_avatar(ch)
+{
+ char tbuf[270];
+ int i, j;
+
+ if( avcnt == 0 )
+ {
+ avbuf[0] = ch;
+ avcnt=1;
+ return;
+ }
+ else
+ {
+ avbuf[avcnt++] = ch;
+ if( avbuf[0] == '\031' )
+ {
+ if( avcnt < 3 ) return;
+ j = (avbuf[2]&0x7F);
+ avcnt = -1;
+ for(i=0; i<j; i++)
+ putscrn(avbuf[1]);
+ avcnt = 0;
+ return;
+ }
+ avbuf[1] &= 0x3F;
+ if( avbuf[1] == '\031' )
+ {
+ if( avcnt < 3 || avcnt < (avbuf[2]&0xFF)+4 )
+ return;
+ }
+ else if( avbuf[1] < 1 || avbuf[1] >= sizeof(avsizes)/sizeof(int) )
+ {
+ avcnt = -1;
+ putscrn('\026');
+ putscrn(ch);
+ avcnt = 0;
+ return;
+ }
+ else
+ if( avcnt < avsizes[avbuf[1]]) return;
+ avcnt = -1;
+ tbuf[0] = '\0';
+ switch( avbuf[1] )
+ {
+ case 1: sprintf(tbuf, "\033[0;3%d;4%dm",
+ colconv[avbuf[2]&0x7], colconv[(avbuf[2]>>4)&0x7]);
+ if( avbuf[2]&0x08 ) sprintf(tbuf+strlen(tbuf), "\033[1m");
+ break;
+ case 2: sprintf(tbuf, "\033[5m");
+ break;
+ case 3: sprintf(tbuf, "\033[A");
+ break;
+ case 4: sprintf(tbuf, "\033[B");
+ break;
+ case 5: sprintf(tbuf, "\033[D");
+ break;
+ case 6: sprintf(tbuf, "\033[C");
+ break;
+ case 7: sprintf(tbuf, "\033[K");
+ break;
+ case 8: if( avbuf[2] > 25 || avbuf[2] < 1 )
+ {
+ putscrn(avbuf[2]);
+ putscrn(avbuf[3]);
+ }
+ else if( avbuf[3] > 80 || avbuf[3] < 1 )
+ {
+ sprintf(tbuf, "\033[%dH", avbuf[2]);
+ j=strlen(tbuf);
+ tbuf[j] = avbuf[3];
+ tbuf[j+1] = '\0';
+ }
+ else
+ sprintf(tbuf, "\033[%d;%dH", avbuf[2], avbuf[3]);
+ break;
+ case 25: memcpy(tbuf, avbuf, 270);
+ j = (tbuf[tbuf[2]+3]&0xFF);
+ avcnt = 0;
+ for(;j>0; j--)
+ for(i=0; i<(tbuf[2]&0xff); i++)
+ putscrn(tbuf[i+3]);
+
+ tbuf[0] = '\0';
+ break;
+ default: sprintf(tbuf, "Unsupported avatar CTRL-V CTRL-%c ",
+ '@'+ avbuf[1] );
+ break;
+ }
+ for(i=0; tbuf[i]; i++)
+ putscrn(tbuf[i]);
+ avcnt = 0;
+ }
+}
+
+#else /* def MEM_SCR */
+
+char avbuf[270];
+int avcnt = 0;
+
+ /* @ A B C D E F G H I J K L M N */
+#ifdef AVATAR_PLUS
+int avsizes[] = { 0, 3, 2, 2, 2, 2, 2, 2, 4, 2, 7, 7, 5, 6, 2 };
+#else
+int avsizes[] = { 0, 3, 2, 2, 2, 2, 2, 2, 4 };
+#endif
+int colconv[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+do_avatar(ch)
+{
+ char tbuf[270];
+ int i, j;
+
+ if( avcnt == 0 )
+ {
+ avbuf[0] = ch;
+ avcnt=1;
+ return;
+ }
+ else
+ {
+ avbuf[avcnt++] = ch;
+ if( avbuf[0] == '\031' )
+ {
+ if( avcnt < 3 ) return;
+ j = (avbuf[2]&0x7F);
+ avcnt = -1;
+ for(i=0; i<j; i++)
+ litput(avbuf[1]);
+ avcnt = 0;
+ return;
+ }
+ avbuf[1] &= 0x3F;
+ if( avbuf[1] == '\031' )
+ {
+ if( avcnt < 3 || avcnt < (avbuf[2]&0xFF)+4 )
+ return;
+ }
+ else if( avbuf[1] < 1 || avbuf[1] >= sizeof(avsizes)/sizeof(int) )
+ {
+ avcnt = -1;
+ litput('\026');
+ litput(ch);
+ avcnt = 0;
+ return;
+ }
+ else
+ if( avcnt < avsizes[avbuf[1]]) return;
+ avcnt = -1;
+ tbuf[0] = '\0';
+ switch( avbuf[1] )
+ {
+ case 1: if( dos_mode != 2 && dos_mode != 7 )
+ curpage->attr = (avbuf[2]&0x7F);
+ else
+ curpage->attr = ((avbuf[2]&0x08)|0x07);
+ if( curpage->honour_attr )
+ curpage->clr_col = curpage->attr;
+ break;
+ case 2: curpage->attr |= 0x80;
+ if( curpage->honour_attr )
+ curpage->clr_col = curpage->attr;
+ break;
+ case 3: set_pos(curpage->line-1, curpage->col);
+ break;
+ case 4: set_pos(curpage->line+1, curpage->col);
+ break;
+ case 5: curpage->col--;
+ if( curpage->col < 0 )
+ curpage->col = 0;
+ break;
+ case 6: curpage->col++;
+ if( curpage->col >= line_len )
+ curpage->col = line_len -1;
+ break;
+ case 7: clr_eol();
+ break;
+ case 8: set_pos(avbuf[2]-1, avbuf[3]-1);
+ break;
+#ifdef AVATAR_PLUS
+/* case 9: insert mode (Gaud! this means lots of changes) */
+
+ case 10: /* scroll up */
+ scroll_up(avbuf[2], avbuf[3], avbuf[4], avbuf[5], avbuf[6]);
+ break;
+
+ case 11: /* scroll down */
+ scroll_down(avbuf[2], avbuf[3], avbuf[4], avbuf[5], avbuf[6]);
+ break;
+
+ case 12: clear_area(curpage->line, curpage->col,
+ avbuf[3], avbuf[4], avbuf[2] , ' ');
+ break;
+ case 13: clear_area(curpage->line, curpage->col,
+ avbuf[4], avbuf[5], avbuf[2], avbuf[3]);
+ break;
+
+ case 14: /* del char */
+ delch(1);
+ break;
+#endif
+ case 25: memcpy(tbuf, avbuf, 270);
+ j = (tbuf[tbuf[2]+3]&0xFF);
+ avcnt = 0;
+ for(;j>0; j--)
+ for(i=0; i<(tbuf[2]&0xff); i++)
+ putscrn(tbuf[i+3]);
+
+ tbuf[0] = '\0';
+ break;
+ default: sprintf(tbuf, "Unsupported avatar CTRL-V CTRL-%c ",
+ '@'+ avbuf[1] );
+ break;
+ }
+ for(i=0; tbuf[i]; i++)
+ putscrn(tbuf[i]);
+ avcnt = 0;
+ }
+}
+
+#ifdef AVATAR_PLUS
+clear_area(r, c, h, w, a, cc)
+int w,h;
+int r, c;
+{
+ int i, j;
+ int ch;
+ int attr;
+
+ attr = a;
+
+ ch = (cc&0xFF)+(attr<<8);
+
+ if( r >= scr_len || c >= line_len
+ || r+h < 0 || c+w < 0 || h < 0 || w < 0 ) return;
+ if( r < 0 ) { h -= r; r = 0; }
+ if( c < 0 ) { w -= c; w = 0; }
+ if( r+h > scr_len ) { h = scr_len-r; }
+ if( c+w > line_len ) { w = line_len-c; }
+
+ for(i=0; i<h; i++)
+ {
+ for(j=0; j<w; j++)
+ {
+ curpage->lines[r+i][c+j] = ch;
+ }
+ }
+ dirty_lines(r, h);
+ curpage->attr = attr;
+}
+
+scroll_up(lines, tlr, tlc, brr, brc)
+int lines, tlr, tlc, brr, brc;
+{
+ int slines;
+ int rows, cols, i, k;
+ if( tlr < 1 ) tlr = 1;
+ if( tlc < 1 ) tlc = 1;
+ if( brr > scr_len ) brr = scr_len;
+ if( brc > line_len ) brc = line_len;
+ if( tlr > brr ) return;
+ if( tlc > brc ) return;
+
+ rows = brr-tlr+1;
+ cols = brc-tlc+1;
+ tlr--; tlc--; brc--; brr--;
+
+ if( lines <= 0 || lines >= rows )
+ {
+ clear_area(tlr, tlc, rows, cols, curpage->attr, ' ');
+ return;
+ }
+ slines = rows - lines;
+ for(i=0;i < slines;i++)
+ {
+ /* copy from line tlr+i+lines to line tlr+i */
+ for(k=tlc;k<=brc;k++)
+ {
+ curpage->lines[tlr+i][k] = curpage->lines[tlr+lines+i][k];
+ }
+ }
+ for(i=slines; i<rows; i++)
+ {
+ /* zap line tlr+i */
+ for(k=tlc;k<=brc;k++)
+ {
+ curpage->lines[tlr+i][k] = (curpage->attr<<8)+' ';
+ }
+ }
+ dirty_lines(tlr, rows);
+}
+
+scroll_down(lines, tlr, tlc, brr, brc)
+int lines, tlr, tlc, brr, brc;
+{
+ int slines;
+ int rows, cols, i, k;
+ if( tlr < 1 ) tlr = 1;
+ if( tlc < 1 ) tlc = 1;
+ if( brr > scr_len ) brr = scr_len;
+ if( brc > line_len ) brc = line_len;
+ if( tlr > brr ) return;
+ if( tlc > brc ) return;
+
+ rows = brr-tlr+1;
+ cols = brc-tlc+1;
+ tlr--; tlc--; brc--; brr--;
+
+ if( lines <= 0 || lines >= rows )
+ {
+ clear_area(tlr, tlc, rows, cols, curpage->attr, ' ');
+ return;
+ }
+ slines = rows - lines;
+ for(i=rows-1;i >= lines;i--)
+ {
+ /* copy from line tlr+i to line tlr+i+lines */
+ for(k=tlc;k<=brc;k++)
+ {
+ curpage->lines[tlr+i][k] = curpage->lines[tlr+i-lines][k];
+ }
+ }
+ for(i=0; i<lines; i++)
+ {
+ /* zap line tlr+i */
+ for(k=tlc;k<=brc;k++)
+ {
+ curpage->lines[tlr+i][k] = (curpage->attr<<8)+' ';
+ }
+ }
+ dirty_lines(tlr, rows);
+}
+
+dirty_lines(top, count)
+int top, count;
+{
+ int i;
+ for(i=0; i<count; i++)
+ {
+ curpage->dirty[top+i] = 1;
+ }
+}
+#endif
+#endif
+#endif
+
+
+#ifdef AT_BIOS_KEY
+
+static int bioskeydecode[] = {
+ 0x0000, 0x3280, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136,
+ 0x3137, 0x3138, 0x3139, 0x3130, 0x312d, 0x313d, 0x3308, 0x1209,
+ 0x3171, 0x3177, 0x3165, 0x3172, 0x3174, 0x3179, 0x3175, 0x3169,
+ 0x316f, 0x3170, 0x315b, 0x315d, 0x330d, 0x0000, 0x3161, 0x3173,
+ 0x3164, 0x3166, 0x3167, 0x3168, 0x316a, 0x316b, 0x316c, 0x313b,
+ 0x0100, 0x0100, 0x0000, 0x0400, 0x317a, 0x3178, 0x3163, 0x3176,
+ 0x3162, 0x316e, 0x316d, 0x312c, 0x312e, 0x312f, 0x0000, 0x0700,
+ 0x0000, 0x3520, 0x0000, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485,
+ 0x0486, 0x0487, 0x0488, 0x0489, 0x048a, 0x0000, 0x0000, 0x0697,
+ 0x0698, 0x0699, 0x0700, 0x0694, 0x0695, 0x0696, 0x0700, 0x0691,
+ 0x0692, 0x0693, 0x0690, 0x069a, 0x1481, 0x1482, 0x1483, 0x1484,
+ 0x1485, 0x1486, 0x1487, 0x1488, 0x1489, 0x148a, 0x2481, 0x2482,
+ 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, 0x2488, 0x2489, 0x248a,
+ 0x3481, 0x3482, 0x3483, 0x3484, 0x3485, 0x3486, 0x3487, 0x3488,
+ 0x3489, 0x348a, 0x0000, 0x2694, 0x2696, 0x2691, 0x2693, 0x2697,
+ 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138,
+ 0x3139, 0x3130, 0x002d, 0x003d, 0x2699, 0x048b, 0x048c, 0x148b,
+ 0x148c, 0x248b, 0x248c, 0x348b, 0x348c, 0x2698, 0x2700, 0x2695,
+ 0x2700, 0x2692, 0x2690, 0x269a, 0x2009, 0x2700, 0x2700, 0x3697,
+ 0x3698, 0x3699, 0x0000, 0x3694, 0x3695, 0x3696, 0x0000, 0x3691,
+ 0x3692, 0x3693, 0x3690, 0x369a, 0x3700, 0x3009, 0x3700, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+int get_key()
+{
+static int last_flgs = 0;
+static int force_flgs[] = {0, 2, 4, 8};
+static int this_flags = -1;
+
+#ifdef __BORLANDC__
+static int kbd_type = -1;
+#else
+static int kbd_type = 0;
+#endif
+
+ int ch, flgs, scan, flgs2;
+ int scand;
+ int i;
+
+try_again:; /* If we get a scan generator */
+
+#ifdef __BORLANDC__
+ if( kbd_type < 0 )
+ {
+ kbd_type = 0;
+
+ for(i=0; i<16;i++)
+ {
+ _AH = 0x01; geninterrupt(0x16); if((_FLAGS&0x40)) break;
+ _AH = 0x00; geninterrupt(0x16);
+ }
+ _AH = 0x05; _CX= 0xFFFF; geninterrupt(0x16);
+ for(i=0; i<16;i++)
+ {
+ _AH = 0x11; geninterrupt(0x16); if((_FLAGS&0x40)) break;
+ _AH = 0x10; geninterrupt(0x16);
+ if( _AX == 0xFFFF )
+ {
+ kbd_type = 0x10;
+ break;
+ }
+ }
+ }
+
+ _AH = kbd_type+1; geninterrupt(0x16);
+ i = (_FLAGS&0x40);
+
+ _AH = kbd_type+2; geninterrupt(0x16); flgs = _AX;
+ if( !kbd_type ) flgs &= 0xFF;
+
+#else
+ i = !_bios_keybrd(_KEYBRD_READY);
+
+ flgs = _bios_keybrd(_KEYBRD_SHIFTSTATUS);
+#endif
+ if(!(flgs&0x8)) flgs &= ~0x0A00;
+
+ if(i)
+ {
+ if( flgs != last_flgs )
+ {
+ ch = 0;
+ last_flgs = flgs;
+ i=0;
+ if( (flgs & 0x500) == 0x500 ) ch |= KEY_CTRL;
+ if( (flgs & 0xA00) == 0xA00 ) ch |= KEY_ALT|KEY_ALTGR;
+ if(!i)
+ {
+ if( (flgs & 0x001) ) i++;
+ if( (flgs & 0x002) ) i++;
+ if( (flgs & 0x004) ) i++;
+ if( (flgs & 0x008) ) i++;
+ }
+
+ if( i>1 )
+ {
+ if( flgs & 0x4 ) ch |= KEY_CTRL;
+ if( flgs & 0x3 ) ch |= KEY_SHIFT;
+ if( (flgs & 0x0A00) )
+ ch |= ((flgs&0x0200)?KEY_ALT:0) + ((flgs&0x0800)?KEY_ALTGR:0) ;
+ else
+ ch |= ((flgs&0x08)?KEY_ALT:0);
+ }
+
+ if( ch )
+ {
+#ifdef DEBUG
+ cprintf( "BIOS ----, FLGS: %04x:", flgs);
+#endif
+ return (ch + KEY_SPECIAL);
+ }
+ }
+ return -1;
+ }
+ else
+ {
+#ifdef __BORLANDC__
+ _AH = kbd_type; geninterrupt(0x16);
+ ch = (unsigned) _AX;
+#else
+ ch = _bios_keybrd(_KEYBRD_READ);
+#endif
+ }
+
+ if( this_flags != -1 )
+ {
+ flgs = ( flgs & 0x70F0 )
+ + ( this_flags & 3 )
+ + ((this_flags & 0x3C) << 6 )
+ + ((this_flags & 0x40) << 9 );
+ if( flgs & 0x500 ) flgs |= 0x04;
+ if( flgs & 0xA00 ) flgs |= 0x08;
+ this_flags = -1;
+ }
+
+ if( ( ch & 0xFF00 ) == 0xFE00 ) { this_flags = ch; goto try_again; }
+
+ last_flgs = flgs;
+#ifdef DEBUG
+ cprintf( "BIOS %04x, FLGS: %04x:", ch, flgs);
+#endif
+
+ flgs &= 0x0A0F;
+ if( ch == 0 ) return KEY_OTHER + 0x03;
+
+ scan = ((ch>>8)&0xFF);
+ ch &= 0xFF;
+
+ if( scan == 0 ) return ch + KEY_DIRECT;
+ if( scan == 0xE0 ) scan = 0xA4 + 2*(ch < ' ');
+
+ flgs2 = 0;
+ if( ch == 0xE0 ) { flgs2 |= KEY_PAD; ch = 0; }
+
+ /* Check for forced flags */
+ if( ch == 0 && (flgs&0xF) == 0 )
+ flgs |= force_flgs[(bioskeydecode[scan]>>12)&3];
+
+ if( flgs & 0x4 ) flgs2 |= KEY_CTRL;
+ if( flgs & 0x3 ) flgs2 |= KEY_SHIFT;
+
+ if( (flgs & 0x0A00) )
+ flgs2 |= ((flgs&0x0200)?KEY_ALT:0) + ((flgs&0x0800)?KEY_ALTGR:0) ;
+ else
+ flgs2 |= ((flgs&0x08)?KEY_ALT:0);
+
+ if( ch ) switch(flgs2)
+ {
+ case 0: case KEY_CTRL: case KEY_SHIFT:
+ switch((bioskeydecode[scan]>>8)&7)
+ {
+ case 1:
+ return ch;
+ case 2:
+ if( flgs2 == 0 ) return ch + KEY_OTHER;
+ break;
+ case 3:
+ if( (flgs2 & ~KEY_CTRL) == 0 ) return ch + KEY_OTHER;
+ break;
+ case 4:
+ if( (flgs2 & ~KEY_SHIFT) == 0 ) return ch;
+ if( flgs2 == KEY_CTRL ) return (ch&0x1F);
+ break;
+ case 5:
+ if( flgs2 == 0 ) return ch;
+ break;
+ case 6:
+ if( flgs2 == 0 ) return ch + KEY_PAD;
+ break;
+ case 7: return ch + KEY_PAD;
+ }
+ }
+
+ flgs2 |= KEY_SPECIAL;
+
+ if( ((bioskeydecode[scan]>>8)&6) == 6 && (flgs&0x08) == 0 && kbd_type )
+ flgs2 ^= KEY_PAD;
+
+ if( ((bioskeydecode[scan]>>8)&7) == 4 && ch )
+ ;
+ else if(bioskeydecode[scan]&0xFF)
+ return flgs2 + (bioskeydecode[scan]&0xFF);
+
+ return flgs2 + KEY_DIRECT + scan;
+}
+
+unsigned char scan_desc[] = {
+ 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 0,
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 10, 'C', 'a', 's',
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 0, 0, 'S', 0, 'z', 'x', 'c', 'v',
+ 'b', 'n', 'm', ',', '.', '/', 'T', 0, 'A', ' ', 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 'E', 'F', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+char hextbl[] = "0123456789abcdef";
+
+/* Write scancodes, in this mode you really need a compatible program on
+ * the host, but you can just about type 'reset<cr>' and have it work
+ */
+void
+write_scan(scan)
+int scan;
+{
+static int lastscan = -1;
+ int by;
+
+ scan &= 0xFF;
+
+ if( scan == lastscan+0x80 )
+ { xmit('~'); xmit('\b'); }
+ else if( by = scan_desc[scan] )
+ xmit(by);
+ else if( by = scan_desc[scan&0x7F] )
+ { xmit('!'); xmit(by); }
+ else
+ { xmit('~'); xmit(hextbl[scan>>4]); xmit(hextbl[scan&0xF]); }
+ lastscan = scan;
+}
+
+/*
+ * This keyboard gives a pattern of control sequences that makes just about
+ * every keypress distinct. It does need a compatible host program but its
+ * useable as a generic terminal type unlike the scancodes.
+ */
+void
+write_dosemu(ch)
+int ch;
+{
+#define CT_KEY 0x1E
+ int by = (ch & 0xFF);
+
+ /* First we swap round ^M and Return, likewise BS, Tab and Esc */
+ if( ( ch & 0xFF00 ) == KEY_OTHER || ( ch & 0xFF00 ) == 0 )
+ {
+ /* Make it so we can detect the 'other' keys */
+ if( strchr("\b\t\r\n\033\003\177", by) )
+ {
+ if( ch & KEY_OTHER )
+ ch ^= KEY_OTHER;
+ else
+ by = ((ch = KEY_SPECIAL+KEY_CTRL+tolower(by+'@')) & 0xFF);
+ }
+ }
+
+ if( ch & 0xFF00 )
+ {
+ if( ch & KEY_SPECIAL )
+ {
+ if( by == 0 ) return;
+
+ if( ch & KEY_ALT ) { xmit(CT_KEY); xmit('a'); }
+ if( ch & KEY_CTRL ) { xmit(CT_KEY); xmit('c'); }
+ if( ch & KEY_SHIFT ) { xmit(CT_KEY); xmit('s'); }
+ if( ch & KEY_ALTGR ) { xmit(CT_KEY); xmit('g'); }
+ if( ch & KEY_PAD ) { xmit(CT_KEY); xmit('k'); }
+ /* if( ch & KEY_OTHER ) { xmit(CT_KEY); xmit('o'); } */
+
+ if( ch & KEY_DIRECT )
+ {
+ xmit(CT_KEY); xmit('~');
+ xmit(hextbl[by>>4]); xmit(hextbl[by&0xF]);
+ }
+ else if((by&0xF0)==0x80 )
+ {
+static char fkeys[] = "01234567890-=..";
+ if( by == 0x80 )
+ {
+ xmit('\033');
+ xmit('\033');
+ }
+ else
+ {
+ xmit(CT_KEY);
+ xmit(fkeys[by&0xF]);
+ }
+ }
+ else if((by&0xF0)==0x90 )
+ {
+ xmit(CT_KEY);
+ xmit('K');
+ xmit(hextbl[by&0xF]);
+ }
+ else
+ xmit(by);
+ }
+ else
+ {
+ if( ch & KEY_PAD ) { xmit(CT_KEY); xmit('k'); }
+ if( ch & KEY_OTHER ) { xmit(CT_KEY); xmit('o'); }
+ if( ch & KEY_DIRECT ) { xmit(CT_KEY); xmit('z'); }
+ xmit(by);
+ }
+ }
+ else if( by == CT_KEY )
+ {
+ xmit(CT_KEY); xmit('c'); xmit(tolower(CT_KEY+'@'));
+ }
+ else
+ {
+ xmit(by);
+ if( by == '\033' )
+ xmit(by);
+ }
+}
+
+/*
+ * This key mapping is designed for easy use with terminfo nevertheless
+ * it has potentially 96 function key + 104 alt/ctrl/shift&letter codes.
+ *
+#ifdef SCO_KEYMAP
+ * This generates key sequences compatible with the SCO-Xenix console.
+ * In addition many extra key combinations generate distinct codes.
+ * But there are normally several ways of generating each standard key.
+#endif
+ */
+void
+write_unix(ch)
+int ch;
+{
+ int by;
+#ifdef SCO_KEYMAP
+ /* 012345678901234567890123456 789012 */
+static char normal[] = " MNOPQRSTUVWX LFBGDECHAI\177 ";
+static char shift [] = " YZabcdefghij 0123456789\177 ";
+static char ctrl [] = " klmnopqrstuv \177 ";
+static char ctrshf[] = " wxyz@[\\]^_`{ \177 ";
+#endif
+
+ /* This seems to be a pain if it stays */
+ if( ch == KEY_SPECIAL+KEY_SHIFT+'\r' ) ch = '\r';
+ if( ch == KEY_SPECIAL+KEY_SHIFT+' ' ) ch = ' ';
+
+#ifdef SCO_KEYMAP
+ if( ch & KEY_SPECIAL )
+ {
+ if( ch & (KEY_ALT|KEY_ALTGR|KEY_DIRECT) )
+ write_dosemu(ch);
+ else if( (ch & 0xE0) != 0x80 )
+ write_dosemu(ch);
+ else
+ {
+ char * keys;
+ if( ch&KEY_SHIFT )
+ {
+ if( ch&KEY_CTRL ) keys = ctrshf; else keys = shift;
+ }
+ else
+ {
+ if( ch&KEY_CTRL ) keys = ctrl; else keys = normal;
+ }
+ by = keys[ch&0x1F];
+ if( by == ' ' ) write_dosemu(ch);
+ else if( by == '\177' || by >= '0' && by <= '9' )
+ xmit(by);
+ else
+ {
+ xmit('\033');
+ xmit('[');
+ xmit(by);
+ }
+ }
+ }
+#else
+ if( ch & KEY_SPECIAL )
+ write_dosemu(ch);
+#endif
+ else
+ xmit(ch&0xFF);
+}
+
+#else !AT_BIOS_KEY
+/***************************************************************************
+ * Get a key from the keyboard (-1 if none available)
+ * Simple XT-BIOS version
+ */
+
+int get_key()
+{
+#ifdef KEY_COMPAT
+ /* This is called so often that windows thinks we're idle; well we
+ * are _but_ windows also seems to stop us.
+ */
+
+ if( _bios_keybrd(_KEYBRD_READY) == 0 ) return -1;
+ return _bios_keybrd(_KEYBRD_READ);
+
+#else
+
+ /* So we have to hack it */
+
+#define bios_ram ((char far *)0x00400000L)
+ static char last_flags = 0;
+ int c;
+
+ if( bios_ram[0x1C] != bios_ram[0x1A] )
+ return _bios_keybrd(_KEYBRD_READ);
+ else
+ return -1;
+
+#endif
+
+}
+
+/***************************************************************************
+ * XT-BIOS Keymap tables for SCO console.
+ */
+
+#ifdef SCO_KEYMAP
+#ifdef SCO_REMAP
+char * keytab[95];
+char keybuf[33] = "";
+int keyxlate[KEYTABSIZE] =
+ { 0073, 0074, 0075, 0076, 0077,
+ 0100, 0101, 0102, 0103, 0104, 0, 0, /* F11, F12 oops */
+ 0124, 0125, 0126, 0127, 0130,
+ 0131, 0132, 0133, 0134, 0135, 0, 0,
+ 0136, 0137, 0140, 0141, 0142,
+ 0143, 0144, 0145, 0146, 0147, 0, 0,
+ 0150, 0151, 0152, 0153, 0154,
+ 0155, 0156, 0157, 0160, 0161, 0, 0,
+ 0107, 0110, 0111, 0112, 0113,
+ 0114, 0115, 0116, 0117, 0120,
+ 0121, 0122
+ };
+#endif
+
+int kbtab[] =
+{
+/* 000 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+/* 010 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x25A,
+/* 020 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+/* 030 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+/* 040 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+/* 050 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+/* 060 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000,
+/* 070 */ 0x000, 0x000, 0x000, 0x24D, 0x24E, 0x24F, 0x250, 0x251,
+/* 100 */ 0x252, 0x253, 0x254, 0x255, 0x256, 0x000, 0x000, 0x248,
+/* 110 */ 0x241, 0x249, 0x000, 0x244, 0x000, 0x243, 0x000, 0x246,
+/* 120 */ 0x242, 0x247, 0x24C, 0x07F, 0x259, 0x25A, 0x261, 0x262,
+/* 130 */ 0x263, 0x264, 0x265, 0x266, 0x267, 0x268, 0x26B, 0x26C,
+/* 140 */ 0x26D, 0x26E, 0x26F, 0x270, 0x271, 0x272, 0x273, 0x274,
+/* 150 */ 0x277, 0x278, 0x279, 0x27A, 0x240, 0x25B, 0x25C, 0x25D,
+/* 160 */ 0x25E, 0x25F, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
+};
+
+bios_keymap(c)
+int c;
+{
+ char * kptr;
+ c >>= 8;
+
+ if(c>=0 && c<0x78 && kbtab[c])
+ {
+ switch((kbtab[c] >> 8)&0xF)
+ {
+ case 1: xmit('\033');
+ break;
+ case 2: xmit('\033');
+ xmit('[');
+ break;
+#ifdef SCO_REMAP
+ case 3: kptr = keytab[kbtab[c] & 0xFF];
+ if(kptr) while( *kptr ) xmit(*kptr++);
+ return TRUE;
+#endif
+ }
+ xmit(kbtab[c] & 0xFF);
+ return 1;
+ }
+ return 0;
+}
+
+/***************************************************************************
+ * These functions are used for defining alternate function keys.
+ */
+
+#ifdef SCO_REMAP
+add_fnchar(ch)
+int ch;
+{
+ int s = strlen(keybuf);
+ if( s == 32 ) return;
+ keybuf[s] = ch;
+ s++;
+ keybuf[s] = 0;
+}
+
+set_key(kno)
+int kno;
+{
+ if( keybuf[0] == 0 ) return message("Function key %d cleared", kno+1);
+ if( keytab[kno] != 0 )
+ {
+ free(keytab[kno]);
+ keytab[kno] = 0;
+ }
+ keytab[kno] = malloc(strlen(keybuf)+1);
+ strcpy(keytab[kno], keybuf);
+ keybuf[0] = 0;
+}
+#endif
+#endif
+#endif
diff --git a/libc/msdos/xxx/TALK.EXE b/libc/msdos/xxx/TALK.EXE
new file mode 100644
index 0000000..549c4fe
--- /dev/null
+++ b/libc/msdos/xxx/TALK.EXE
Binary files differ
diff --git a/libc/msdos/xxx/ZIP.COM b/libc/msdos/xxx/ZIP.COM
new file mode 100644
index 0000000..cd06cf9
--- /dev/null
+++ b/libc/msdos/xxx/ZIP.COM
Binary files differ
diff --git a/libc/msdos/xxx/comx.com b/libc/msdos/xxx/comx.com
new file mode 100644
index 0000000..db80d00
--- /dev/null
+++ b/libc/msdos/xxx/comx.com
Binary files differ
diff --git a/libc/msdos/xxx/cpu.com b/libc/msdos/xxx/cpu.com
new file mode 100644
index 0000000..23ab7e8
--- /dev/null
+++ b/libc/msdos/xxx/cpu.com
Binary files differ
diff --git a/libc/msdos/xxx/list.com b/libc/msdos/xxx/list.com
new file mode 100644
index 0000000..f17d5e3
--- /dev/null
+++ b/libc/msdos/xxx/list.com
Binary files differ
diff --git a/libc/msdos/xxx/mail-to-lasu.html b/libc/msdos/xxx/mail-to-lasu.html
new file mode 100644
index 0000000..2babe2d
--- /dev/null
+++ b/libc/msdos/xxx/mail-to-lasu.html
@@ -0,0 +1,105 @@
+<!-- X-URL: http://www.cs.helsinki.fi/~wirzeniu/mail-to-lasu.html -->
+<BASE HREF="http://www.cs.helsinki.fi/~wirzeniu/mail-to-lasu.html">
+
+<html> <head> <title>Sending mail to Lasu</title> </head> <body>
+
+<h1>Sending mail to Lasu</h1>
+
+<p>I get mail from a lot of people I don't know. Some of this mail is
+welcome, some is not. Unwelcome mail annoys me, because I pay for my
+Internet connection, and I don't want to pay for something I don't want.
+Even if I didn't pay, unwanted mail still wastes my time, which alone
+is bad enough.
+
+<p>
+This page explains my mail preferences. I'm grateful if you read it
+before sending me mail.
+
+<p><strong>I don't want to receive</strong>:
+
+<ul>
+<li> Advertisments I did not ask for. Making me pay for your ads is
+ rude, and possibly illegal. I react strongly to ads.
+<li> Chain letters. Most of them are illegal. All of them are a waste
+ of network resources. I react strongly to chain letters.
+<li> Mailing lists I did not subscribe to, whether they are for ads or
+ not. I react strongly to this.
+<li> Questions about Linux from strangers. I'm somewhat well
+ known in the Linux community, and I often get questions related
+ to Linux. I don't have the time to answer a lot of questions, and
+ much of the time I don't even know the answer. If you send one
+ to me, I will probably just ignore it. (This point only applies
+ to general questions; I'm happy to discuss my own activities.)
+<li> Questions on other things you think I might know, especially including
+ Procmail, unless you have reason to believe I'm the only person
+ (or one of a small group) able to answer the question.
+<li> Anything that is big (more than about 50 kB), in one or more pieces.
+ If you want me to have a big file, ask me first.
+<li> Privately mailed copies of public responses to my messages on mailing
+ lists or in newsgroups. Don't make me pay
+ for downloading duplicate copies of the same message or wasting
+ my time reading the same message twice.
+</ul>
+
+<p><strong>I welcome</strong>:
+
+<ul>
+<li> Anything from friends, relatives, and other people I personally know.
+<li> Anything I've specifically asked for, including ads or big files.
+<li> Anything concerning something I've written (programs, documents,
+ articles, letters, etc), as long as it related to that. Replying
+ to my article with an unrelated ad invites hostility on my part.
+<li> Anything related to comp.os.linux.announce, which I moderate.
+<li> Anything related to the Linux Software Map, which I maintain.
+<li> Anything concerning one of my other volunteer activities, such
+ as creating new groups in the sfnet hierarchy, or about one of the
+ associations or organizations I'm active in.
+<li> Mailing lists I've subscribed to.
+</ul>
+
+<p>If you aren't sure if I'm interested, send me one line and ask me.
+Neither of the above lists are exhaustive, and I'm sure there will be
+exceptions.
+
+<p>I used to have a mail filter that was quite aggressive and
+deleted all mail from unknown people. I've since softened
+it quite a bit: now, the filter deletes nothing, but puts
+mail from unknown people in a separate folder, which I check
+when I feel like it (not necessarily very often). The filter
+also sends back a note that tells what happened. (Read the <a
+href="mailfilter.html">description of the filter</a>, if you're
+curious about it.)
+
+
+<p>I don't engage in e-mail bombs (sending many large or mails to the same
+address) or other forms of Internet terrorism. I don't even suggest
+other do. On the contrary, I react with hostility to people who suggest
+such things. Most of them are just ignorant, but that is not an excuse.
+Network abuse is network abuse, regardless of why you do it. If you send
+a mail bomb, you deserve to get thrown out of the net. Period.
+
+<h2>Privacy</h2>
+
+<p>I like to keep my private stuff private. If you can, please do PGP encrypt
+your mail to me (you can download my PGP public key
+<a href="lars-public-key.asc">directly</a> or from the
+<a href="http://www.pgp.net/pgpnet/">key servers</a>).
+
+<p>Please also PGP sign your letters, because Netscape made
+forging the sender trivial and popular.
+
+<h2>The address</h2>
+
+<p>My personal e-mail address is liw@iki.fi. Other addresses may or may
+not work. MIME is OK. My home page is at
+<a href="http://www.iki.fi/liw/">http://www.iki.fi/liw/</a>.
+
+<p>Articles meant for comp.os.linux.announce should be sent
+to linux-announce@news.ornl.gov, not to my personal address.
+The address must be in the To: or Cc: header. I reserve the
+right to ignore any articles sent via mailing lists or with Bcc:. News
+programs can usually send it to the correct address. See also <a
+href="http://www.iki.fi/liw/linux/cola.html">the comp.os.linux.announce
+home page</a>.
+
+<p>(22 September 1997, Lars Wirzenius) </body> </html>
diff --git a/libc/msdos/xxx/mailfilter-mh.html b/libc/msdos/xxx/mailfilter-mh.html
new file mode 100644
index 0000000..f7d4fb9
--- /dev/null
+++ b/libc/msdos/xxx/mailfilter-mh.html
@@ -0,0 +1,86 @@
+<!-- X-URL: http://www.cs.helsinki.fi/~wirzeniu/mailfilter-mh.html -->
+<BASE HREF="http://www.cs.helsinki.fi/~wirzeniu/mailfilter-mh.html">
+
+<html>
+<head>
+<title>Saving the outgoing addresses automatically</title>
+</head>
+<body>
+
+<h1>Saving the outgoing addresses automatically</h1>
+
+<p>I have a <a href="mailfilter.html">anti-junk mail filter</a>, which
+uses a whitelist of people I know and want mail from. Maintaining this
+list by hand is tiresome, so I have automated it.
+
+<p>I have configured MH to run a small script for each letter that I
+send. This is easy to do: edit <code>~/.mh_profile</code> to include
+a line like the following:
+
+<blockquote><pre>
+postproc: /home/liw/bin/xtract-to-and-post
+</pre></blockquote>
+
+This instructs MH to run the specified command for each outgoing letter.
+The letter will be given as input to it.
+
+<p><code>xtract-to-and-post</code> is a simple shell script:
+
+<blockquote><pre>
+#!/bin/sh
+
+PATH=$PATH:$HOME/bin
+
+greylist=$HOME/.procmail/greylist
+whitelist=$HOME/.procmail/whitelist
+lock=$greylist.lock
+
+x=''
+for i in "$@"
+do
+ x="$i"
+done
+
+if test -r "$x"
+then
+ if lockfile $lock
+ then
+ xtract-to-cc &lt; "$x" | sort -fu -o $greylist $greylist -
+ rm -f $lock
+ fi
+fi
+
+/usr/lib/mh/post "$@"
+</pre></blockquote>
+
+It looks more complicated than it is. Essentially it only uses
+<code>xtract-to-cc</code> to get all addresses from the To and Cc
+headers and adds them to the greylist file. There's some locking
+added to avoid concurrent updates.
+
+<p><code>xtract-to-cc</code> is a small <a
+href="http://www.python.org/">Python</a> script that prints
+out all addresses in the To and Cc headers of a mail message:
+
+<blockquote><pre>
+#!/usr/bin/python
+
+import sys
+from rfc822 import Message
+
+x = Message(sys.stdin)
+for i in x.getaddrlist('to'):
+ print i[1]
+for i in x.getaddrlist('cc'):
+ print i[1]
+</pre></blockquote>
+
+<p>Similar hacks can be done for other systems. If nothing else
+works, have your mailer send a copy of each sent message, and
+periodically run a suitable program to extract the addresses.
+
+<p>(9 September 1996,
+<a href="mail-to-lasu.html">Lars Wirzenius</a>)
+
+</body>
+</html>
diff --git a/libc/msdos/xxx/mailfilter.html b/libc/msdos/xxx/mailfilter.html
new file mode 100644
index 0000000..035c26e
--- /dev/null
+++ b/libc/msdos/xxx/mailfilter.html
@@ -0,0 +1,153 @@
+<!-- X-URL: http://www.cs.helsinki.fi/~wirzeniu/mailfilter.html -->
+<BASE HREF="http://www.cs.helsinki.fi/~wirzeniu/mailfilter.html">
+
+<html>
+<head>
+<title>Lasu's mail filters</title>
+</head>
+<body>
+
+<strong>Note: I've updated this page a little bit, but it still describes
+the previous version of the filter. The new filter is quite similar to
+the old one, but has easier configurability, and is (by default) rather
+less aggressive.</strong>
+
+<h1>Lasu's mail filters</h1>
+
+<p>This page explains how I use procmail to filter
+my mail. Perhaps the most interesting part is how I reject mail from
+strangers in order to avoid getting spammed. This is not an introduction
+to spam or why it's bad, or to procmail or mail filtering; see links at
+end for some suggestions, but I do assume you're able to implement the
+filtering on your own.
+
+<h2>The approach</h2>
+
+<p>My filtering approach is like this:
+<ol>
+<li> If the sender is on the blacklist, delete the letter.
+<li> Put mailing lists in their own folders. <em>This must be done
+ correctly!</em> Otherwise the mailing list mail is treated as
+ junk e-mail.
+<li> Put local administrative e-mail in its own folder. I administrate my
+ own Linux
+ box. This catches mail from system crontabs, news log summaries,
+ and so on. (Maybe not relevant to you.)
+<li> At this point, it should be personal mail. Check that the To or Cc
+ headers address me. If not, delete the mail.
+<li> Put bounce messages in their own mailbox.
+<li> If the sender is on my whitelist:
+ <ol>
+ <li> If I'm on vacation, send back automatic response.
+ <li> Put the letter in inbox.
+ </ol>
+<li> If the subject includes password, put in special folder for
+ unknown people.
+<li> Otherwise, autoreply with request to use password and delete the mail.
+</ol>
+
+<p>Instead of deleting the unwanted mail, it is also possible to just store
+it in a special folder. You should do this while testing the setup, so that
+you don't lose any important mail due to errors. It's best to use separate
+folders for each case; I have folders no-password and new-OTHER, but feel
+free to use other names.
+
+<p>When using this scheme, it is imperative to put all addresses you send
+mail to on your whitelist or else to put the password in the subject.
+Otherwise, you will annoy people. I have an automatic setup for the
+MH mailer.
+
+<h2>Problems</h2>
+
+<p>My approach has some problems:
+<ul>
+<li> If someone sends you mail using the Bcc header, it will be treated as
+ junk, since your address won't be visible in the To or Cc headers.
+ The Bcc header is removed before the mail is sent, so there is
+ no way to distinguish interesting Bcc'd messages and junk mail.
+ This is not really a problem for me, because I almost never get
+ Bcc'd mail, and when I do it is via one specific mailing list.
+<li> Subscribing to mailing lists. You can't filter away the list until
+ you know what the headers look like, so you have to turn off
+ the check for personal mail until you can get the list filtering
+ to work. (The new version of the filter attempts to put stuff from
+ unknown mailing lists to a separate folder, but better safe than
+ sorry.)
+<li> Spam sent to mailing lists won't be filtered away. This is not too big
+ a problem, because many mailing lists
+ now only allow subscribers to post to avoid spam.
+<li> Not all bounce messages are filtered correctly. Unfortunately, there
+ are about as many bounce message formats as there are mail
+ transport programs. This is a real problem, because it's not
+ really a good idea to not lose bounce messages. It also opens
+ a glaring hole, because spammers can make their junk look like
+ bounce messaages.
+<li> If the filter starts acting up, you'd better know Procmail, or be
+ prepared to drop it at once.
+</ul>
+
+<h2>Alternative methods</h2>
+
+<p>Many ways to fight junk mail have been proposed. Below is a list of
+a few of them and the reasons why I don't do that.
+
+<ul>
+
+<li><strong>Just delete them.</strong>
+This is what I've been doing. It takes time to read enough of a letter
+ to positively identify it as junk. Not a whole lot of time, but
+ doing something unproductive several times a day is not fun.
+ It is annoying and lowers my work morale. I do computers because
+ it's fun, and junkmail makes it not fun.
+
+<li><strong>Complain to sender or in public.</strong>
+This takes time. I don't want to spend time on dealing with junk.
+Using tools to automate most of the complaint process is not good
+enough, since no tool is able to decode forged headers completely,
+and sending the complaints to the wrong address is <em>wrong</em>.
+
+<li><strong>Just filter away known baddies.</strong>
+I won't know who they are, unless I get the mail, and by then it's too
+ late. Actually, I could read suitable newsgroups and mailing lists
+ and find reports of spammers, but again, it takes time I don't want
+ to spend. It also never ends, since the most persistent spammers
+ change accounts often, and there are hordes of new spammers on
+ the horizon.
+
+<li><strong>Use a service that removes your address from spammers' lists.</strong>
+Which one? How do I know they're reputable? What guarantee do I have that
+ the spammers use the services? Also, many of them have
+ been shown to be just another way to harvest e-mail addresses.
+
+<li><strong>Use a munged mail address in public.</strong>
+This causes postmasters (the people who keep the mail systems running)
+extra work. Not polite, and counter-productive on the long run.
+
+</ul>
+
+<h2>Related links</h2>
+<ul>
+<li> <a href="mailfilter2.tar.gz">My mail filter</a>.
+<li> <a href="mailfilter-mh.html">My MH setup to automatically put addresses
+ I send to to the whitelist.</a>
+<li> <a href="ftp://ftp.informatik.rwth-aachen.de/pub/packages/procmail/procmail.tar.gz">Procmail source code</a>,
+ if you system doesn't have procmail installed.
+<li> <a href="http://www.jazzie.com/ii/faqs/archive/mail/filtering-faq/">Mail Filtering FAQ</a>,
+ for more information about mail filtering in general.
+</ul>
+
+<h2>Feedback</h2>
+
+<p>I'd be glad to hear any suggestions on how this filtering scheme
+can be improved. Don't hesitate to tell me if you have ideas on solving
+the above problems or if you can think of a new problem. I'd also be
+grateful if tell me if you use this filtering scheme so that I can tell
+you about important updates. I'd also like to hear of alternative filtering
+schemes, especially for people using non-Unix systems. Follow the link
+at the bottom before mailing, so you'll know how to avoid my filtering.
+
+<p>(22 September 1997,
+<a href="mail-to-lasu.html">Lars Wirzenius</a>)
+
+</body>
+</html>
diff --git a/libc/msdos/xxx/mailfilter2.tar.gz b/libc/msdos/xxx/mailfilter2.tar.gz
new file mode 100644
index 0000000..233090d
--- /dev/null
+++ b/libc/msdos/xxx/mailfilter2.tar.gz
Binary files differ
diff --git a/libc/msdos/xxx/mips.com b/libc/msdos/xxx/mips.com
new file mode 100644
index 0000000..66cc110
--- /dev/null
+++ b/libc/msdos/xxx/mips.com
Binary files differ
diff --git a/libc/msdos/xxx/tryit.com b/libc/msdos/xxx/tryit.com
new file mode 100644
index 0000000..71ff71b
--- /dev/null
+++ b/libc/msdos/xxx/tryit.com
Binary files differ
diff --git a/libc/stdio2/stdio.c b/libc/stdio2/stdio.c
index 4bada7e..bc96100 100644
--- a/libc/stdio2/stdio.c
+++ b/libc/stdio2/stdio.c
@@ -13,6 +13,10 @@
#include <malloc.h>
#include <errno.h>
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
extern FILE *__IO_list; /* For fflush at exit */
#ifdef __AS386_16__
@@ -131,12 +135,12 @@ FILE *fp;
if ((v & __MODE_READING) && fflush(fp))
return EOF;
- /* Can't write or there's been an EOF or error then return EOF */
+ /* Can't write if there's been an EOF or error then return EOF */
if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE)
return EOF;
/* In MSDOS translation mode */
-#if __MODE_IOTRAN
+#if __MODE_IOTRAN && !O_BINARY
if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF)
return EOF;
#endif
@@ -197,7 +201,7 @@ FILE *fp;
}
ch = *(fp->bufpos++);
-#if __MODE_IOTRAN
+#if __MODE_IOTRAN && !O_BINARY
/* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */
if (ch == '\r' && (fp->mode & __MODE_IOTRAN))
goto try_again;
@@ -407,11 +411,12 @@ FILE *fp;
{
memcpy(buf, fp->bufpos, (unsigned) bytes);
fp->bufpos += bytes;
- return bytes;
+ return nelm;
}
else if (len > 0) /* Some buffered */
{
memcpy(buf, fp->bufpos, len);
+ fp->bufpos += len;
got = len;
}
@@ -473,12 +478,18 @@ FILE *fp;
len = fp->bufend - fp->bufpos;
if (bytes <= len) /* It'll fit in the buffer ? */
{
+ register int do_flush=0;
fp->mode |= __MODE_WRITING;
memcpy(fp->bufpos, buf, bytes);
+ if (v & _IOLBF)
+ {
+ if(memchr(fp->bufpos, '\n', bytes))
+ do_flush=1;
+ }
fp->bufpos += bytes;
- /* If we're not fully buffered */
- if (v & (_IOLBF | _IONBF))
+ /* If we're unbuffered or line buffered and have seen nl */
+ if (do_flush || (v & _IONBF) != 0)
fflush(fp);
return nelm;
@@ -584,7 +595,7 @@ FILE *fp;
char *mode;
{
int open_mode = 0;
-#if __MODE_IOTRAN
+#if __MODE_IOTRAN && !O_BINARY
int do_iosense = 1;
#endif
int fopen_mode = 0;
@@ -617,14 +628,19 @@ char *mode;
case '+':
fopen_mode |= __MODE_RDWR;
break;
-#if __MODE_IOTRAN
+#if __MODE_IOTRAN || O_BINARY
case 'b': /* Binary */
fopen_mode &= ~__MODE_IOTRAN;
+ open_mode |= O_BINARY;
+#if __MODE_IOTRAN && !O_BINARY
do_iosense=0;
+#endif
break;
case 't': /* Text */
fopen_mode |= __MODE_IOTRAN;
+#if __MODE_IOTRAN && !O_BINARY
do_iosense=0;
+#endif
break;
#endif
}
@@ -674,7 +690,7 @@ char *mode;
if( isatty(fd) )
{
fp->mode |= _IOLBF;
-#if __MODE_IOTRAN
+#if __MODE_IOTRAN && !O_BINARY
if( do_iosense ) fopen_mode |= __MODE_IOTRAN;
#endif
}
@@ -786,6 +802,7 @@ char * buf;
int mode;
size_t size;
{
+ int rv = 0;
fflush(fp);
if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart);
fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF);
@@ -796,14 +813,21 @@ size_t size;
if( mode == _IOFBF || mode == _IOLBF )
{
if( size <= 0 ) size = BUFSIZ;
- if( buf == 0 ) buf = malloc(size);
- if( buf == 0 ) return EOF;
-
- fp->bufstart = buf;
- fp->bufend = buf+size;
- fp->mode |= mode;
+ if( buf == 0 )
+ {
+ if( (buf = malloc(size)) != 0 )
+ fp->mode |= __MODE_FREEBUF;
+ else rv = EOF;
+ }
+ if( buf )
+ {
+ fp->bufstart = buf;
+ fp->bufend = buf+size;
+ fp->mode |= mode;
+ }
}
fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart;
+ return rv;
}
#endif
diff --git a/libc/string/string.c b/libc/string/string.c
index 3e6d2e4..ffce96c 100644
--- a/libc/string/string.c
+++ b/libc/string/string.c
@@ -632,7 +632,7 @@ unsigned int srcseg, srcoff, destseg, destoff, len;
cld
#endif
- ! sei ! Are we _really_ paranoid ?
+ ! sti ! Are we _really_ paranoid ?
#if !__FIRST_ARG_IN_AX__
mov ds,[bp+4] ! Careful, [bp+xx] is SS based.
diff --git a/libc/syscall/Makefile b/libc/syscall/Makefile
index 07b1428..0fd2ad6 100644
--- a/libc/syscall/Makefile
+++ b/libc/syscall/Makefile
@@ -4,7 +4,7 @@
LSRC=syslib0.c
LOBJ=__cstartup.o lseek.o getpid.o getppid.o getuid.o geteuid.o getgid.o \
- getegid.o dup2.o dup.o getpgrp.o times.o
+ getegid.o dup2.o getpgrp.o times.o
ESRC=exec.c
EOBJ=execve.o execl.o execv.o execle.o execlp.o execvp.o
@@ -13,7 +13,7 @@ DSRC=dirent.c
DOBJ=opendir.o closedir.o readdir.o
ifeq ($(LIB_CPU)-$(LIB_OS),i86-ELKS)
-OBJ=$(LOBJ) $(LOBJ) $(DOBJ) $(EOBJ) signal.o setjmp.o
+OBJ=$(LOBJ) $(DOBJ) $(EOBJ) signal.o setjmp.o
SYSCALLS=call_i86
endif
@@ -32,6 +32,9 @@ call_i86: syscall.mak
syscall.mak: mksyscall syscall.dat
sh mksyscall
+syscall.dat:
+ @touch syscall.dat
+
$(LIBC): $(LIBC)($(OBJ))
$(LIBC)($(LOBJ)): $(LSRC)
@@ -48,5 +51,5 @@ $(LIBC)($(EOBJ)): $(ESRC)
clean:
rm -f *.o libc.a
- rm -f syscall.c syscall.mak
+ rm -f syscall.c syscall.mak syscall.dat
rm -f call_tab.v defn_tab.v
diff --git a/libc/syscall/TODO b/libc/syscall/TODO
index f396897..ff14000 100644
--- a/libc/syscall/TODO
+++ b/libc/syscall/TODO
@@ -10,6 +10,8 @@ Subject: 8086 Shared Libs and local RPC.
True shared libs are impossible with the 8086 in small model.
BUT we can use RPC type links to provide a similar system.
+This is very machine specific.
+
Client side
-----------
diff --git a/libc/syscall/dirent.c b/libc/syscall/dirent.c
index 8f7574c..b928757 100644
--- a/libc/syscall/dirent.c
+++ b/libc/syscall/dirent.c
@@ -60,33 +60,6 @@ DIR *dirp;
}
#endif
-#ifdef __AS386_16__
-#ifdef L_readdir
-/*
- * This currently assumes we see a v. simple diectory structure, it's
- * probably faked!
- */
-struct dirent *
-readdir(dirp)
-DIR *dirp;
-{
- int cc;
- cc = read(dirp->dd_fd, dirp->dd_buf, sizeof(struct dirent));
-
- if (cc <= 0)
- return 0;
- if (cc != sizeof(struct dirent))
- {
- errno = EBADF;
- return 0;
- }
- return dirp->dd_buf;
-}
-#endif
-#else
-
-/* This is for 386 linux */
-
#ifdef L_readdir
struct dirent *
readdir(dirp)
@@ -103,4 +76,3 @@ DIR *dirp;
}
#endif
-#endif
diff --git a/libc/syscall/exec.c b/libc/syscall/exec.c
index 411b744..8337f11 100644
--- a/libc/syscall/exec.c
+++ b/libc/syscall/exec.c
@@ -107,7 +107,7 @@ char ** envp;
}
*pip++ = 0;
- rv = __exec(fname, stk_ptr, stack_bytes);
+ rv = __execve(fname, stk_ptr, stack_bytes);
/* FIXME: This will probably have to interpret '#!' style exe's */
sbrk(-stack_bytes);
return rv;
@@ -283,7 +283,7 @@ char ** envp;
}
*pip++ = 0;
- rv = __exec(fname, stk_ptr, stack_bytes);
+ rv = __execve(fname, stk_ptr, stack_bytes);
/* FIXME: This will probably have to interpret '#!' style exe's */
sbrk(-stack_bytes);
return rv;
diff --git a/libc/syscall/mkentry.sh b/libc/syscall/mkentry.sh
new file mode 100644
index 0000000..aae4904
--- /dev/null
+++ b/libc/syscall/mkentry.sh
@@ -0,0 +1,83 @@
+#!/bin/sh -
+#
+# This program generates entry.c from syscall.dat
+
+cat << \Trailer
+/* Switched to V7 system call layout... Chad - 1/5/96
+*/
+#asm
+*
+* The call table - autogenerated from syscall.dat
+*
+ .data
+sys_call_table:
+Trailer
+
+tr '[A-Z]' '[a-z]' < syscall.dat | \
+awk '/^#/{next;}
+/^[ ]$/{next;}
+{
+ callno = 0+$2;
+ if( $4 != "-" )
+ assigned_to[callno] = $1;
+
+ if( $3 == "x" || $3 == "" ) next;
+ else if( $4 == "@" || $4 == "-" ) next;
+
+ # Not implemented yet
+ if( substr($2, 1, 1) != "+" ) next;
+
+ if( maxno < callno ) maxno = callno;
+
+ str = "\t.word _sys_" $1;
+ line[callno] = sprintf("%-25s ! %d", str, callno);
+}
+END{
+ for(callno=0; callno<=maxno; callno++)
+ {
+ if( assigned_to[callno] == "fork" )
+ gsub("_sys_fork", "_do_fork ", line[callno]);
+
+ if( callno in line )
+ print line[callno];
+ else
+ {
+ if( assigned_to[callno] == "" )
+ assigned_to[callno] = "unassigned";
+ if( assigned_to[callno] == "vfork" )
+ {
+ str = "\t.word _do_fork";
+ }
+ else
+ str = "\t.word _no_syscall";
+ printf "%-25s ! %d - %s\n", str, callno, assigned_to[callno];
+ }
+ }
+}
+'
+
+cat <<\Trailer
+sys_call_table_end:
+
+*
+* Despatch a syscall (called from syscall_int)
+* Entry: ax=function code, stack contains parameters
+*
+ .text
+ .globl _syscall
+_syscall:
+ cmp ax,#((sys_call_table_end - sys_call_table)/2)
+ ja _no_syscall
+ ! look up address and jump to function
+ mov bx,ax
+ shl bx,#1 ! multiply by 2
+ add bx,#sys_call_table
+ j [bx]
+*
+* Unimplemented calls
+*
+_no_syscall:
+ mov ax,#-38
+ ret
+#endasm
+Trailer
diff --git a/libc/syscall/mksyscall b/libc/syscall/mksyscall
index f7b91a6..190554c 100644
--- a/libc/syscall/mksyscall
+++ b/libc/syscall/mksyscall
@@ -15,7 +15,16 @@
COMPACT=1
-rm -f syscall.c syscall.mak call_tab.v defn_tab.v
+rm -f syscall.c syscall.mak call_tab.v defn_tab.v syscall.dat
+
+if [ -r ${ELKSSRC}/arch/i86/kernel/syscall.dat \
+ -a ! -r ${TOPDIR}/libc/kinclude/Used ]
+
+then echo Using syscalls from ${ELKSSRC}
+ cp -p ${ELKSSRC}/arch/i86/kernel/syscall.dat syscall.dat
+else echo Using syscalls from syscall.dev86
+ cp -p syscall.dev86 syscall.dat
+fi
tr '[A-Z]' '[a-z]' < syscall.dat | \
awk -v COMPACT=$COMPACT 'BEGIN{
@@ -148,16 +157,18 @@ awk -v COMPACT=$COMPACT 'BEGIN{
/^[ ]*#/ { next; }
/^[ ]*$/ { next; }
{
- if( $2 > max_call ) max_call = $2;
- if( !($2 in calltab) )
- callwas[$2] = " /* " $1 " */";
+ callno = 0+$2;
+ if( !(callno in calltab) )
+ callwas[callno] = " /* " $1 " */";
if( $3 == "x" || $3 == "" ) next;
- else if( $4 == "-" ) next;
+ else if( $4 == "@" || $4 == "-" ) next;
else if( $4 == "*" ) funcname="__" $1;
else funcname=$1;
- calltab[$2] = $1;
+ if( callno > max_call ) max_call = callno;
+
+ calltab[callno] = $1;
if( length(obj) > 60 )
{
@@ -178,14 +189,14 @@ awk -v COMPACT=$COMPACT 'BEGIN{
{
if( $3 == 0 )
{
- printf(" mov ax,#%d\n", $2);
+ printf(" mov ax,#%d\n", callno);
}
else
{
printf("#if __FIRST_ARG_IN_AX__\n");
- printf(" mov dx,#%d\n", $2);
+ printf(" mov dx,#%d\n", callno);
printf("#else\n");
- printf(" mov ax,#%d\n", $2);
+ printf(" mov ax,#%d\n", callno);
printf("#endif\n");
}
printf(" br sys_call%d\n", $3);
@@ -231,7 +242,7 @@ awk -v COMPACT=$COMPACT 'BEGIN{
if( $3 >= 1 )
printf("#endif\n");
- printf(" mov ax,#%d\n", $2);
+ printf(" mov ax,#%d\n", callno);
printf(" int $80\n");
diff --git a/libc/syscall/syscall.dat b/libc/syscall/syscall.dat
deleted file mode 100644
index de5ed9b..0000000
--- a/libc/syscall/syscall.dat
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# Name No Args Flag, comment
-#
-# . = Ok, with comment
-# * = Needs libc code (Prefix __)
-# - = Obsolete/not required
-#
-# WARNING!
-# This file is used to generate includes for ELKSemu too.
-# This file is continually changing, when you upgrade you _MUST_ ensure
-# that ELKSemu is of a matching build!
-#
-# Calls that use one fd
-READ 3 3
-WRITE 4 3
-CLOSE 6 1
-LSEEK 19 3 * NB 2nd arg is an IO ptr to long not a long.
-FSTAT 28 2
-IOCTL 54 3 . Make this and fcntl the same ?
-FCNTL 55 3
-FTRUNCATE 93 3
-FCHMOD 94 2
-FCHOWN 95 3
-FSYNC 118 1
-FCHDIR 133 1
-LLSEEK 140 3 * 2nd arg is ptr to two longs
-READV 145 3
-WRITEV 146 3
-FLOCK 143 2 - Use fcntl
-DUP 41 1 - Using nasty fcntl function
-
-#
-SETUP 0 X
-EXIT 1 1 * C exit does stdio, _exit in crt0
-FORK 2 0
-OPEN 5 3
-WAIT4 7 4
-VFORK 8 0 . Needed for 8086
-GETINFO 49 1 - Possible? Gets pid,ppid,uid,euid etc
-LINK 9 2
-UNLINK 10 1
-EXEC 11 3 * Minix style exec
-CHDIR 12 1
-GETTIMEOFDAY 13 2 . time() exists only in libc
-MKNOD 14 3
-CHMOD 15 2
-CHOWN 16 3
-BRK 17 1 * This is only to tell the system
-STAT 18 2
-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
-SETTIMEOFDAY 25 2 . STIME should _NOT_ exist even as a libc.
-STIME 25 2 - This must NOT exist - even as a libc.
-PTRACE 26 4
-ALARM 27 2
-PAUSE 29 0
-UTIME 30 2
-ACCESS 33 2
-NICE 34 1 .
-FTIME 35 1 - Use gettimeofday
-SYNC 36 0
-KILL 37 2
-RENAME 38 2
-MKDIR 39 2
-RMDIR 40 1
-PIPE 42 1
-TIMES 43 2 * 2nd arg is pointer for long ret val.
-SETGID 46 1
-GETGID 47 1 * This gets both gid and egid
-SIGNAL 48 2 * Have put the despatch table in user space.
-ACCT 51 1 -
-SETPGID 57 2
-ULIMIT 58 2
-UMASK 60 1
-CHROOT 61 1
-USTAT 62 2
-GETPGRP 65 0 - use getpgid(0)
-SETSID 66 0
-SIGACTION 67 X
-SGETMASK 68 X
-SSETMASK 69 X
-SETREUID 70 2
-SETREGID 71 2
-SIGSUSPEND 72 X
-SIGPENDING 73 X
-SETHOSTNAME 74 2
-SETRLIMIT 75 2
-GETRLIMIT 76 2
-GETRUSAGE 77 2
-GETGROUPS 80 2
-SETGROUPS 81 2
-SYMLINK 83 2
-LSTAT 84 2
-READLINK 85 3
-SWAPON 87 X
-REBOOT 88 3 . The magic number is 0xfee1,0xdead,...
-MUNMAP 91 X
-TRUNCATE 92 3
-GETPRIORITY 96 2
-SETPRIORITY 97 3
-PROFIL 98 X
-STATFS 99 2
-FSTATFS 100 2
-SOCKETCALL 102 X
-SYSLOG 103 X
-SETITIMER 104 3
-GETITIMER 105 2
-UNAME 109 1
-VHANGUP 111 0
-SWAPOFF 115 X
-SYSINFO 116 X - Use /proc
-IPC 117 5 * This is for all SYSV IPC
-SIGRETURN 119 X
-SETDOMAINNAME 121 X
-ADJTIMEX 124 X
-MPROTECT 125 X
-SIGPROCMASK 126 X
-QUOTACTL 131 X
-GETPGID 132 1
-SYSFS 135 X
-PERSONALITY 136 X
-SETFSUID 138 1
-SETFSGID 139 1
-GETDENTS 141 X
-SELECT 142 5 *
-MSYNC 144 X
-GETSID 147 X
-FDATASYNC 148 X
-SYSCTL 149 X
-MUNLOCK 151 X
-MUNLOCKALL 153 X
-SCHED_SETPARAM 154 X
-SCHED_GETPARAM 155 X
-SCHED_SETSCHEDULER 156 X
-SCHED_GETSCHEDULER 157 X
-SCHED_YIELD 158 X
-SCHED_GET_PRIORITY_MAX 159 X
-SCHED_GET_PRIORITY_MIN 160 X
-SCHED_RR_GET_INTERVAL 161 X
diff --git a/libc/syscall/syscall.dev86 b/libc/syscall/syscall.dev86
new file mode 100644
index 0000000..29e7b5e
--- /dev/null
+++ b/libc/syscall/syscall.dev86
@@ -0,0 +1,160 @@
+#
+# 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 bba61ac..eb156ec 100644
--- a/makefile.in
+++ b/makefile.in
@@ -31,11 +31,11 @@ WALL =-Wtraditional -Wshadow -Wid-clash-14 -Wpointer-arith \
WALL =-Wstrict-prototypes
-CC =gcc $(GCCFLAG)
+CC =gcc
#ifdef __i386__
-CFLAGS =-Wall $(WALL) -O2 -m486 -fno-strength-reduce -g
+CFLAGS =$(GCCFLAG) -Wall $(WALL) -O2 -m486 -fno-strength-reduce -g
#else
-CFLAGS =-Wall $(WALL) -O6 -g
+CFLAGS =$(GCCFLAG) -Wall $(WALL) -O6 -g
#endif
#endif
@@ -68,8 +68,15 @@ INDAT=-o root -g root -m 644
INEXE=-o root -g root -m 755 -s
INSCR=-o root -g root -m 755
-all: check_config bcc unproto copt as86 ld86 \
+#ifdef GNUMAKE
+all: check_config bcc unproto copt as86 ld86 objdump86 \
library lib-bsd alt-libs elksemu
+#else
+all: check_config bcc unproto copt as86 ld86 objdump86
+ @echo
+ @echo 'NOTE: To build the libraries you need GNU-Make.'
+ @echo ' They are available precompiled in the Dev86clb-X.X.X.zip file.'
+#endif
install: check_config install-bcc install-man \
install-lib install-lib2 install-emu
@@ -81,10 +88,15 @@ install-all: install install-other
LIBARGS= CC=ncc CCFLAGS= ARFLAGS=$(ARFLAGS)
# Season in the top makefile
+ELKSSRC= %ELKSSRC%
PREFIX= %PREFIX%
BINDIR= %BINDIR%
LIBDIR= %LIBDIR%
+#ifdef GNUMAKE
+export ELKSSRC
+#endif
+
DISTBIN= $(DIST)$(BINDIR)
DISTLIB= $(DIST)$(LIBDIR)
DISTPRE= $(DIST)$(PREFIX)
@@ -100,6 +112,10 @@ bindir: $(MAKEX)
@mkdir -p bin lib lib/i386
@rm -f include
@ln -s libc/include include 2>/dev/null || true
+#ifndef GNUMAKE
+ @ln -s ../kinclude/linuxmt include/linuxmt 2>/dev/null || true
+ @ln -s ../kinclude/arch include/arch 2>/dev/null || true
+#endif
phony:
@@ -131,13 +147,17 @@ ld86r: bindir
$(MAKEC) ld $(MAKEARG) ld86r
cp -p ld/ld86r bin/ld86r
+objdump86: bindir
+ $(MAKEC) ld $(MAKEARG) objdump86
+ cp -p ld/objdump86 bin/objdump86
+
elksemu: bindir
#ifdef __i386__
$(MAKEC) elksemu \
CC='$(CC)' PREFIX=$(PREFIX) LIBDIR='$(LIBDIR)' BINDIR='$(BINDIR)' \
elksemu
#else
- $(MAKEC) elksemu CC='ncc' DEFS=-N- elksemu
+ $(MAKEC) elksemu CC='ncc' elksemu
#endif
cp -p elksemu/elksemu bin/elksemu
@@ -151,12 +171,15 @@ install-ln: bcc unproto copt as86 ld86 elksemu
install -d $(DIST)/usr/lib
install $(INDAT) libc/error/liberror.txt $(DIST)/usr/lib/liberror.txt
-install-bcc: bcc unproto copt as86 ld86
+install-bcc: bcc unproto copt as86 ld86 objdump86
install -d $(DISTBIN) $(DISTLIB) $(DISTLIB)/i86
install $(INEXE) bin/Bcc $(DISTBIN)/bcc
install $(INSCR) bin/as86_encap $(DISTBIN)/as86_encap
install $(INEXE) bin/as86 $(DISTBIN)/as86
install $(INEXE) bin/ld86 $(DISTBIN)/ld86
+ install $(INEXE) bin/objdump86 $(DISTBIN)/objdump86
+ install $(INEXE) bin/objdump86 $(DISTBIN)/nm86
+ install $(INEXE) bin/objdump86 $(DISTBIN)/size86
install $(INEXE) lib/bcc-cc1 $(DISTLIB)/bcc-cc1
install $(INEXE) lib/unproto $(DISTLIB)/unproto
install $(INEXE) lib/copt $(DISTLIB)/copt
@@ -256,7 +279,7 @@ config: $(MAKEX)
$(MAKEC) libc config
#else
-check_config: $(MAKEX) ;
+check_config: ;
config: ;
#endif
@@ -285,5 +308,6 @@ realclean:
rm -rf bin lib
rm -f include
rm -f makec
+ rm -f `find . -type l -print`
##############################################################################
diff --git a/man/as86.1 b/man/as86.1
index 199c65f..27e7d74 100644
--- a/man/as86.1
+++ b/man/as86.1
@@ -1,4 +1,4 @@
-.TH as86 1 "Jan, 1997"
+.TH as86 1 "Oct, 1997"
.BY Bruce Evans
.nh
.SH NAME
diff --git a/man/bcc.1 b/man/bcc.1
index 21cc421..fab6275 100644
--- a/man/bcc.1
+++ b/man/bcc.1
@@ -1,11 +1,11 @@
-.TH bcc 1 "Jan, 1997"
+.TH bcc 1 "Nov, 1997"
.BY Bruce Evans
.nh
.SH NAME
bcc \- Bruce's C compiler
.SH SYNOPSIS
.B bcc
-.RB [ -03EGNOPSVcegv ]
+.RB [ -03EGNOPSVcegvwxW ]
.RB [ -Aas_option ]
.RB [ -Bexecutable_prefix ]
.RB [ -Ddefine ]
@@ -18,6 +18,7 @@ bcc \- Bruce's C compiler
.RB [ -Lld_option ]
.RB [ -Ttmpdir ]
.RB [ -Qc386_option ]
+.RB [ -ttext_segno ]
.RB [ ld_options ]
.RB [ infiles ]
.SH DESCRIPTION
@@ -168,7 +169,7 @@ output file name follows (assembler, object or executable) (as usual)
error (profiling not supported)
.TP
.B -t
-error (substitution of some cc passes not supported)
+pass to the assembler to renumber the text segment for multi-segment programs.
.TP
.B -v
print names and args of subprocesses being run. Two or more -v's print
@@ -176,8 +177,15 @@ names of files being unlinked. Three or more -v's print names of paths
being searched.
.TP
.B -w
-allow the assembler to generate warnings, useful for finding 80186+
-instructions.
+Supress any warning diagnostics.
+.TP
+.B -W
+Turn
+.B on
+assembler warning messages.
+.TP
+.B -x
+don't include crt0.o in the link.
.P
Other options are passed to the linker, in particular -i-, -lx, -M, -m, -s, -H.
The -i option is always passed to the linker but can be cancelled using -i-.
diff --git a/man/ld86.1 b/man/ld86.1
index 1349969..4f14bd7 100644
--- a/man/ld86.1
+++ b/man/ld86.1
@@ -1,4 +1,4 @@
-.TH ld86 1 "Jan, 1997"
+.TH ld86 1 "Apr, 1997"
.BY Bruce Evans
.nh
.SH NAME