From 48f0b3eb836162d41622cedc1eb5f5168168fb8e Mon Sep 17 00:00:00 2001 From: Robert de Bath Date: Sun, 1 Feb 1998 11:26:21 +0100 Subject: Import Dev86src-0.13.5.tar.gz --- Changes | 23 +- Contributors | 7 +- Libc_version | 2 +- MAGIC | 2 +- Makefile | 25 +- README | 28 +- as/as.c | 8 + as/as86_encap.sh | 10 +- as/globvar.h | 2 + as/pops.c | 5 +- as/readsrc.c | 1 + bcc/align.h | 2 +- bcc/assign.c | 14 +- bcc/bcc.c | 106 +- bcc/codefrag.c | 76 +- bcc/debug.c | 2 +- bcc/declare.c | 32 +- bcc/express.c | 2 +- bcc/exptree.c | 2 +- bcc/function.c | 8 +- bcc/gencode.c | 38 +- bcc/gencode.h | 34 +- bcc/genloads.c | 38 +- bcc/glogcode.c | 4 +- bcc/hardop.c | 16 +- bcc/label.c | 12 +- bcc/loadexp.c | 14 +- bcc/longop.c | 2 +- bcc/output.c | 12 +- bcc/preserve.c | 8 +- bcc/proto.h | 48 +- bcc/sizes.h | 6 +- bcc/softop.c | 66 +- bcc/state.c | 24 +- bcc/type.c | 20 +- bcc/type.h | 12 +- bcc/types.h | 14 +- bootblocks/Makefile | 14 +- bootblocks/bzimage.c | 197 +- bootblocks/dosfs.c | 418 ---- bootblocks/fs.c | 81 + bootblocks/fs_dos.c | 317 +++ bootblocks/fs_min.c | 31 + bootblocks/fs_tar.c | 156 ++ bootblocks/i86_funcs.c | 1 + bootblocks/makeboot.c | 348 +++- bootblocks/mbr.s | 5 + bootblocks/monitor.c | 85 +- bootblocks/msdos.s | 48 +- bootblocks/nofs.c | 55 - bootblocks/readfs.h | 27 + bootblocks/relocate.c | 27 +- bootblocks/standalone.c | 1 + bootblocks/sysboot.s | 4 - bootblocks/tarboot.s | 4 +- bootblocks/trk_buf.c | 275 +++ bootblocks/unix.c | 137 ++ copt/copt.c | 72 +- copt/copt.diff | 72 - copt/rules.86 | 8 +- copt/rules.end | 2 +- elksemu/elks.c | 24 + elksemu/elks_sys.c | 30 +- ld/Makefile | 6 +- ld/dumps.c | 24 +- ld/io.c | 48 +- ld/objchop.c | 2 +- ld/objdump86.c | 681 +++++++ ld/syshead.h | 2 + ld/type.h | 1 + ld/writex86.c | 80 +- ld/x | 1 + libc/Config_sh | 4 +- libc/Makefile | 7 +- libc/bios/Makefile | 2 +- libc/bios/bios_vid.c | 7 + libc/bios/time.c | 127 ++ libc/error/sys_errlist.c | 13 +- libc/getent/pwent.c | 2 + libc/include/asm/limits.h | 16 +- libc/include/dos.h | 1 + libc/kinclude/Config | 2 +- libc/misc/Makefile | 2 +- libc/misc/crypt.c | 45 +- libc/misc/tmpnam.c | 50 + libc/msdos/Makefile | 2 +- libc/msdos/i86.c | 50 +- libc/msdos/time.c | 2 +- libc/msdos/xxx/KEYTEST.C | 575 ++++++ libc/msdos/xxx/KEYTEST.EXE | Bin 0 -> 12236 bytes libc/msdos/xxx/KEYTEST.OBJ | Bin 0 -> 5567 bytes libc/msdos/xxx/TALK.C | 3931 +++++++++++++++++++++++++++++++++++++ libc/msdos/xxx/TALK.EXE | Bin 0 -> 23166 bytes libc/msdos/xxx/ZIP.COM | Bin 0 -> 16336 bytes libc/msdos/xxx/comx.com | Bin 0 -> 7772 bytes libc/msdos/xxx/cpu.com | Bin 0 -> 4824 bytes libc/msdos/xxx/list.com | Bin 0 -> 25927 bytes libc/msdos/xxx/mail-to-lasu.html | 105 + libc/msdos/xxx/mailfilter-mh.html | 86 + libc/msdos/xxx/mailfilter.html | 153 ++ libc/msdos/xxx/mailfilter2.tar.gz | Bin 0 -> 7104 bytes libc/msdos/xxx/mips.com | Bin 0 -> 13312 bytes libc/msdos/xxx/tryit.com | Bin 0 -> 3504 bytes libc/stdio2/stdio.c | 54 +- libc/string/string.c | 2 +- libc/syscall/Makefile | 9 +- libc/syscall/TODO | 2 + libc/syscall/dirent.c | 28 - libc/syscall/exec.c | 4 +- libc/syscall/mkentry.sh | 83 + libc/syscall/mksyscall | 31 +- libc/syscall/syscall.dat | 142 -- libc/syscall/syscall.dev86 | 160 ++ makefile.in | 38 +- man/as86.1 | 2 +- man/bcc.1 | 18 +- man/ld86.1 | 2 +- 117 files changed, 8470 insertions(+), 1296 deletions(-) delete mode 100644 bootblocks/dosfs.c create mode 100644 bootblocks/fs.c create mode 100644 bootblocks/fs_dos.c create mode 100644 bootblocks/fs_min.c create mode 100644 bootblocks/fs_tar.c delete mode 100644 bootblocks/nofs.c create mode 100644 bootblocks/trk_buf.c create mode 100644 bootblocks/unix.c delete mode 100644 copt/copt.diff create mode 100644 ld/objdump86.c create mode 100644 ld/x create mode 100644 libc/bios/time.c create mode 100644 libc/misc/tmpnam.c create mode 100644 libc/msdos/xxx/KEYTEST.C create mode 100644 libc/msdos/xxx/KEYTEST.EXE create mode 100644 libc/msdos/xxx/KEYTEST.OBJ create mode 100644 libc/msdos/xxx/TALK.C create mode 100644 libc/msdos/xxx/TALK.EXE create mode 100644 libc/msdos/xxx/ZIP.COM create mode 100644 libc/msdos/xxx/comx.com create mode 100644 libc/msdos/xxx/cpu.com create mode 100644 libc/msdos/xxx/list.com create mode 100644 libc/msdos/xxx/mail-to-lasu.html create mode 100644 libc/msdos/xxx/mailfilter-mh.html create mode 100644 libc/msdos/xxx/mailfilter.html create mode 100644 libc/msdos/xxx/mailfilter2.tar.gz create mode 100644 libc/msdos/xxx/mips.com create mode 100644 libc/msdos/xxx/tryit.com create mode 100644 libc/syscall/mkentry.sh delete mode 100644 libc/syscall/syscall.dat create mode 100644 libc/syscall/syscall.dev86 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 -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 Nat Friedman Steven Huang +Steffen Kaiser +Shane Kerr Gero Kuhlmann Chad Page Dick Porter Dale Schumacher +Wietse Venema Joel Weber II 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 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 ) +Rob. (Robert de Bath ) 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)); @@ -232,9 +221,6 @@ char **argv; bool_T cpp_pass = TRUE; #else bool_T cpp_pass = FALSE; -#endif -#ifdef BCC86 - char *crt0; #endif char *libc = "-lc"; #ifdef MSDOS @@ -242,12 +228,12 @@ char **argv; #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 +#include #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/dosfs.c b/bootblocks/dosfs.c deleted file mode 100644 index b9a2c04..0000000 --- a/bootblocks/dosfs.c +++ /dev/null @@ -1,418 +0,0 @@ - -#ifdef __STANDALONE__ - -#include -#include -#include "readfs.h" - -#define DOS_SECT(P) get_uint(P,0x0B) -#define DOS_CLUST(P) get_byte(P,0x0D) -#define DOS_RESV(P) get_uint(P,0x0E) -#define DOS_NFAT(P) get_byte(P,0x10) -#define DOS_NROOT(P) get_uint(P,0x11) -#define DOS_MAXSECT(P) get_uint(P,0x13) -#define DOS_MEDIA(P) get_byte(P,0x15) -#define DOS_FATLEN(P) get_uint(P,0x16) -#define DOS_SPT(P) get_uint(P,0x18) -#define DOS_HEADS(P) get_uint(P,0x1A) -#define DOS_HIDDEN(P) get_long(P,0x1C) -#define DOS4_MAXSECT(P) get_long(P,0x20) -#define DOS4_PHY_DRIVE(P) get_byte(P,0x24) -#define DOS4_SERIAL(P) get_long(P,0x27) - -/* These assume alignment is not a problem */ -#define get_byte(P,Off) *((unsigned char*)((char*)(P)+(Off))) -#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 char * fat_buf = 0; - -struct filestatus { - char fname[12]; - unsigned short first_cluster; - unsigned short cur_cluster; - unsigned short sector_no; - long file_length; -} - cur_file = { "", 0, 0, 0 }; - -open_file(fname) -char * fname; -{ - extern union REGS __argr; - char conv_name[12]; - char *s, *d; - int i; - int dodir = 0; - - if(strcmp(fname, ".") == 0) dodir = 1; - else - { - /* Convert the name to MSDOS directory format */ - strcpy(conv_name, " "); - for(s=fname, d=conv_name; *s && *d && *s != '.' && *s != ' '; s++) - { - if( islower(*s) ) *d++ = toupper(*s); - else *d++ = *s; - } - while( *s && *s != '.' ) s++; - strcpy(d=(conv_name+8), " "); - if( *s == '.' ) - { - for(s++; *s && *d; s++) - { - if( islower(*s) ) *d++ = toupper(*s); - else *d++ = *s; - } - } - - /* Already opened ? Then just rewind it */ - if( cur_file.first_cluster && strcmp(cur_file.fname, conv_name) == 0 ) - return rewind_file(); - } - - memset(&cur_file, '\0', sizeof(cur_file)); - - /* Get the superblock */ - 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 ) - { - /* Read in and buffer the FAT */ - if( fat_buf ) free(fat_buf); - fat_buf = malloc(DOS_FATLEN(s) * 512); - if( fat_buf == 0 ) return -1; - else - { - int fatsec = DOS_RESV(s); - int nsec = DOS_FATLEN(s); - - for(i=0; i>5)&0xF), - ((get_uint(d,24)>>9)&0x7F)+1980, - ((get_uint(d,22)>>11)&0x1F), - ((get_uint(d,22)>>5)&0x3F) - ); - if( *d > ' ' && *d <= '~' ) switch(d[11]&0x18) - { - case 0: - printf("%-8.8s %-3.3s %10ld%s\n", d, d+8, get_long(d,28), dtime); - break; - case 0x10: - printf("%-8.8s %-3.3s %s\n", d, d+8, dtime); - break; - case 8: - if( (d[11] & 7) == 0 ) - printf("%-11.11s %s\n", d, dtime); - break; - } - } - else if( memcmp(d, conv_name, 11) == 0 && (d[11]&0x18) == 0 ) - { /* Name matches and is normal file */ - - strcpy(cur_file.fname, conv_name); - cur_file.first_cluster = get_uint(d,26); - cur_file.file_length = get_long(d,28); - - cur_file.cur_cluster = cur_file.first_cluster; - cur_file.sector_no = 0; - - return 0; - } - } - return -1; -} - -rewind_file() -{ - /* Is there an opened file ? */ - if( cur_file.fname[0] == 0 ) return -1; - - cur_file.sector_no = 0; - cur_file.cur_cluster = cur_file.first_cluster; - return 0; -} - -close_file() -{ - 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; - return 0; -} - -long -file_length() -{ - /* Is there an opened file ? */ - if( cur_file.fname[0] == 0 ) return -1; - - return cur_file.file_length; -} - -read_block(buffer) -char * buffer; -{ - int s; - char * ptr; - - /* Is there an opened file ? */ - if( cur_file.fname[0] == 0 ) return -1; - - /* Are we before the EOF ? NB: FAT12 ONLY! */ - if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) return -1; - - for(s=0; s<2; s++) - { - unsigned int sectno; - - if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) - { - memset(buffer, '\0', 512); - buffer += 512; - continue; - } - - sectno = dos_clust0 - + cur_file.cur_cluster * dos_spc - + cur_file.sector_no % dos_spc; - - ptr = read_sector(sectno); - if( ptr == 0 ) return -1; - memcpy(buffer, ptr, 512); - - cur_file.sector_no++; - if( cur_file.sector_no % dos_spc == 0 ) - { - int odd = (cur_file.cur_cluster&1); - unsigned int val; - - val = cur_file.cur_cluster + (cur_file.cur_cluster>>1); - val = get_uint(fat_buf, val); - - if( odd ) val>>=4; - - val &= 0xFFF; - - cur_file.cur_cluster = val; - } - - buffer += 512; - } - - 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 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; -} - -static int alloc_trackbuf(sectors) -int sectors; -{ - char * new_track; - int seg_start, seg_end; - if( sectors <= track_len ) return 0; - - if( track_buffer ) free(track_buffer); - track_buffer = 0; - track_len = 0; - track_number = -1; - - if( sectors < 1 || sectors > 63 ) /* WTF! */ return -1; - - new_track = malloc(sectors*512); - if( new_track == 0 ) return -1; - - seg_start = __get_ds() + (unsigned int)new_track / 16; - seg_end = __get_ds() + (unsigned int)(new_track+sectors*512-1) / 16; - - if( (seg_start&0xF000) != (seg_end&0xF000) ) /* Bugger */ - { - int rv = alloc_trackbuf(sectors); - free(new_track); - return rv; - } - - 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.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 +#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/fs_dos.c b/bootblocks/fs_dos.c new file mode 100644 index 0000000..d2ca5eb --- /dev/null +++ b/bootblocks/fs_dos.c @@ -0,0 +1,317 @@ + +#include +#include +#include +#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) +#define DOS_NFAT(P) get_byte(P,0x10) +#define DOS_NROOT(P) get_uint(P,0x11) +#define DOS_MAXSECT(P) get_uint(P,0x13) +#define DOS_MEDIA(P) get_byte(P,0x15) +#define DOS_FATLEN(P) get_uint(P,0x16) +#define DOS_SPT(P) get_uint(P,0x18) +#define DOS_HEADS(P) get_uint(P,0x1A) +#define DOS_HIDDEN(P) get_long(P,0x1C) +#define DOS4_MAXSECT(P) get_long(P,0x20) +#define DOS4_PHY_DRIVE(P) get_byte(P,0x24) +#define DOS4_SERIAL(P) get_long(P,0x27) + +/* These assume alignment is not a problem */ +#define get_byte(P,Off) *((unsigned char*)((char*)(P)+(Off))) +#define get_uint(P,Off) *((unsigned short*)((char*)(P)+(Off))) +#define get_long(P,Off) *((long*)((char*)(P)+(Off))) + +static int read_bootblock(); +static int dir_nentry, dir_sect; +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; + unsigned short cur_cluster; + unsigned short sector_no; + long file_length; +} + cur_file = { "", 0, 0, 0 }; + +dos_open_file(fname) +char * fname; +{ + extern union REGS __argr; + char conv_name[12]; + char *s, *d; + int i; + int dodir = 0; + + /* Get the superblock */ + if( read_bootblock() < 0 ) return -1; + + if(strcmp(fname, ".") == 0) + dodir = 1; + else + { + /* Convert the name to MSDOS directory format */ + strcpy(conv_name, " "); + for(s=fname, d=conv_name; *s && *d && *s != '.' && *s != ' '; s++) + { + if( islower(*s) ) *d++ = toupper(*s); + else *d++ = *s; + } + while( *s && *s != '.' ) s++; + strcpy(d=(conv_name+8), " "); + if( *s == '.' ) + { + for(s++; *s && *d; s++) + { + if( islower(*s) ) *d++ = toupper(*s); + else *d++ = *s; + } + } + + /* Already opened ? Then just rewind it */ + if( cur_file.first_cluster && strcmp(cur_file.fname, conv_name) == 0 ) + return dos_rewind_file(); + } + + memset(&cur_file, '\0', sizeof(cur_file)); + +#ifdef BUFFER_FAT + s = read_sector(0); + + if( !dodir ) + { + /* Read in and buffer the FAT */ + if( fat_buf ) free(fat_buf); + fat_buf = malloc(DOS_FATLEN(s) * 512); + if( fat_buf == 0 ) return -1; + else + { + int fatsec = DOS_RESV(s); + int nsec = DOS_FATLEN(s); + + for(i=0; i>5)&0xF), + ((get_uint(d,24)>>9)&0x7F)+1980, + ((get_uint(d,22)>>11)&0x1F), + ((get_uint(d,22)>>5)&0x3F) + ); + if( *d > ' ' && *d <= '~' ) switch(d[11]&0x18) + { + case 0: + printf("%-8.8s %-3.3s %10ld%s\n", d, d+8, get_long(d,28), dtime); + break; + case 0x10: + printf("%-8.8s %-3.3s %s\n", d, d+8, dtime); + break; + case 8: + if( (d[11] & 7) == 0 ) + printf("%-11.11s %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 */ + + strcpy(cur_file.fname, conv_name); + cur_file.first_cluster = get_uint(d,26); + cur_file.file_length = get_long(d,28); + + 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; + } + } + return -1; +} + +dos_rewind_file() +{ + /* Is there an opened file ? */ + if( cur_file.fname[0] == 0 ) return -1; + + cur_file.sector_no = 0; + cur_file.cur_cluster = cur_file.first_cluster; + return 0; +} + +dos_close_file() +{ +#ifdef BUFFER_FAT + if( fat_buf ) free(fat_buf); + fat_buf = 0; +#endif + memset(&cur_file, '\0', sizeof(cur_file)); + + reset_disk(); + return 0; +} + +long +dos_file_length() +{ + /* Is there an opened file ? */ + if( cur_file.fname[0] == 0 ) return -1; + + return cur_file.file_length; +} + +dos_read_block(buffer) +char * buffer; +{ + int s; + char * ptr; + + /* Is there an opened file ? */ + 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 ) + { +#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++) + { + unsigned int sectno; + + if( cur_file.cur_cluster >= 0xFF0 || cur_file.cur_cluster < 2 ) + { + memset(buffer, '\0', 512); + buffer += 512; + continue; + } + + sectno = dos_clust0 + + cur_file.cur_cluster * dos_spc + + cur_file.sector_no % dos_spc; + + ptr = read_sector(sectno); + if( ptr == 0 ) return -1; + memcpy(buffer, ptr, 512); + + cur_file.sector_no++; + if( cur_file.sector_no % dos_spc == 0 ) + { + int odd = (cur_file.cur_cluster&1); + unsigned int val, val2; + + val = cur_file.cur_cluster + (cur_file.cur_cluster>>1); +#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 ) val2>>=4; + + val2 &= 0xFFF; + + cur_file.cur_cluster = val2; + } + + buffer += 512; + } + + return 0; +} + +static int read_bootblock() +{ + char * sptr; + int rv, media_byte = 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( DOS_MEDIA(sptr) != media_byte ) return -1; + if( DOS_SPT(sptr) > 63 ) return -1; + if( DOS_SECT(sptr) != 512 ) return -1; + + if( last_serial != DOS4_SERIAL(sptr) ) dos_close_file(); + last_serial = DOS4_SERIAL(sptr); + + /* Collect important data */ + dir_sect = DOS_RESV(sptr) + DOS_NFAT(sptr)*DOS_FATLEN(sptr); + dir_nentry = DOS_NROOT(sptr); + + 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( disk_cyls == 0 ) + { + disk_spt = DOS_SPT(sptr); + disk_heads = DOS_HEADS(sptr); + } + + return 0; +} 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 +#endif + +#include +#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 #include +#include #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 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 -#include -#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 +#include +#include +#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 #include #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 +#include +#include +#include +#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 + +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 #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 +#include +#include + +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>(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>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; i7), 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 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 + +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 -#include /* TEA based crypt(), version 0.0 * 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 + 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 under terms of LGPL + */ + +#include +#include +#include + +#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 +#include +#include +#include + +#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' 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 Binary files /dev/null and b/libc/msdos/xxx/KEYTEST.EXE differ diff --git a/libc/msdos/xxx/KEYTEST.OBJ b/libc/msdos/xxx/KEYTEST.OBJ new file mode 100644 index 0000000..10e5755 Binary files /dev/null and b/libc/msdos/xxx/KEYTEST.OBJ 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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, ®, ®) +#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 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, ®s, ®s); + 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 ' [ 5 ; 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 ( 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; idirtypg || 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; ilines[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; ilines[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; arattr = curpage->std_col; + break; + case 1: curpage->attr |= 0x08; + break; +#ifdef SCO_ANSI + case 2: if( dos_mode != 2 && dos_mode != 7 && ar+2std_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+1attr = ((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+2rev_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; iclr_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, ®s, ®s); + + 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, ®s, ®s); + 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= 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>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= 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= 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; ilines[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; ilines[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; ilines[tlr+i][k] = (curpage->attr<<8)+' '; + } + } + dirty_lines(tlr, rows); +} + +dirty_lines(top, count) +int top, count; +{ + int i; + for(i=0; idirty[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' 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 Binary files /dev/null and b/libc/msdos/xxx/TALK.EXE differ diff --git a/libc/msdos/xxx/ZIP.COM b/libc/msdos/xxx/ZIP.COM new file mode 100644 index 0000000..cd06cf9 Binary files /dev/null and b/libc/msdos/xxx/ZIP.COM differ diff --git a/libc/msdos/xxx/comx.com b/libc/msdos/xxx/comx.com new file mode 100644 index 0000000..db80d00 Binary files /dev/null and b/libc/msdos/xxx/comx.com differ diff --git a/libc/msdos/xxx/cpu.com b/libc/msdos/xxx/cpu.com new file mode 100644 index 0000000..23ab7e8 Binary files /dev/null and b/libc/msdos/xxx/cpu.com differ diff --git a/libc/msdos/xxx/list.com b/libc/msdos/xxx/list.com new file mode 100644 index 0000000..f17d5e3 Binary files /dev/null and b/libc/msdos/xxx/list.com 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 @@ + + + + Sending mail to Lasu + +

Sending mail to Lasu

+ +

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. + +

+This page explains my mail preferences. I'm grateful if you read it +before sending me mail. + +

I don't want to receive: + +

    +
  • Advertisments I did not ask for. Making me pay for your ads is + rude, and possibly illegal. I react strongly to ads. +
  • Chain letters. Most of them are illegal. All of them are a waste + of network resources. I react strongly to chain letters. +
  • Mailing lists I did not subscribe to, whether they are for ads or + not. I react strongly to this. +
  • 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.) +
  • 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. +
  • 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. +
  • 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. +
+ +

I welcome: + +

    +
  • Anything from friends, relatives, and other people I personally know. +
  • Anything I've specifically asked for, including ads or big files. +
  • 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. +
  • Anything related to comp.os.linux.announce, which I moderate. +
  • Anything related to the Linux Software Map, which I maintain. +
  • 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. +
  • Mailing lists I've subscribed to. +
+ +

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. + +

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 description of the filter, if you're +curious about it.) + + +

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. + +

Privacy

+ +

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 +directly or from the +key servers). + +

Please also PGP sign your letters, because Netscape made +forging the sender trivial and popular. + +

The address

+ +

My personal e-mail address is liw@iki.fi. Other addresses may or may +not work. MIME is OK. My home page is at +http://www.iki.fi/liw/. + +

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 the comp.os.linux.announce +home page. + +

(22 September 1997, Lars Wirzenius) 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 @@ + + + + + +Saving the outgoing addresses automatically + + + +

Saving the outgoing addresses automatically

+ +

I have a anti-junk mail filter, which +uses a whitelist of people I know and want mail from. Maintaining this +list by hand is tiresome, so I have automated it. + +

I have configured MH to run a small script for each letter that I +send. This is easy to do: edit ~/.mh_profile to include +a line like the following: + +

+postproc: /home/liw/bin/xtract-to-and-post
+
+ +This instructs MH to run the specified command for each outgoing letter. +The letter will be given as input to it. + +

xtract-to-and-post is a simple shell script: + +

+#!/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 < "$x" | sort -fu -o $greylist $greylist -
+		rm -f $lock
+	fi
+fi
+
+/usr/lib/mh/post "$@"
+
+ +It looks more complicated than it is. Essentially it only uses +xtract-to-cc 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. + +

xtract-to-cc is a small Python script that prints +out all addresses in the To and Cc headers of a mail message: + +

+#!/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]
+
+ +

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. + +

(9 September 1996, +Lars Wirzenius) + + + 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 @@ + + + + + +Lasu's mail filters + + + +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. + +

Lasu's mail filters

+ +

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. + +

The approach

+ +

My filtering approach is like this: +

    +
  1. If the sender is on the blacklist, delete the letter. +
  2. Put mailing lists in their own folders. This must be done + correctly! Otherwise the mailing list mail is treated as + junk e-mail. +
  3. 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.) +
  4. At this point, it should be personal mail. Check that the To or Cc + headers address me. If not, delete the mail. +
  5. Put bounce messages in their own mailbox. +
  6. If the sender is on my whitelist: +
      +
    1. If I'm on vacation, send back automatic response. +
    2. Put the letter in inbox. +
    +
  7. If the subject includes password, put in special folder for + unknown people. +
  8. Otherwise, autoreply with request to use password and delete the mail. +
+ +

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. + +

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. + +

Problems

+ +

My approach has some problems: +

    +
  • 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. +
  • 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.) +
  • 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. +
  • 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. +
  • If the filter starts acting up, you'd better know Procmail, or be + prepared to drop it at once. +
+ +

Alternative methods

+ +

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. + +

    + +
  • Just delete them. +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. + +
  • Complain to sender or in public. +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 wrong. + +
  • Just filter away known baddies. +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. + +
  • Use a service that removes your address from spammers' lists. +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. + +
  • Use a munged mail address in public. +This causes postmasters (the people who keep the mail systems running) +extra work. Not polite, and counter-productive on the long run. + +
+ +

Related links

+ + +

Feedback

+ +

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. + +

(22 September 1997, +Lars Wirzenius) + + + diff --git a/libc/msdos/xxx/mailfilter2.tar.gz b/libc/msdos/xxx/mailfilter2.tar.gz new file mode 100644 index 0000000..233090d Binary files /dev/null and b/libc/msdos/xxx/mailfilter2.tar.gz differ diff --git a/libc/msdos/xxx/mips.com b/libc/msdos/xxx/mips.com new file mode 100644 index 0000000..66cc110 Binary files /dev/null and b/libc/msdos/xxx/mips.com differ diff --git a/libc/msdos/xxx/tryit.com b/libc/msdos/xxx/tryit.com new file mode 100644 index 0000000..71ff71b Binary files /dev/null and b/libc/msdos/xxx/tryit.com 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 #include +#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 ) </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 -- cgit v1.2.1