diff options
author | Robert de Bath <rdebath@poboxes.com> | 1996-03-24 17:45:55 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:29:43 +0200 |
commit | fe22c37817ce338fbbc90b239320248c270957fa (patch) | |
tree | d9550410c4a20bdd382fcc58d2d3d7c5e04e5245 | |
parent | a7aba15e8efffb1c5d3097656f1a93955a64f01f (diff) | |
parent | 42192453ea219b80d0bf9f41e51e36d3d4d0740b (diff) | |
download | dev86-fe22c37817ce338fbbc90b239320248c270957fa.tar.gz |
Import Dev86-0.0.4.tar.gzv0.0.4
500 files changed, 30843 insertions, 21781 deletions
diff --git a/Libc_version b/Libc_version new file mode 100644 index 0000000..81340c7 --- /dev/null +++ b/Libc_version @@ -0,0 +1 @@ +0.0.4 diff --git a/Make.defs b/Make.defs new file mode 100644 index 0000000..0297154 --- /dev/null +++ b/Make.defs @@ -0,0 +1,16 @@ + +# WALL =-Wall -Wtraditional -Wshadow -Wid-clash-14 -Wpointer-arith \ +# -Wcast-qual -Wcast-align -Wconversion -Waggregate-return \ +# -Wstrict-prototypes -Wmissing-prototypes -Wredundant-decls \ +# -Wnested-externs -Winline + +# unproto is yukky +WALL=-Wno-comment +CCFLAGS =-Wall $(WALL) -O2 -fno-strength-reduce +LDFLAGS =-s + +BCCHOME =/usr/bcc +LIBDIR =$(BCCHOME)/lib/bcc +BINDIR =/usr/bin +CC =gcc +CFLAGS =$(CCFLAGS) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b47ed39 --- /dev/null +++ b/Makefile @@ -0,0 +1,82 @@ + +export TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) + +include Make.defs + +PARTS= ld as unproto bcc +TESTDIRS= tests dis88 +DISTFILES=Makefile Make.defs README README.ash Libc_version +DISTDIRS= elksemu $(TESTDIRS) + +default: + @echo You have to do make install as root + @echo Or: + @echo + @echo 'make bcc' + @echo 'su -c "make install-bcc"' + @echo 'make library' + @echo 'su -c "make install-lib"' + @echo 'make elksemu' + @echo 'su -c "make install-emu"' + @echo 'make tests' + @echo + +install: install-bcc install-lib install-emu tests + +bcc: dummy + @for i in $(PARTS) ; do make -C $$i || exit 1; done + +clean: clean_rest + make -C libc realclean + +clean_rest: dummy + @for i in $(PARTS) ; do make -C $$i clean || exit 1; done + @for i in $(DISTDIRS) ; do make -C $$i clean || exit 1; done + +tests: dummy + @test -f $(BINDIR)/bcc -a -f $(LIBDIR)/ld86 || \ + ( echo 'Must do "make install-bcc" first' && exit 1 ) + @test -f $(LIBDIR)/i86/crt0.o || \ + ( echo 'Must do "make install-lib" first' && exit 1 ) + @for i in $(TESTDIRS) ; do make -C $$i || exit 1; done + +library: link_libc + @test -f $(BINDIR)/bcc -a -f $(LIBDIR)/ld86 || \ + ( echo 'Must do "make install-bcc" first' && exit 1 ) + make -C libc + +elksemu: dummy + @test -f libc/syscall/call_tab.v || \ + ( echo 'Must do "make library" first' && exit 1 ) + make -C elksemu + +install-bcc: dummy + @for i in $(PARTS) ; do make -C $$i install || exit 1; done + +install-lib: link_libc + @test -f $(BINDIR)/bcc -a -f $(LIBDIR)/ld86 || \ + ( echo 'Must do "make install-bcc" first' && exit 1 ) + make -C libc install + +install-emu: dummy + @test -f libc/syscall/call_tab.v || \ + ( echo 'Must do "make library" first' && exit 1 ) + make -C elksemu install + +link_libc: dummy + @if [ -f Libc_version ] ; then \ + rm -f libc ; ln -fs libc-`cat Libc_version` libc ; fi + +distribution: clean_rest + -rm -f libc + make -C libc dist_ver + tar xzf libc-8086-`cat Libc_version`.tar.gz + tar cf /tmp/Development.tar $(DISTFILES) $(PARTS) $(DISTDIRS) \ + libc-`cat Libc_version` + rm -rf libc-`cat Libc_version` Libc_version + rm -rf /tmp/linux-86 + mkdir /tmp/linux-86 + (cd /tmp/linux-86 ; tar xf ../Development.tar ; rm ../Development.tar) + (cd /tmp; tar czf Development.tar.gz linux-86 ; rm -rf linux-86) + +dummy: @@ -0,0 +1,31 @@ +This is a development environment for ELKS-86 + +You have to do make install as root +Or: + +$ make bcc +$ su -c "make install-bcc" +$ make library +$ su -c "make install-lib" +$ make elksemu +$ su -c "make install-emu" +$ make tests + +All from the top directory. +Once this is done new files will be /lib/elksemu, /usr/bcc/* and /usr/bin/bcc + +The bcc command defaults to using /usr/bcc/include and /usr/bcc/lib. Beware +that /usr/bcc/include is a symlink into this directory. + +The as86 and ld86 with this are _different_ from the ones needed for the +linux-i386 kernel but can replace them, the kernel-i386 ones _will_ _not_ +work correctly here! + +To compile the various tools as Linux-8086 binaries cd into the relevent +directory and do a "make clean ; make" from there, note you'll have to +do "ld" before "as". Currently bcc won't work this way. + +I _strongly_ suggest you install the kernel patch in the elksemu directory +in your Linux-i386 kernel, it makes things _far_ easier. + +-Rob. diff --git a/README.ash b/README.ash new file mode 100644 index 0000000..7c84985 --- /dev/null +++ b/README.ash @@ -0,0 +1,115 @@ +Building /bin/ash + +After doing make install for 'bcc' unpack ash-linux-0.2.tar.gz; within this +rename builtins to builtings.in then patch with this patchfile. + +You'll also need to turn on 'JOBS' on line 58 of shell.h when libc can +provide the functions. + +If you don't install the elksemu kernel patch you'll also have to make +sure that the programs that are run by the make file are interpreted +through elksemu. If it's installed you should be able just to type 'make'. + +diff -ru ash-linux-0.2/Makefile ash/Makefile +--- ash-linux-0.2/Makefile Sun May 15 20:16:13 1994 ++++ ash/Makefile Sat Mar 16 11:28:19 1996 +@@ -1,5 +1,9 @@ + # Makefile,v 1.7 1993/08/09 04:58:18 mycroft Exp + ++CC=bcc ++CFLAGS=-DSHELL ++LDFLAGS=-s ++ + PROG= sh + SRCS= builtins.c cd.c dirent.c echo.c error.c eval.c exec.c expand.c \ + input.c jobs.c mail.c main.c memalloc.c miscbltin.c \ +@@ -14,8 +18,8 @@ + + OBJS = $(OBJ1) $(OBJ2) + +-CFLAGS = -O2 -fomit-frame-pointer -m486 -DSHELL -I/usr/include/bsd -I. +-LDFLAGS = -s -lbsd ++# CFLAGS = -O2 -fomit-frame-pointer -m486 -DSHELL -I/usr/include/bsd -I. ++# LDFLAGS = -s -lbsd + + CLEANFILES =\ + builtins.c builtins.h init.c mkinit mknodes mksyntax \ +@@ -32,7 +36,7 @@ + token.def: mktokens + sh ./mktokens + +-builtins.h builtins.c: mkbuiltins builtins ++builtins.h builtins.c: mkbuiltins builtins.in + sh ./mkbuiltins + + init.c: mkinit $(SRCS) +Only in ash-linux-0.2: builtins +Only in ash: builtins.in +diff -ru ash-linux-0.2/main.c ash/main.c +--- ash-linux-0.2/main.c Mon Oct 4 19:47:56 1993 ++++ ash/main.c Sun Feb 18 21:57:59 1996 +@@ -321,9 +321,9 @@ + /* + * Should never be called. + */ +-#endif + + void + exit(exitstatus) { + _exit(exitstatus); + } ++#endif +diff -ru ash-linux-0.2/miscbltin.c ash/miscbltin.c +--- ash-linux-0.2/miscbltin.c Mon Oct 4 19:47:56 1993 ++++ ash/miscbltin.c Sun Feb 18 21:56:14 1996 +@@ -45,6 +45,7 @@ + + #include <sys/types.h> + #include <sys/stat.h> ++#include <ctype.h> + #include "shell.h" + #include "options.h" + #include "var.h" +@@ -208,14 +209,18 @@ + umask(mask); + } else { + #ifndef __linux__ ++#ifndef __BCC__ + void *set; + if ((set = setmode (ap)) == 0) + #endif ++#endif + error("Illegal number: %s", ap); + + #ifndef __linux__ ++#ifndef __BCC__ + mask = getmode (set, ~mask & 0777); + umask(~mask & 0777); ++#endif + #endif + } + } +diff -ru ash-linux-0.2/mkbuiltins ash/mkbuiltins +--- ash-linux-0.2/mkbuiltins Sun Apr 18 18:37:04 1993 ++++ ash/mkbuiltins Mon Feb 12 19:42:46 1996 +@@ -54,7 +54,7 @@ + #include "builtins.h" + + ! +-awk '/^[^#]/ {if('$havejobs' || $2 != "-j") print $0}' builtins | ++awk '/^[^#]/ {if('$havejobs' || $2 != "-j") print $0}' builtins.in | + sed 's/-j//' > $temp + awk '{ printf "int %s();\n", $1}' $temp + echo ' +diff -ru ash-linux-0.2/shell.h ash/shell.h +--- ash-linux-0.2/shell.h Mon Oct 4 19:47:56 1993 ++++ ash/shell.h Sat Mar 16 11:28:54 1996 +@@ -60,7 +60,7 @@ + #define DIRENT 1 + #define UDIR 0 + #define ATTY 0 +-#define BSD ++/* #define BSD */ + /* #define DEBUG */ + + #ifdef __STDC__ diff --git a/as/Makefile b/as/Makefile index d7468a9..a4c5456 100644 --- a/as/Makefile +++ b/as/Makefile @@ -1,14 +1,32 @@ -CFLAGS =-O -LDFLAGS = + +ifneq ($(TOPDIR),) +include $(TOPDIR)/Make.defs +else +CC=bcc +LDFLAGS=-s +endif OBJS =as.o assemble.o error.o express.o \ genbin.o genlist.o genobj.o gensym.o \ macro.o mops.o pops.o readsrc.o \ scan.o table.o typeconv.o -as: $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) -o as - chmem =182000 as +all: as86 + +as86: $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o as86 + +install: all + install -d $(LIBDIR) + install -m 755 as86 $(LIBDIR) + +typeconv.o: dummy + -cp -p ../ld/typeconv.o . + +dummy: + +clean: + rm -f *.o as86 as.o: const.h type.h byteord.h macro.h file.h flag.h globvar.h assemble.o: const.h type.h address.h globvar.h opcode.h scan.h @@ -25,3 +43,4 @@ pops.o: const.h type.h address.h flag.h globvar.h opcode.h scan.h readsrc.o: const.h type.h flag.h file.h globvar.h macro.h scan.h source.h scan.o: const.h type.h globvar.h scan.h table.o: const.h type.h globvar.h opcode.h scan.h + @@ -21,7 +21,6 @@ void *malloc P((unsigned size)); char *strcpy P((char *s1, const char *s2)); unsigned strlen P((const char *s)); #else -#undef NULL #include <stdlib.h> #include <string.h> #endif @@ -31,7 +30,6 @@ int close P((int fd)); int creat P((const char *path, int mode)); int write P((int fd, const void *buf, unsigned nbytes)); #else -#undef NULL #include <sys/types.h> #include <fcntl.h> #include <unistd.h> @@ -53,7 +51,9 @@ FORWARD void summary P((fd_t fd)); FORWARD void summ_number P((unsigned num)); FORWARD void usage P((void)); +#ifndef USERMEM #define USERMEM (sizeof(int) <= 2 ? (unsigned) 0xAC00 : (unsigned) 0x28000L) +#endif PUBLIC int main(argc, argv) int argc; @@ -146,7 +146,11 @@ char *message; { int fd; +#ifdef O_BINARY + if ((fd = open(name, O_RDWR|O_BINARY|O_CREAT|O_TRUNC, CREAT_PERMS)) < 0 || fd > 255) +#else if ((fd = creat(name, CREAT_PERMS)) < 0 || fd > 255) +#endif as_abort(message); return fd; } @@ -157,7 +161,7 @@ char **argv; { char *arg; bool_t isnextarg; - char *nextarg; + char *nextarg = 0; if (argc <= 1) usage(); diff --git a/as/assemble.c b/as/assemble.c index c438ce6..1fdef1a 100644 --- a/as/assemble.c +++ b/as/assemble.c @@ -155,7 +155,7 @@ PUBLIC void assemble() while (TRUE) { asline(); - if (label != NULL) /* must be confirmed if still set */ + if (label != NUL_PTR) /* must be confirmed if still set */ { /* it is nulled by EQU, COMM and SET */ #ifndef MC6809 #define NEEDENDLABEL ILLAB @@ -172,7 +172,7 @@ PUBLIC void assemble() if ((mcount | popflags) == 0) /* unaccompanied label, display adr like EQU and SET */ showlabel(); - label = NULL; /* reset for next line */ + label = NUL_PTR; /* reset for next line */ } skipline(); listline(); @@ -210,7 +210,7 @@ PRIVATE void asline() if (!ifflag) /* not assembling, just test for IF/ELSE/ELSEIF/ENDIF */ { - if (symptr == NULL || !(symptr->type & MNREGBIT) || + if (symptr == NUL_PTR || !(symptr->type & MNREGBIT) || symptr->data & REGBIT || symptr->value_reg_or_op.op.routine >= MIN_NONCOND) return; @@ -41,7 +41,7 @@ #define FORWARD static #define PRIVATE static #define PUBLIC -#define NULL 0 +#define NUL_PTR ((void*)0) /* O/S constants */ @@ -6,7 +6,6 @@ #ifdef STDC_HEADERS_MISSING char *strcpy P((char *s1, const char *s2)); #else -#undef NULL #include <string.h> #endif diff --git a/as/genlist.c b/as/genlist.c index e179fcf..eb3b277 100644 --- a/as/genlist.c +++ b/as/genlist.c @@ -14,14 +14,12 @@ void *memset P((void *s, int c, unsigned n)); unsigned strlen P((const char *s)); #else -#undef NULL #include <string.h> #endif #ifdef POSIX_HEADERS_MISSING int write P((int fd, const void *buf, unsigned nbytes)); #else -#undef NULL #include <sys/types.h> #include <unistd.h> #endif @@ -186,8 +184,8 @@ PUBLIC void listline() { if (!listpre) { - if (errcount || list.current && (!macflag || mcount != 0) || - macflag && maclist.current) + if (errcount || (list.current && (!macflag || mcount != 0)) || + (macflag && maclist.current)) list1(lstfil); if (errcount) { diff --git a/as/genobj.c b/as/genobj.c index 80b03ce..2992232 100644 --- a/as/genobj.c +++ b/as/genobj.c @@ -11,14 +11,12 @@ char *strcpy P((char *s1, const char *s2)); char *strrchr P((const char *s, int c)); unsigned strlen P((const char *s)); #else -#undef NULL #include <string.h> #endif #ifdef POSIX_HEADERS_MISSING int write P((int fd, const void *buf, unsigned nbytes)); #else -#undef NULL #include <sys/types.h> #include <unistd.h> #endif @@ -371,22 +369,22 @@ PUBLIC void objheader() /* build array of imported/exported symbols */ symosiz = 0; - if (truefilename == NULL) + if (truefilename == NUL_PTR) truefilename = filnamptr; nameptr = strrchr(truefilename, DIRCHAR); - strcpy(module_name, nameptr != NULL ? nameptr + 1 : truefilename); - if ((nameptr = strrchr(module_name, '.')) != NULL) + strcpy(module_name, nameptr != NUL_PTR ? nameptr + 1 : truefilename); + if ((nameptr = strrchr(module_name, '.')) != NUL_PTR) *nameptr = 0; strsiz = strlen(module_name) + 1; align(heapptr); for (hashptr = spt, arrext = copyptr = (struct sym_s **) heapptr; hashptr < spt_top;) - if ((symptr = *hashptr++) != NULL) + if ((symptr = *hashptr++) != NUL_PTR) do { if ((symptr->type & EXPBIT || symptr->data & IMPBIT) || - !globals_only_in_obj && symptr->name[0] != '.' && - !(symptr->type & (MNREGBIT | MACBIT | VARBIT))) + (!globals_only_in_obj && symptr->name[0] != '.' && + !(symptr->type & (MNREGBIT | MACBIT | VARBIT)))) { if (copyptr >= (struct sym_s **) heapend) { @@ -412,7 +410,7 @@ PUBLIC void objheader() ++numext; } } - while ((symptr = symptr->next) != NULL); + while ((symptr = symptr->next) != NUL_PTR); heapptr = (char *) (copytop = copyptr); /* calculate length of text, and number of seg size bytes in header */ diff --git a/as/gensym.c b/as/gensym.c index bc773db..c5c6d1b 100644 --- a/as/gensym.c +++ b/as/gensym.c @@ -10,14 +10,12 @@ void *memset P((void *s, int c, unsigned n)); int strcmp P((const char *s1, const char *s2)); #else -#undef NULL #include <string.h> #endif #ifdef POSIX_HEADERS_MISSING int write P((int fd, const void *buf, unsigned nbytes)); #else -#undef NULL #include <sys/types.h> #include <unistd.h> #endif @@ -51,7 +49,7 @@ PUBLIC void gensym() align(heapptr); for (hashptr = spt, symlptr = copyptr = (struct sym_s **) heapptr; hashptr < spt_top;) - if ((symptr = *hashptr++) != NULL) + if ((symptr = *hashptr++) != NUL_PTR) do if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT))) { @@ -66,7 +64,7 @@ PUBLIC void gensym() ++label_count; labels_length += symptr->length + 3; /* 3 for type, value */ } - while ((symptr = symptr->next) != NULL); + while ((symptr = symptr->next) != NUL_PTR); sort_symbols: sort(symlptr, copyptr, TRUE); /* sort on name */ @@ -11,7 +11,6 @@ #ifdef STDC_HEADERS_MISSING int strncmp P((const char *s1, const char *s2, unsigned n)); #else -#undef NULL #include <string.h> #endif @@ -39,7 +38,7 @@ struct sym_s *symptr; ++maclevel; (--macstak)->text = (char *) symptr->value_reg_or_op.value; macstak->parameters = param1 = macpar; - param1->next = NULL; + param1->next = NUL_PTR; *(stringptr = build_number(++macnum, 3, param1->string)) = 0; macpar = (struct schain_s *) (stringptr + 1); /* TODO: alignment */ @@ -70,7 +69,7 @@ struct sym_s *symptr; } *stringptr = 0; param1->next = macpar; /* ptr from previous */ - (param1 = macpar)->next = NULL; + (param1 = macpar)->next = NUL_PTR; /* this goes nowhere */ macpar = (struct schain_s *) (stringptr + 1); /* but is finished OK - TODO align */ @@ -95,12 +94,12 @@ PUBLIC void pmacro() { bool_t saving; bool_t savingc; - struct sym_s *symptr; + struct sym_s *symptr=0; saving = /* prepare for bad macro */ savingc = FALSE; /* normally don't save comments */ macload = TRUE; /* show loading */ - if (label != NULL) + if (label != NUL_PTR) error(ILLAB); else if (sym != IDENT) error(LABEXP); @@ -547,7 +547,7 @@ register struct ea_s *eap; mcount += asize; } else if (lastexp.offset != 0x0 || - eap->base == BPREG && eap->index == NOREG || + (eap->base == BPREG && eap->index == NOREG) || eap->base == EBPREG) { postb |= MEM1_MOD; @@ -917,8 +917,8 @@ register struct ea_s *eap; if (!(lastexp.data & UNDBIT) && lastexp.offset != 0x1) { if (eap->base <= MAX16BITINDREG || - lastexp.offset != 0x2 && lastexp.offset != 0x4 && - lastexp.offset != 0x8) + (lastexp.offset != 0x2 && lastexp.offset != 0x4 && + lastexp.offset != 0x8)) error(ILL_SCALE); else { @@ -1107,16 +1107,16 @@ PUBLIC void mbswap() PUBLIC void mcall() { - opcode_pt far; + opcode_pt far_diff; bool_t indirect; register struct sym_s *symptr; - far = 0x0; + far_diff = 0x0; if (sym == IDENT && (symptr = gsymptr)->type & MNREGBIT && symptr->data & SIZEBIT && symptr->value_reg_or_op.op.routine == FAROP) { - far = 0x8; + far_diff = 0x8; getsym(); } indirect = FALSE; @@ -1174,7 +1174,7 @@ PUBLIC void mcall() opcode = 0x20; else opcode = 0x10; - postb |= opcode + far; + postb |= opcode + far_diff; opcode = 0xFF; } } @@ -1589,9 +1589,9 @@ PUBLIC void mgroup1() { if (target.indcount == 0x0 && (target.base == ALREG || target.base == AXREG || - target.base == EAXREG && + (target.base == EAXREG && (source.displ.data & (FORBIT | RELBIT | UNDBIT) || - !is8bitsignedoffset(source.displ.offset)))) + !is8bitsignedoffset(source.displ.offset))))) { opcode |= 0x04 | segword; buildimm(&source, FALSE); @@ -72,7 +72,7 @@ PUBLIC bool_pt checksegrel(symptr) register struct sym_s *symptr; { if ((symptr->type & LABIT || - symptr->data & IMPBIT && !(symptr->data & UNDBIT)) && + (symptr->data & IMPBIT && !(symptr->data & UNDBIT))) && ((symptr->data ^ lcdata) & (RELBIT | SEGM))) { error(SEGREL); @@ -220,7 +220,7 @@ unsigned char impbits; while (TRUE) { - if ((symptr = needlabel()) != NULL) + if ((symptr = needlabel()) != NUL_PTR) { if (symptr->type & COMMBIT) error(ALREADY); @@ -428,7 +428,7 @@ error_pt errnum; lineptr = oldlineptr; sym = oldsym; symname = oldsymname; - label = NULL; + label = NUL_PTR; } PRIVATE struct sym_s *needlabel() @@ -439,7 +439,7 @@ PRIVATE struct sym_s *needlabel() (symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT)) { error(LABEXP); - return NULL; + return NUL_PTR; } return symptr; } @@ -506,7 +506,7 @@ PUBLIC void pbss() PUBLIC void pcomm() { - if (label == NULL) + if (label == NUL_PTR) labelerror(MISLAB); else if (label->type & VARBIT) labelerror(VARLAB); /* variable cannot be COMM'd */ @@ -520,11 +520,11 @@ PUBLIC void pcomm1() { unsigned oldseg; - if (label != NULL) + if (label != NUL_PTR) labelerror(ILLAB); oldseg = lcdata & SEGM; setloc(BSSLOC); - if ((label = needlabel()) != NULL && checksegrel(label)) + if ((label = needlabel()) != NUL_PTR && checksegrel(label)) { /* Like import. */ if (label->type & (EXPBIT | LABIT)) @@ -583,7 +583,7 @@ PUBLIC void pelsifc() PUBLIC void pendb() { - if (label != NULL) + if (label != NUL_PTR) labelerror(ILLAB); if (blocklevel == 0) error(ENDBBAD); @@ -645,7 +645,7 @@ PUBLIC void pequ() { register struct sym_s *labptr; - if ((labptr = label) == NULL) + if ((labptr = label) == NUL_PTR) labelerror(MISLAB); else if (labptr->type & COMMBIT) showredefinedlabel(); /* common cannot be EQU'd */ @@ -812,7 +812,7 @@ PUBLIC void pimport() error(NOIMPORT); while (TRUE) { - if ((symptr = needlabel()) != NULL && checksegrel(symptr)) + if ((symptr = needlabel()) != NUL_PTR && checksegrel(symptr)) { if (symptr->type & (COMMBIT | EXPBIT | LABIT)) /* IMPORT is null if label (to be) declared */ @@ -855,7 +855,7 @@ PUBLIC void plist() PUBLIC void ploc() { - if (label != NULL) + if (label != NUL_PTR) labelerror(ILLAB); absexpres(); if (!(lastexp.data & UNDBIT)) @@ -892,7 +892,7 @@ PUBLIC void pmap() PUBLIC void porg() { - if (label != NULL) + if (label != NUL_PTR) labelerror(ILLAB); absexpres(); if (!((lcdata = lastexp.data) & UNDBIT)) @@ -914,7 +914,7 @@ PUBLIC void prmb() PUBLIC void psect() { - if (label != NULL) + if (label != NUL_PTR) labelerror(ILLAB); while (sym == IDENT) { @@ -947,7 +947,7 @@ PUBLIC void pset() { register struct sym_s *labptr; - if ((labptr = label) == NULL) + if ((labptr = label) == NUL_PTR) labelerror(MISLAB); else if (labptr->type & COMMBIT) labelerror(RELAB); /* common cannot be SET'd */ @@ -1024,7 +1024,7 @@ PUBLIC void showlabel() lastexp.data = labptr->data; lastexp.offset = labptr->value_reg_or_op.value; popflags = POPLONG | POPHI | POPLO; - label = NULL; /* show handled by COMM, EQU or SET */ + label = NUL_PTR; /* show handled by COMM, EQU or SET */ } /* set location segment */ diff --git a/as/readsrc.c b/as/readsrc.c index 39bd063..f74db84 100644 --- a/as/readsrc.c +++ b/as/readsrc.c @@ -23,7 +23,6 @@ off_t lseek P((int fd, off_t offset, int whence)); int open P((const char *path, int oflag, ...)); int read P((int fd, void *buf, unsigned nbytes)); #else -#undef NULL #include <sys/types.h> #include <fcntl.h> #include <unistd.h> @@ -220,7 +219,7 @@ PUBLIC void readline() char *oldbufptr; struct schain_s *parameters; char paramnum; - unsigned char remaining; /* space remaining in line + 2 */ + unsigned int remaining; /* space remaining in line + 2 */ /* value 0 not used except for temp predec */ /* value 1 means error already gen */ /* values 1 and 2 mean no space */ @@ -244,9 +243,9 @@ PUBLIC void readline() { parameters = macstak->parameters; for (paramnum = *bufptr++; paramnum-- != '0';) - if ((parameters = parameters->next) == NULL) + if ((parameters = parameters->next) == NUL_PTR) break; - if (parameters != NULL) + if (parameters != NUL_PTR) { for (oldbufptr = bufptr, bufptr = parameters->string; *bufptr++ != 0;) @@ -9,7 +9,6 @@ #ifdef STDC_HEADERS_MISSING int memcmp P((const void *s1, const void *s2, unsigned n)); #else -#undef NULL #include <string.h> #endif @@ -809,7 +808,7 @@ unsigned char data; * If string is not found and ifflag is TRUE, string is added to table, with * type = 0 * data = inidata (RELBIT | UNDBIT, possibly with IMPBIT | SEGM) - * Returns pointer to symbol entry (NULL if not found and not installed) + * Returns pointer to symbol entry (NUL_PTR if not found and not installed) * unless symbol table overflows, when routine aborts. */ @@ -855,7 +854,7 @@ PUBLIC struct sym_s *lookup() nameptr = symname; if ((symptr = *(hashptr = spt + (hashval ^ (hconv(nameptr[0]) << 1)) % SPTSIZ)) - != NULL) + != NUL_PTR) { do { @@ -873,9 +872,9 @@ PUBLIC struct sym_s *lookup() if (memcmp(symptr->name, nameptr, length) == 0) return symptr; } - while ((symptr = symptr->next) != NULL); + while ((symptr = symptr->next) != NUL_PTR); - /* Calculate last non-NULL hash ptr. + /* Calculate last non-NUL_PTR hash ptr. * This is faster than keeping hashptr up to date in previous loop * since most lookups are successful and hash ptr is not needed. */ @@ -884,10 +883,10 @@ PUBLIC struct sym_s *lookup() symptr = *hashptr; hashptr = &symptr->next; } - while (symptr->next != NULL); + while (symptr->next != NUL_PTR); } if (!ifflag) - return NULL; + return NUL_PTR; align(heapptr); if (heapptr >= heapend) fatalerror(SYMOV); @@ -900,7 +899,7 @@ PUBLIC struct sym_s *lookup() symptr->type = 0; symptr->data = inidata; symptr->length = length; - symptr->value_reg_or_op.value = (unsigned) (symptr->next = NULL); + symptr->value_reg_or_op.value = (unsigned) (symptr->next = NUL_PTR); heapptr = symptr->name; do *heapptr++ = *nameptr++; @@ -917,7 +916,7 @@ unsigned hashval; register struct sym_s *symptr; printf("%04x ", hashval); - for (symptr = spt[hashval]; symptr != NULL; symptr = symptr->next) + for (symptr = spt[hashval]; symptr != NUL_PTR; symptr = symptr->next) printf("%s ", symptr->name); printf("\n"); } @@ -46,7 +46,7 @@ typedef unsigned long u32_T; struct sym_s { - struct sym_s *next; /* next symbol in hash chain (NULL if none) */ + struct sym_s *next; /* next symbol in hash chain (NUL_PTR if none) */ /* zero offset because it is accessed most */ unsigned char type; unsigned char data; /* flags valid for expressions as well as syms*/ diff --git a/bcc-bruce/Makefile b/bcc-bruce/Makefile deleted file mode 100644 index 6a507fe..0000000 --- a/bcc-bruce/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Build bcc -# - -all: bcc bcc-cc1 - -CFLAGS = -DLOCALPREFIX="\"/usr/local\"" -O2 - -SRCS =assign.c declare.c gencode.c label.c preserve.c type.c \ - bcc-cc1.c express.c genloads.c loadexp.c scan.c \ - exptree.c glogcode.c longop.c softop.c codefrag.c \ - floatop.c hardop.c output.c state.c debug.c function.c \ - input.c preproc.c table.c - -OBJS =assign.o declare.o gencode.o label.o preserve.o type.o \ - bcc-cc1.o express.o genloads.o loadexp.o scan.o \ - exptree.o glogcode.o longop.o softop.o codefrag.o \ - floatop.o hardop.o output.o state.o debug.o function.o \ - input.o preproc.o table.o - - -bcc: bcc.c - $(CC) $(CFLAGS) -o bcc bcc.c - -bcc-cc1: $(OBJS) - $(CC) $(CFLAGS) -o bcc-cc1 $(OBJS) - diff --git a/bcc-linux16.patch b/bcc-linux16.patch deleted file mode 100644 index 6fe0ad2..0000000 --- a/bcc-linux16.patch +++ /dev/null @@ -1,444 +0,0 @@ -diff -Nurd bcc-bruce/COPYING bcc-linux16/COPYING ---- bcc-bruce/COPYING Thu Jan 1 01:00:00 1970 -+++ bcc-linux16/COPYING Sun Mar 26 10:39:11 1995 -@@ -0,0 +1,339 @@ -+ GNU GENERAL PUBLIC LICENSE -+ Version 2, June 1991 -+ -+ Copyright (C) 1989, 1991 Free Software Foundation, Inc. -+ 675 Mass Ave, Cambridge, MA 02139, USA -+ Everyone is permitted to copy and distribute verbatim copies -+ of this license document, but changing it is not allowed. -+ -+ Preamble -+ -+ The licenses for most software are designed to take away your -+freedom to share and change it. By contrast, the GNU General Public -+License is intended to guarantee your freedom to share and change free -+software--to make sure the software is free for all its users. This -+General Public License applies to most of the Free Software -+Foundation's software and to any other program whose authors commit to -+using it. (Some other Free Software Foundation software is covered by -+the GNU Library General Public License instead.) You can apply it to -+your programs, too. -+ -+ When we speak of free software, we are referring to freedom, not -+price. Our General Public Licenses are designed to make sure that you -+have the freedom to distribute copies of free software (and charge for -+this service if you wish), that you receive source code or can get it -+if you want it, that you can change the software or use pieces of it -+in new free programs; and that you know you can do these things. -+ -+ To protect your rights, we need to make restrictions that forbid -+anyone to deny you these rights or to ask you to surrender the rights. -+These restrictions translate to certain responsibilities for you if you -+distribute copies of the software, or if you modify it. -+ -+ For example, if you distribute copies of such a program, whether -+gratis or for a fee, you must give the recipients all the rights that -+you have. You must make sure that they, too, receive or can get the -+source code. And you must show them these terms so they know their -+rights. -+ -+ We protect your rights with two steps: (1) copyright the software, and -+(2) offer you this license which gives you legal permission to copy, -+distribute and/or modify the software. -+ -+ Also, for each author's protection and ours, we want to make certain -+that everyone understands that there is no warranty for this free -+software. If the software is modified by someone else and passed on, we -+want its recipients to know that what they have is not the original, so -+that any problems introduced by others will not reflect on the original -+authors' reputations. -+ -+ Finally, any free program is threatened constantly by software -+patents. We wish to avoid the danger that redistributors of a free -+program will individually obtain patent licenses, in effect making the -+program proprietary. To prevent this, we have made it clear that any -+patent must be licensed for everyone's free use or not licensed at all. -+ -+ The precise terms and conditions for copying, distribution and -+modification follow. -+ -+ GNU GENERAL PUBLIC LICENSE -+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -+ -+ 0. This License applies to any program or other work which contains -+a notice placed by the copyright holder saying it may be distributed -+under the terms of this General Public License. The "Program", below, -+refers to any such program or work, and a "work based on the Program" -+means either the Program or any derivative work under copyright law: -+that is to say, a work containing the Program or a portion of it, -+either verbatim or with modifications and/or translated into another -+language. (Hereinafter, translation is included without limitation in -+the term "modification".) Each licensee is addressed as "you". -+ -+Activities other than copying, distribution and modification are not -+covered by this License; they are outside its scope. The act of -+running the Program is not restricted, and the output from the Program -+is covered only if its contents constitute a work based on the -+Program (independent of having been made by running the Program). -+Whether that is true depends on what the Program does. -+ -+ 1. You may copy and distribute verbatim copies of the Program's -+source code as you receive it, in any medium, provided that you -+conspicuously and appropriately publish on each copy an appropriate -+copyright notice and disclaimer of warranty; keep intact all the -+notices that refer to this License and to the absence of any warranty; -+and give any other recipients of the Program a copy of this License -+along with the Program. -+ -+You may charge a fee for the physical act of transferring a copy, and -+you may at your option offer warranty protection in exchange for a fee. -+ -+ 2. You may modify your copy or copies of the Program or any portion -+of it, thus forming a work based on the Program, and copy and -+distribute such modifications or work under the terms of Section 1 -+above, provided that you also meet all of these conditions: -+ -+ a) You must cause the modified files to carry prominent notices -+ stating that you changed the files and the date of any change. -+ -+ b) You must cause any work that you distribute or publish, that in -+ whole or in part contains or is derived from the Program or any -+ part thereof, to be licensed as a whole at no charge to all third -+ parties under the terms of this License. -+ -+ c) If the modified program normally reads commands interactively -+ when run, you must cause it, when started running for such -+ interactive use in the most ordinary way, to print or display an -+ announcement including an appropriate copyright notice and a -+ notice that there is no warranty (or else, saying that you provide -+ a warranty) and that users may redistribute the program under -+ these conditions, and telling the user how to view a copy of this -+ License. (Exception: if the Program itself is interactive but -+ does not normally print such an announcement, your work based on -+ the Program is not required to print an announcement.) -+ -+These requirements apply to the modified work as a whole. If -+identifiable sections of that work are not derived from the Program, -+and can be reasonably considered independent and separate works in -+themselves, then this License, and its terms, do not apply to those -+sections when you distribute them as separate works. But when you -+distribute the same sections as part of a whole which is a work based -+on the Program, the distribution of the whole must be on the terms of -+this License, whose permissions for other licensees extend to the -+entire whole, and thus to each and every part regardless of who wrote it. -+ -+Thus, it is not the intent of this section to claim rights or contest -+your rights to work written entirely by you; rather, the intent is to -+exercise the right to control the distribution of derivative or -+collective works based on the Program. -+ -+In addition, mere aggregation of another work not based on the Program -+with the Program (or with a work based on the Program) on a volume of -+a storage or distribution medium does not bring the other work under -+the scope of this License. -+ -+ 3. You may copy and distribute the Program (or a work based on it, -+under Section 2) in object code or executable form under the terms of -+Sections 1 and 2 above provided that you also do one of the following: -+ -+ a) Accompany it with the complete corresponding machine-readable -+ source code, which must be distributed under the terms of Sections -+ 1 and 2 above on a medium customarily used for software interchange; or, -+ -+ b) Accompany it with a written offer, valid for at least three -+ years, to give any third party, for a charge no more than your -+ cost of physically performing source distribution, a complete -+ machine-readable copy of the corresponding source code, to be -+ distributed under the terms of Sections 1 and 2 above on a medium -+ customarily used for software interchange; or, -+ -+ c) Accompany it with the information you received as to the offer -+ to distribute corresponding source code. (This alternative is -+ allowed only for noncommercial distribution and only if you -+ received the program in object code or executable form with such -+ an offer, in accord with Subsection b above.) -+ -+The source code for a work means the preferred form of the work for -+making modifications to it. For an executable work, complete source -+code means all the source code for all modules it contains, plus any -+associated interface definition files, plus the scripts used to -+control compilation and installation of the executable. However, as a -+special exception, the source code distributed need not include -+anything that is normally distributed (in either source or binary -+form) with the major components (compiler, kernel, and so on) of the -+operating system on which the executable runs, unless that component -+itself accompanies the executable. -+ -+If distribution of executable or object code is made by offering -+access to copy from a designated place, then offering equivalent -+access to copy the source code from the same place counts as -+distribution of the source code, even though third parties are not -+compelled to copy the source along with the object code. -+ -+ 4. You may not copy, modify, sublicense, or distribute the Program -+except as expressly provided under this License. Any attempt -+otherwise to copy, modify, sublicense or distribute the Program is -+void, and will automatically terminate your rights under this License. -+However, parties who have received copies, or rights, from you under -+this License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+ 5. You are not required to accept this License, since you have not -+signed it. However, nothing else grants you permission to modify or -+distribute the Program or its derivative works. These actions are -+prohibited by law if you do not accept this License. Therefore, by -+modifying or distributing the Program (or any work based on the -+Program), you indicate your acceptance of this License to do so, and -+all its terms and conditions for copying, distributing or modifying -+the Program or works based on it. -+ -+ 6. Each time you redistribute the Program (or any work based on the -+Program), the recipient automatically receives a license from the -+original licensor to copy, distribute or modify the Program subject to -+these terms and conditions. You may not impose any further -+restrictions on the recipients' exercise of the rights granted herein. -+You are not responsible for enforcing compliance by third parties to -+this License. -+ -+ 7. If, as a consequence of a court judgment or allegation of patent -+infringement or for any other reason (not limited to patent issues), -+conditions are imposed on you (whether by court order, agreement or -+otherwise) that contradict the conditions of this License, they do not -+excuse you from the conditions of this License. If you cannot -+distribute so as to satisfy simultaneously your obligations under this -+License and any other pertinent obligations, then as a consequence you -+may not distribute the Program at all. For example, if a patent -+license would not permit royalty-free redistribution of the Program by -+all those who receive copies directly or indirectly through you, then -+the only way you could satisfy both it and this License would be to -+refrain entirely from distribution of the Program. -+ -+If any portion of this section is held invalid or unenforceable under -+any particular circumstance, the balance of the section is intended to -+apply and the section as a whole is intended to apply in other -+circumstances. -+ -+It is not the purpose of this section to induce you to infringe any -+patents or other property right claims or to contest validity of any -+such claims; this section has the sole purpose of protecting the -+integrity of the free software distribution system, which is -+implemented by public license practices. Many people have made -+generous contributions to the wide range of software distributed -+through that system in reliance on consistent application of that -+system; it is up to the author/donor to decide if he or she is willing -+to distribute software through any other system and a licensee cannot -+impose that choice. -+ -+This section is intended to make thoroughly clear what is believed to -+be a consequence of the rest of this License. -+ -+ 8. If the distribution and/or use of the Program is restricted in -+certain countries either by patents or by copyrighted interfaces, the -+original copyright holder who places the Program under this License -+may add an explicit geographical distribution limitation excluding -+those countries, so that distribution is permitted only in or among -+countries not thus excluded. In such case, this License incorporates -+the limitation as if written in the body of this License. -+ -+ 9. The Free Software Foundation may publish revised and/or new versions -+of the General Public License from time to time. Such new versions will -+be similar in spirit to the present version, but may differ in detail to -+address new problems or concerns. -+ -+Each version is given a distinguishing version number. If the Program -+specifies a version number of this License which applies to it and "any -+later version", you have the option of following the terms and conditions -+either of that version or of any later version published by the Free -+Software Foundation. If the Program does not specify a version number of -+this License, you may choose any version ever published by the Free Software -+Foundation. -+ -+ 10. If you wish to incorporate parts of the Program into other free -+programs whose distribution conditions are different, write to the author -+to ask for permission. For software which is copyrighted by the Free -+Software Foundation, write to the Free Software Foundation; we sometimes -+make exceptions for this. Our decision will be guided by the two goals -+of preserving the free status of all derivatives of our free software and -+of promoting the sharing and reuse of software generally. -+ -+ NO WARRANTY -+ -+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -+REPAIR OR CORRECTION. -+ -+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -+POSSIBILITY OF SUCH DAMAGES. -+ -+ END OF TERMS AND CONDITIONS -+ -+ Appendix: How to Apply These Terms to Your New Programs -+ -+ If you develop a new program, and you want it to be of the greatest -+possible use to the public, the best way to achieve this is to make it -+free software which everyone can redistribute and change under these terms. -+ -+ To do so, attach the following notices to the program. It is safest -+to attach them to the start of each source file to most effectively -+convey the exclusion of warranty; and each file should have at least -+the "copyright" line and a pointer to where the full notice is found. -+ -+ <one line to give the program's name and a brief idea of what it does.> -+ Copyright (C) 19yy <name of author> -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ -+Also add information on how to contact you by electronic and paper mail. -+ -+If the program is interactive, make it output a short notice like this -+when it starts in an interactive mode: -+ -+ Gnomovision version 69, Copyright (C) 19yy name of author -+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. -+ This is free software, and you are welcome to redistribute it -+ under certain conditions; type `show c' for details. -+ -+The hypothetical commands `show w' and `show c' should show the appropriate -+parts of the General Public License. Of course, the commands you use may -+be called something other than `show w' and `show c'; they could even be -+mouse-clicks or menu items--whatever suits your program. -+ -+You should also get your employer (if you work as a programmer) or your -+school, if any, to sign a "copyright disclaimer" for the program, if -+necessary. Here is a sample; alter the names: -+ -+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program -+ `Gnomovision' (which makes passes at compilers) written by James Hacker. -+ -+ <signature of Ty Coon>, 1 April 1989 -+ Ty Coon, President of Vice -+ -+This General Public License does not permit incorporating your program into -+proprietary programs. If your program is a subroutine library, you may -+consider it more useful to permit linking proprietary applications with the -+library. If this is what you want to do, use the GNU Library General -+Public License instead of this License. -diff -Nurd bcc-bruce/Makefile bcc-linux16/Makefile ---- bcc-bruce/Makefile Tue Jul 25 19:27:02 1995 -+++ bcc-linux16/Makefile Mon Nov 6 23:06:11 1995 -@@ -1,27 +1,23 @@ --# --# Build bcc --# -- --all: bcc bcc-cc1 -- --CFLAGS = -DLOCALPREFIX="\"/usr/local\"" -O2 -+CFLAGS =-O2 -+LDFLAGS = -+CC = gcc - --SRCS =assign.c declare.c gencode.c label.c preserve.c type.c \ -- bcc-cc1.c express.c genloads.c loadexp.c scan.c \ -- exptree.c glogcode.c longop.c softop.c codefrag.c \ -- floatop.c hardop.c output.c state.c debug.c function.c \ -- input.c preproc.c table.c -+bcc: bcc.c -+ $(CC) $(CFLAGS) $(LDFLAGS) $@.c -o $@ - --OBJS =assign.o declare.o gencode.o label.o preserve.o type.o \ -- bcc-cc1.o express.o genloads.o loadexp.o scan.o \ -- exptree.o glogcode.o longop.o softop.o codefrag.o \ -- floatop.o hardop.o output.o state.o debug.o function.o \ -- input.o preproc.o table.o -+bcc09: bcc.c -+ $(CC) -DMC6809 $(CFLAGS) $(LDFLAGS) bcc.c -o $@ - -+ccc: bcc.c -+ $(CC) -DCCC $(CFLAGS) $(LDFLAGS) bcc.c -o $@ - --bcc: bcc.c -- $(CC) $(CFLAGS) -o bcc bcc.c -+SOURCES = bcc-cc1.c codefrag.c debug.c declare.c express.c exptree.c floatop.c \ -+ function.c gencode.c genloads.c glogcode.c hardop.c input.c label.c \ -+ loadexp.c longop.c output.c preproc.c preserve.c scan.c softop.c \ -+ state.c table.c type.c assign.c - --bcc-cc1: $(OBJS) -- $(CC) $(CFLAGS) -o bcc-cc1 $(OBJS) -+bcc-cc1: $(SOURCES) -+ $(CC) $(CFLAGS) $(LDFLAGS) $(SOURCES) -o bcc-cc1 - -+clean: -+ rm -f bcc bcc09 ccc -diff -Nurd bcc-bruce/README bcc-linux16/README ---- bcc-bruce/README Thu Jan 1 01:00:00 1970 -+++ bcc-linux16/README Mon Nov 6 23:07:46 1995 -@@ -0,0 +1,8 @@ -+ This is a source distribution of bcc designed for use with as86 and -+ld86 (part of the bin86 package). I have altered the Makefile so that bcc-cc1 -+can be made from the Makefile (it does not check for dependancies, so it can -+be slow. bcc and bcc-cc1 are both needed to build Linux/16. -+ -+ - Chad Page -+ page0588@sundance.sjsu.edu -+ -diff -Nurd bcc-bruce/VERSION bcc-linux16/VERSION ---- bcc-bruce/VERSION Thu Jan 1 01:00:00 1970 -+++ bcc-linux16/VERSION Sun Mar 26 10:48:18 1995 -@@ -0,0 +1 @@ -+1995 Mar 12 10:29 UTC -Binary files bcc-bruce/bcc and bcc-linux16/bcc differ -Binary files bcc-bruce/bcc-cc1 and bcc-linux16/bcc-cc1 differ -diff -Nurd bcc-bruce/bcc.c bcc-linux16/bcc.c ---- bcc-bruce/bcc.c Tue Jul 25 19:18:16 1995 -+++ bcc-linux16/bcc.c Mon Nov 6 23:05:59 1995 -@@ -32,15 +32,15 @@ - #define BCC86 - #define CC1 "bcc-cc1" - #define CC1_MINUS_O_BROKEN FALSE --#define CPP "bcc-cc1" /* normally a link to /usr/bin/bcc-cc1 */ -+#define CPP "bcc-cc1" /* normally a link to /usr/bin/bcc-cc1 */ - #define CPPFLAGS "-E" --#define CRT0 "crt0.o" -+#define CRT0 "ncrtso.o" - #define GCC "gcc" - #define LD "ld86" --#define STANDARD_CRT0_0_PREFIX LOCALPREFIX "/lib/bcc/i86/" --#define STANDARD_CRT0_3_PREFIX LOCALPREFIX "/lib/bcc/i386/" --#define STANDARD_EXEC_PREFIX LOCALPREFIX "/lib/bcc/" --#define STANDARD_EXEC_PREFIX_2 LOCALPREFIX "/bin/" -+#define STANDARD_CRT0_0_PREFIX "/usr/home/minix/lib/" -+#define STANDARD_CRT0_3_PREFIX "/usr/home/minix/lib/" -+#define STANDARD_EXEC_PREFIX "/usr/bin/" -+#define STANDARD_EXEC_PREFIX_2 "/usr/bin/" - - #ifdef CCC - #undef BCC86 -@@ -207,7 +207,7 @@ - addarg(&ldargs, "-i"); - #endif - #ifdef BAS86 -- addarg(&ldrargs, "-r"); -+ addarg(&ldrargs, "-r -0"); - #endif - - /* Pass 1 over argv to gather compile options. */ diff --git a/bcc-bruce/6809/const.h b/bcc/6809/const.h index 559680c..559680c 100644 --- a/bcc-bruce/6809/const.h +++ b/bcc/6809/const.h diff --git a/bcc/Makefile b/bcc/Makefile new file mode 100644 index 0000000..eec2f83 --- /dev/null +++ b/bcc/Makefile @@ -0,0 +1,43 @@ +# +# bcc Makefile +# $Id$ +# +BCCDEFS=-DLOCALPREFIX="\"/usr\"" -DDEFARCH=0 + +ifneq ($(TOPDIR),) +include $(TOPDIR)/Make.defs +BCCDEFS=-DLOCALPREFIX="\"$(BCCHOME)\"" -DDEFARCH=0 +else +CC=bcc +LDFLAGS=-s +endif + +OBJS = bcc-cc1.o codefrag.o debug.o declare.o express.o exptree.o floatop.o \ + function.o gencode.o genloads.o glogcode.o hardop.o input.o label.o \ + loadexp.o longop.o output.o preproc.o preserve.o scan.o softop.o \ + state.o table.o type.o assign.o + +all: bcc bcc-cc1 + +install: all + install -d $(LIBDIR) + install -m 755 bcc $(BINDIR)/bcc + install -m 755 bcc-cc1 $(LIBDIR)/bcc-cc1 + +bcc: bcc.o + $(CC) -ansi $(LDFLAGS) bcc.o -o $@ + +bcc.o: bcc.c + $(CC) -ansi $(CFLAGS) $(BCCDEFS) -c bcc.c + +bcc09: bcc.o + $(CC) -DMC6809 bcc.o $(LDFLAGS) -o $@ + +ccc: bcc.o + $(CC) -DCCC bcc.o $(LDFLAGS) -o $@ + +bcc-cc1: $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o bcc-cc1 + +clean: + rm -f bcc bcc-cc1 bcc09 ccc bcc.o $(OBJS) diff --git a/bcc-bruce/align.h b/bcc/align.h index 3c8971b..3c8971b 100644 --- a/bcc-bruce/align.h +++ b/bcc/align.h diff --git a/bcc-bruce/assign.c b/bcc/assign.c index 6814f64..ebbc1fc 100644 --- a/bcc-bruce/assign.c +++ b/bcc/assign.c @@ -26,23 +26,23 @@ struct symstruct *target; if (target->type->constructor & (ARRAY | FUNCTION) || target->flags == TEMP || target->flags == (LABELLED | STRING) || - target->indcount == 0 && target->flags != REGVAR) + (target->indcount == 0 && target->flags != REGVAR)) { bugerror("botched lvalue"); return; } if (source->storage != target->storage - || source->indcount != target->indcount - || source->level != target->level - || source->offset.offi != target->offset.offi /* kludge union cmp */ - || source->type != target->type - || (source->storage & (LOCAL | GLOBAL) - || source->level == OFFKLUDGELEVEL) - && ((source->flags ^ target->flags) & LABELLED - || source->flags & LABELLED - && source->name.label != target->name.label - || !(source->flags & LABELLED) - && strcmp(source->name.namep, target->name.namep) != 0)) + || source->indcount != target->indcount + || source->level != target->level + || source->offset.offi != target->offset.offi /* kludge union cmp */ + || source->type != target->type + || ((source->storage & (LOCAL | GLOBAL) + || source->level == OFFKLUDGELEVEL) + && ((source->flags ^ target->flags) & LABELLED + || (source->flags & LABELLED + && source->name.label != target->name.label) + || (!(source->flags & LABELLED) + && strcmp(source->name.namep, target->name.namep) != 0)))) { tscalar = target->type->scalar; if (tscalar & CHAR && source->storage == CONSTANT) @@ -210,7 +210,7 @@ struct symstruct *target; store_pt targreg; if (type->constructor & (ARRAY | FUNCTION) - || type->constructor & STRUCTU && target->type != type) + || (type->constructor & STRUCTU && target->type != type)) { bugerror("botched implicit cast"); return; @@ -262,7 +262,7 @@ struct symstruct *target; target->storage = BREG; } } - else if (newscalar & (SHORT | INT | LONG) && !(newscalar & DLONG) + else if ((newscalar & (SHORT | INT | LONG) && !(newscalar & DLONG)) || type->constructor & POINTER) { if (oldscalar & RSCALAR) diff --git a/bcc-bruce/bcc-cc1.c b/bcc/bcc-cc1.c index d6fece3..d6fece3 100644 --- a/bcc-bruce/bcc-cc1.c +++ b/bcc/bcc-cc1.c diff --git a/bcc-bruce/bcc.bugs b/bcc/bcc.bugs index 52f6958..52f6958 100644 --- a/bcc-bruce/bcc.bugs +++ b/bcc/bcc.bugs diff --git a/bcc-bruce/bcc.c b/bcc/bcc.c index bb89bf7..810cbcb 100644 --- a/bcc-bruce/bcc.c +++ b/bcc/bcc.c @@ -14,14 +14,12 @@ #define FALSE 0 #define FORWARD static -#ifndef NULL -#define NULL 0 -#endif +#define NUL_PTR ((void*)0) #define PRIVATE static #define PUBLIC #define TRUE 1 -#if __STDC__ +#ifdef __STDC__ #define P(x) x #else #define P(x) () @@ -37,10 +35,16 @@ #define CRT0 "crt0.o" #define GCC "gcc" #define LD "ld86" +#ifndef NO_ANSI_SUPPORT +#define UNPROTO "unproto" +#endif #define STANDARD_CRT0_0_PREFIX LOCALPREFIX "/lib/bcc/i86/" #define STANDARD_CRT0_3_PREFIX LOCALPREFIX "/lib/bcc/i386/" #define STANDARD_EXEC_PREFIX LOCALPREFIX "/lib/bcc/" #define STANDARD_EXEC_PREFIX_2 LOCALPREFIX "/bin/" +#define DEFAULT_INCLUDE "-I" LOCALPREFIX "/include" +#define DEFAULT_LIBDIR0 "-L" LOCALPREFIX "/lib/bcc/i86/" +#define DEFAULT_LIBDIR3 "-L" LOCALPREFIX "/lib/bcc/i386/" #ifdef CCC #undef BCC86 @@ -88,6 +92,9 @@ struct prefix_s PRIVATE struct arg_s asargs = { AS, }; PRIVATE struct arg_s ccargs = { CC1, CC1_MINUS_O_BROKEN, }; PRIVATE struct arg_s cppargs = { CPP, }; +#ifndef NO_ANSI_SUPPORT +PRIVATE struct arg_s unprotoargs = { UNPROTO, TRUE }; +#endif #ifdef STANDARD_CRT0_PREFIX PRIVATE struct prefix_s crt0_prefix = { STANDARD_CRT0_PREFIX, }; #endif @@ -108,7 +115,7 @@ PRIVATE struct arg_s tmpargs; /* = empty */ PRIVATE char *tmpdir; PRIVATE unsigned verbosity; /* = 0 */ -#ifndef DONT_REDECLARE_STDC_FUNCTIONS +#ifdef REDECLARE_STDC_FUNCTIONS void exit P((int status)); char *getenv P((const char *name)); void *malloc P((size_t size)); @@ -119,7 +126,7 @@ size_t strlen P((const char *s)); char *strrchr P((const char *s, int c)); #endif -#ifndef DONT_REDECLARE_POSIX_FUNCTIONS +#ifdef REDECLARE_POSIX_FUNCTIONS int access P((const char *path, int amode)); int execv P((const char *path, char * const *argv)); pid_t fork P((void)); @@ -157,15 +164,24 @@ int argc; char **argv; { char *arg; + int add_default_inc = 1; + int add_default_lib = 1; int argcount = argc; bool_T *argdone = my_malloc((unsigned) argc * sizeof *argdone, "argdone"); bool_T as_only = FALSE; char *basename; #ifdef BCC86 +#ifdef DEFARCH + bool_T bits32 = (DEFARCH != 0); +#else bool_T bits32 = sizeof (char *) >= 4; +#endif char *bits_arg; #endif bool_T cc_only = FALSE; +#ifndef NO_ANSI_SUPPORT + bool_T ansi_pass = FALSE; +#endif #ifdef CCC bool_T cpp_pass = TRUE; #else @@ -178,7 +194,7 @@ char **argv; bool_T echo = FALSE; unsigned errcount = 0; char ext; - char *f_out = NULL; + char *f_out = NUL_PTR; bool_T float_emulation = FALSE; #ifdef BAS86 bool_T gnu_objects = FALSE; @@ -269,7 +285,7 @@ char **argv; } else { - if (f_out != NULL) + if (f_out != NUL_PTR) show_who("more than one output file\n"); f_out = *++argv; *++argdone = TRUE; @@ -283,6 +299,12 @@ char **argv; case 'v': ++verbosity; break; + case 'I': + add_default_inc = 0; + break; + case 'L': + add_default_lib = 0; + break; default: *argdone = FALSE; break; @@ -290,6 +312,20 @@ char **argv; else if (arg[0] == '-') switch (arg[1]) { +#ifndef NO_ANSI_SUPPORT + case 'a': + if (!strcmp(arg, "-ansi")) + { + ansi_pass=TRUE; + cpp_pass=TRUE; +#ifndef CCC + /* NOTE I'm setting this to zero, this isn't a _real_ STDC */ + addarg(&ccargs, "-D__STDC__=0"); +#endif + addarg(&cppargs, "-D__STDC__=0"); +#endif + } + break; case 'A': addarg(&asargs, arg + 2); break; @@ -307,17 +343,18 @@ char **argv; #endif addarg(&cppargs, arg); break; - case 'L': + case 'X': addarg(&ldargs, arg + 2); break; + case 'L': + addarg(&ldargs, arg); + break; case 'P': addarg(&cppargs, arg + 2); break; -#ifdef CCC case 'Q': addarg(&ccargs, arg); break; -#endif case 'T': tmpdir = arg + 2; break; @@ -348,7 +385,7 @@ char **argv; ++errcount; show_who("more than 1 option from -E -P -S -c\n"); } - if (f_out != NULL && ncisfiles > 1) + if (f_out != NUL_PTR && ncisfiles > 1) { ++errcount; show_who("cannot have more than 1 input with non-linked output\n"); @@ -362,8 +399,24 @@ char **argv; if (errcount != 0) exit(1); - if ((temp = getenv("BCC_EXEC_PREFIX")) != NULL) + if ((temp = getenv("BCC_EXEC_PREFIX")) != NUL_PTR) addprefix(&exec_prefix, temp); + if( add_default_inc ) + { +#ifndef CCC + addarg(&ccargs, DEFAULT_INCLUDE); +#endif + addarg(&cppargs, DEFAULT_INCLUDE); + } + if( add_default_lib ) + { +#ifdef BCC86 + if( bits32 ) + addarg(&ldargs, DEFAULT_LIBDIR3); + else +#endif + addarg(&ldargs, DEFAULT_LIBDIR0); + } addprefix(&exec_prefix, STANDARD_EXEC_PREFIX); addprefix(&exec_prefix, STANDARD_EXEC_PREFIX_2); cppargs.prog = fixpath(cppargs.prog, &exec_prefix, X_OK); @@ -371,7 +424,10 @@ char **argv; asargs.prog = fixpath(asargs.prog, &exec_prefix, X_OK); ldargs.prog = fixpath(ldargs.prog, &exec_prefix, X_OK); ldrargs.prog = fixpath(ldrargs.prog, &exec_prefix, X_OK); - if (tmpdir == NULL && (tmpdir = getenv("TMPDIR")) == NULL) +#ifndef NO_ANSI_SUPPORT + unprotoargs.prog=fixpath(unprotoargs.prog, &exec_prefix, X_OK); +#endif + if (tmpdir == NUL_PTR && (tmpdir = getenv("TMPDIR")) == NUL_PTR) tmpdir = "/tmp"; if (prep_only && !prep_line_numbers) @@ -395,7 +451,8 @@ char **argv; { addarg(&ldargs, bits_arg); addarg(&ldrargs, bits_arg); - addarg(&ldargs, crt0); + /* addarg(&ldargs, crt0);*/ + addarg(&ldargs, "-C0"); } #endif /* BAS86 */ #endif /* BCC86 */ @@ -423,7 +480,7 @@ char **argv; writes(arg); writesn(":"); } - if ((basename = strrchr(arg, DIRCHAR)) == NULL) + if ((basename = strrchr(arg, DIRCHAR)) == NUL_PTR) basename = arg; else ++basename; @@ -432,13 +489,30 @@ char **argv; { if (cpp_pass) { +#ifndef NO_ANSI_SUPPORT + if (prep_only && !ansi_pass) +#else if (prep_only) +#endif out_name = f_out; else out_name = my_mktemp(); if (run(in_name, out_name, &cppargs) != 0) continue; in_name = out_name; +#ifndef NO_ANSI_SUPPORT + if (ansi_pass) + { + if (prep_only) + out_name = f_out; + else + out_name = my_mktemp(); + + if (run(in_name, out_name, &unprotoargs) != 0) + continue; + in_name=out_name; + } +#endif } ext = 'i'; } @@ -448,7 +522,7 @@ char **argv; continue; if (cc_only) { - if (f_out != NULL) + if (f_out != NUL_PTR) out_name = f_out; else { @@ -469,7 +543,7 @@ char **argv; out_name = f_out; else if (cc_only) { - if (f_out != NULL) + if (f_out != NUL_PTR) out_name = f_out; else { @@ -492,7 +566,7 @@ char **argv; out_name[strlen(out_name) - 1] = 'o'; if (as_only) { - if (f_out != NULL) + if (f_out != NUL_PTR) out_name = f_out; else { @@ -543,7 +617,7 @@ char **argv; if (!prep_only && !cc_only && !as_only && !runerror) { - if (f_out == NULL) + if (f_out == NUL_PTR) f_out = "a.out"; #ifdef BAS86 if (gnu_objects) @@ -553,23 +627,23 @@ char **argv; { arg = ldargs.argv[argc]; if (arg[0] == '-' && arg[1] == 'i' - && (arg[2] == 0 || arg[2] == '-' && arg[3] == 0)) + && (arg[2] == 0 || (arg[2] == '-' && arg[3] == 0))) { --ldargs.argc; memmove(ldargs.argv + argc, ldargs.argv + argc + 1, (ldargs.argc - argc) * sizeof ldargs.argv[0]); - ldargs.argv[ldargs.argc] = NULL; + ldargs.argv[ldargs.argc] = NUL_PTR; } } ldargs.prog = fixpath(GCC, &exec_prefix, X_OK); - run((char *) NULL, f_out, &ldargs); + run((char *) NUL_PTR, f_out, &ldargs); } else #endif { addarg(&ldargs, "-lc"); - run((char *) NULL, f_out, &ldargs); + run((char *) NUL_PTR, f_out, &ldargs); } } killtemps(); @@ -590,12 +664,12 @@ char *arg; { argp->nr_allocated += ALLOC_UNIT; new_argv = realloc(argp->argv, argp->nr_allocated * sizeof *argp->argv); - if (new_argv == NULL) + if (new_argv == NUL_PTR) outofmemory("addarg"); argp->argv = new_argv; } argp->argv[argp->argc] = arg; - argp->argv[argp->argc = new_argc] = NULL; + argp->argv[argp->argc = new_argc] = NUL_PTR; } PRIVATE void addprefix(prefix, name) @@ -604,14 +678,14 @@ char *name; { struct prefix_s *new_prefix; - if (prefix->name == NULL) + if (prefix->name == NUL_PTR) prefix->name = name; else { new_prefix = my_malloc(sizeof *new_prefix, "addprefix"); new_prefix->name = name; - new_prefix->next = NULL; - while (prefix->next != NULL) + new_prefix->next = NUL_PTR; + while (prefix->next != NUL_PTR) prefix = prefix->next; prefix->next = new_prefix; } @@ -632,7 +706,7 @@ int mode; { char *ppath; - for (; prefix != NULL; prefix = prefix->next) + for (; prefix != NUL_PTR; prefix = prefix->next) { if (verbosity > 2) { @@ -665,7 +739,7 @@ char *where; { void *block; - if ((block = malloc(size)) == NULL) + if ((block = malloc(size)) == NUL_PTR) outofmemory(where); return block; } @@ -680,6 +754,7 @@ PRIVATE char *my_mktemp() p = template = stralloc2(tmpdir, "/bccYYYYXXXX"); p += strlen(p); + digits = getpid(); while (*--p == 'X') { @@ -733,9 +808,9 @@ struct arg_s *argp; int status; arg0 = 0; - if (in_name == NULL) + if (in_name == NUL_PTR) ++arg0; - if (out_name == NULL) + if (out_name == NUL_PTR) arg0 += 2; else if (argp->minus_O_broken) ++arg0; @@ -743,9 +818,9 @@ struct arg_s *argp; startarg(argp); argp->argv[arg0] = argp->prog; i = arg0 + 1; - if (in_name != NULL) + if (in_name != NUL_PTR) argp->argv[i++] = in_name; - if (out_name != NULL) + if (out_name != NUL_PTR) { if (!argp->minus_O_broken) argp->argv[i++] = "-o"; @@ -779,7 +854,7 @@ struct arg_s *argp; --tmpargs.argc; memmove(tmpargs.argv + i, tmpargs.argv + i + 1, (tmpargs.argc - i) * sizeof tmpargs.argv[0]); - tmpargs.argv[tmpargs.argc] = NULL; + tmpargs.argv[tmpargs.argc] = NUL_PTR; break; } if (status != 0) @@ -793,17 +868,28 @@ struct arg_s *argp; PRIVATE void set_trap() { - int signum; +#ifndef NORDB +#ifdef SIGINT + signal(SIGINT, trap); +#endif +#ifdef SIGQUIT + signal(SIGQUIT, trap); +#endif +#else + /* This is being too trap happy! */ #ifndef _NSIG #define _NSIG NSIG #endif + int signum; + for (signum = 0; signum <= _NSIG; ++signum) #ifdef SIGCHLD if (signum != SIGCHLD) #endif if (signal(signum, SIG_IGN) != SIG_IGN) signal(signum, trap); +#endif } PRIVATE void show_who(message) @@ -820,7 +906,7 @@ struct arg_s *argp; argp->argv = my_malloc((argp->nr_allocated = ALLOC_UNIT) * sizeof *argp->argv, "startarg"); argp->argc = START_ARGS; - argp->argv[START_ARGS] = NULL; + argp->argv[START_ARGS] = NUL_PTR; } PRIVATE char *stralloc(s) diff --git a/bin86-0.3/bcc/bcc.c b/bcc/bcc.c.gnu index 58035c8..8491c97 100644 --- a/bin86-0.3/bcc/bcc.c +++ b/bcc/bcc.c.gnu @@ -1,10 +1,6 @@ -/* - * bin86/bcc/bcc.c - * - * Copyright (C) 1992 Bruce Evans - */ +/* bcc.c - driver for Bruce's C compiler (bcc) and for CvW's C compiler */ -/* bcc.c - driver for Bruce's C compiler and for CvW's C compiler */ +/* Copyright (C) 1992 Bruce Evans */ #define _POSIX_SOURCE 1 @@ -18,32 +14,38 @@ #define FALSE 0 #define FORWARD static -#ifndef NULL -#define NULL 0 -#endif +#define NUL_PTR ((void*)0) #define PRIVATE static #define PUBLIC #define TRUE 1 -#if __STDC__ +#ifdef __STDC__ #define P(x) x #else #define P(x) () #endif -#define AS "as" +#define AS "as86" #define BAS86 #define BCC86 -#define CC1 "cc1" +#define CC1 "bcc-cc1" #define CC1_MINUS_O_BROKEN FALSE -#define CPP "cc1" +#define CPP "bcc-cc1" /* normally a link to /usr/bin/bcc-cc1 */ #define CPPFLAGS "-E" -#define CRTSO "crtso.o" -#define GCC "/usr/bin/gcc" -#define LD "ld" -#define STANDARD_CRTSO0_PREFIX "/usr/local/lib/i86/" -#define STANDARD_CRTSO3_PREFIX "/usr/local/lib/i386/" -#define STANDARD_EXEC_PREFIX "/usr/local/libexec/i386/bcc/" +#define CRT0 "crt0.o" +#define GCC "gcc" +#define LD "ld86" +#ifdef ANSI_SUPPORT +#define UNPROTO "unprotoize" +#define CP "/bin/cp" +#endif +#define STANDARD_CRT0_0_PREFIX LOCALPREFIX "/lib/bcc/i86/" +#define STANDARD_CRT0_3_PREFIX LOCALPREFIX "/lib/bcc/i386/" +#define STANDARD_EXEC_PREFIX LOCALPREFIX "/lib/bcc/" +#define STANDARD_EXEC_PREFIX_2 LOCALPREFIX "/bin/" +#define DEFAULT_INCLUDE "-I" LOCALPREFIX "/include" +#define DEFAULT_LIBDIR0 "-L" LOCALPREFIX "/lib/bcc/i86/" +#define DEFAULT_LIBDIR3 "-L" LOCALPREFIX "/lib/bcc/i386/" #ifdef CCC #undef BCC86 @@ -51,24 +53,18 @@ #define CC1 "c386" #undef CC1_MINUS_O_BROKEN #define CC1_MINUS_O_BROKEN TRUE -#undef CPP -#define CPP "cpp" /* could also use bcc-cc1 -E */ -#undef CPPFLAGS -#define CPPFLAGS "-traditional" -#undef GCC -#undef STANDARD_CRTSO0_PREFIX -#undef STANDARD_CRTSO3_PREFIX -#define STANDARD_CRTSO_PREFIX "/usr/local/lib/i386/" -#define STANDARD_EXEC_PREFIX_2 "/usr/local/bin/" +#undef STANDARD_CRT0_0_PREFIX +#undef STANDARD_CRT0_3_PREFIX +#define STANDARD_CRT0_PREFIX "/usr/local/lib/i386/" #endif /* CCC */ #ifdef MC6809 #undef BAS86 #undef BCC86 -#undef CRTSO +#undef CRT0 #undef GCC -#undef STANDARD_CRTSO0_PREFIX -#undef STANDARD_CRTSO3_PREFIX +#undef STANDARD_CRT0_0_PREFIX +#undef STANDARD_CRT0_3_PREFIX #undef STANDARD_EXEC_PREFIX #define STANDARD_EXEC_PREFIX "/usr/local/libexec/m09/bcc/" #endif /* MC6809 */ @@ -97,14 +93,17 @@ struct prefix_s PRIVATE struct arg_s asargs = { AS, }; PRIVATE struct arg_s ccargs = { CC1, CC1_MINUS_O_BROKEN, }; PRIVATE struct arg_s cppargs = { CPP, }; -#ifdef STANDARD_CRTSO_PREFIX -PRIVATE struct prefix_s crtso_prefix = { STANDARD_CRTSO_PREFIX, }; +#ifdef ANSI_SUPPORT +PRIVATE struct arg_s unprotoargs = { UNPROTO, }; #endif -#ifdef STANDARD_CRTSO0_PREFIX -PRIVATE struct prefix_s crtso0_prefix = { STANDARD_CRTSO0_PREFIX, }; +#ifdef STANDARD_CRT0_PREFIX +PRIVATE struct prefix_s crt0_prefix = { STANDARD_CRT0_PREFIX, }; #endif -#ifdef STANDARD_CRTSO3_PREFIX -PRIVATE struct prefix_s crtso3_prefix = { STANDARD_CRTSO3_PREFIX, }; +#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, }; @@ -115,24 +114,30 @@ PRIVATE char *progname; PRIVATE bool_T runerror; /* = FALSE */ PRIVATE struct arg_s tmpargs; /* = empty */ PRIVATE char *tmpdir; -PRIVATE bool_T verbose; /* = FALSE */ +PRIVATE unsigned verbosity; /* = 0 */ -/* Who can say if the standard headers declared these? */ -int chmod P((const char *name, int mode)); -int execv P((char *name, char **argv)); +#ifndef DONT_REDECLARE_STDC_FUNCTIONS void exit P((int status)); -pid_t fork P((void)); -char *getenv P((const char *_name)); -pid_t getpid P((void)); -void *malloc P((unsigned size)); -void *realloc P((void *ptr, unsigned size)); +char *getenv P((const char *name)); +void *malloc P((size_t size)); +void *realloc P((void *ptr, size_t size)); void (*signal P((int sig, void (*func) P((int sig))))) P((int sig)); -char *strcpy P((char *target, const char *source)); +char *strcpy P((char *dest, const char *src)); size_t strlen P((const char *s)); char *strrchr P((const char *s, int c)); -int unlink P((const char *name)); +#endif + +#ifndef DONT_REDECLARE_POSIX_FUNCTIONS +int access P((const char *path, int amode)); +int execv P((const char *path, char * const *argv)); +pid_t fork P((void)); +pid_t getpid P((void)); +int unlink P((const char *path)); pid_t wait P((int *status)); -int write P((int fd, char *buf, unsigned nbytes)); +ssize_t write P((int fd, const void *buf, size_t nbytes)); +#endif + +int main P((int argc, char **argv)); FORWARD void addarg P((struct arg_s *argp, char *arg)); FORWARD void addprefix P((struct prefix_s *prefix, char *name)); @@ -140,7 +145,7 @@ FORWARD void fatal P((char *message)); FORWARD char *fixpath P((char *path, struct prefix_s *prefix, int mode)); FORWARD void killtemps P((void)); FORWARD void *my_malloc P((unsigned size, char *where)); -FORWARD char *my_mktemp P((void)); +FORWARD char *my_mktemp P((int c_extension)); FORWARD void my_unlink P((char *name)); FORWARD void outofmemory P((char *where)); FORWARD int run P((char *in_name, char *out_name, struct arg_s *argp)); @@ -160,28 +165,38 @@ int argc; char **argv; { char *arg; + int add_default_inc = 1; + int add_default_lib = 1; int argcount = argc; bool_T *argdone = my_malloc((unsigned) argc * sizeof *argdone, "argdone"); bool_T as_only = FALSE; char *basename; #ifdef BCC86 +#ifdef DEFARCH + bool_T bits32 = (DEFARCH != 0); +#else bool_T bits32 = sizeof (char *) >= 4; +#endif char *bits_arg; #endif bool_T cc_only = FALSE; +#ifdef ANSI_SUPPORT + bool_T ansi_pass = FALSE; + bool_T quiet_ansi = TRUE; +#endif #ifdef CCC bool_T cpp_pass = TRUE; #else bool_T cpp_pass = FALSE; #endif #ifdef BCC86 - char *crtso; + char *crt0; #endif bool_T debug = FALSE; bool_T echo = FALSE; unsigned errcount = 0; char ext; - char *f_out = NULL; + char *f_out = NUL_PTR; bool_T float_emulation = FALSE; #ifdef BAS86 bool_T gnu_objects = FALSE; @@ -213,7 +228,7 @@ char **argv; addarg(&ldrargs, "-r"); #endif - /* pass 1 over argv to gather compile options */ + /* Pass 1 over argv to gather compile options. */ for (; --argc != 0;) { arg = *++argv; @@ -272,7 +287,7 @@ char **argv; } else { - if (f_out != NULL) + if (f_out != NUL_PTR) show_who("more than one output file\n"); f_out = *++argv; *++argdone = TRUE; @@ -284,7 +299,16 @@ char **argv; unsupported(arg, "profile"); break; case 'v': - verbose = TRUE; + ++verbosity; +#ifdef ANSI_SUPPORT + quiet_ansi=FALSE; +#endif + break; + case 'I': + add_default_inc = 0; + break; + case 'L': + add_default_lib = 0; break; default: *argdone = FALSE; @@ -293,6 +317,20 @@ char **argv; else if (arg[0] == '-') switch (arg[1]) { +#ifdef ANSI_SUPPORT + case 'a': + if (!strcmp(arg, "-ansi")) + { + ansi_pass=TRUE; +#if 0 +#ifndef CCC + addarg(&ccargs, "-D__STDC__=1"); +#endif + addarg(&cppargs, "-D__STDC__=1"); +#endif + } + break; +#endif case 'A': addarg(&asargs, arg + 2); break; @@ -310,9 +348,12 @@ char **argv; #endif addarg(&cppargs, arg); break; - case 'L': + case 'X': addarg(&ldargs, arg + 2); break; + case 'L': + addarg(&ldargs, arg); + break; case 'P': addarg(&cppargs, arg + 2); break; @@ -337,8 +378,9 @@ char **argv; ++nifiles; *argdone = FALSE; length = strlen(arg); - if (length >= 2 && arg[length - 2] == '.' && - ((ext = arg[length - 1]) == 'c' || ext == 'i' || ext == 's')) + if (length >= 2 && arg[length - 2] == '.' + && ((ext = arg[length - 1]) == 'c' || ext == 'i' || ext == 'S' + || ext == 's')) ++ncisfiles; } } @@ -350,7 +392,7 @@ char **argv; ++errcount; show_who("more than 1 option from -E -P -S -c\n"); } - if (f_out != NULL && ncisfiles > 1) + if (f_out != NUL_PTR && ncisfiles > 1) { ++errcount; show_who("cannot have more than 1 input with non-linked output\n"); @@ -364,18 +406,35 @@ char **argv; if (errcount != 0) exit(1); - if ((temp = getenv("BCC_EXEC_PREFIX")) != NULL) + if ((temp = getenv("BCC_EXEC_PREFIX")) != NUL_PTR) addprefix(&exec_prefix, temp); + if( add_default_inc ) + { +#ifndef CCC + addarg(&ccargs, DEFAULT_INCLUDE); +#endif + addarg(&cppargs, DEFAULT_INCLUDE); + } + if( add_default_lib ) + { +#ifdef BCC86 + if( bits32 ) + addarg(&ldargs, DEFAULT_LIBDIR3); + else +#endif + addarg(&ldargs, DEFAULT_LIBDIR0); + } addprefix(&exec_prefix, STANDARD_EXEC_PREFIX); -#ifdef STANDARD_EXEC_PREFIX_2 addprefix(&exec_prefix, STANDARD_EXEC_PREFIX_2); -#endif cppargs.prog = fixpath(cppargs.prog, &exec_prefix, X_OK); ccargs.prog = fixpath(ccargs.prog, &exec_prefix, X_OK); asargs.prog = fixpath(asargs.prog, &exec_prefix, X_OK); ldargs.prog = fixpath(ldargs.prog, &exec_prefix, X_OK); ldrargs.prog = fixpath(ldrargs.prog, &exec_prefix, X_OK); - if (tmpdir == NULL && (tmpdir = getenv("TMPDIR")) == NULL) +#ifdef ANSI_SUPPORT + unprotoargs.prog=fixpath(unprotoargs.prog, &exec_prefix, X_OK); +#endif + if (tmpdir == NUL_PTR && (tmpdir = getenv("TMPDIR")) == NUL_PTR) tmpdir = "/tmp"; if (prep_only && !prep_line_numbers) @@ -384,12 +443,12 @@ char **argv; if (bits32) { bits_arg = "-3"; - crtso = fixpath(CRTSO, &crtso3_prefix, R_OK); + crt0 = fixpath(CRT0, &crt0_3_prefix, R_OK); } else { bits_arg = "-0"; - crtso = fixpath(CRTSO, &crtso0_prefix, R_OK); + crt0 = fixpath(CRT0, &crt0_0_prefix, R_OK); } addarg(&ccargs, bits_arg); addarg(&cppargs, bits_arg); @@ -399,47 +458,71 @@ char **argv; { addarg(&ldargs, bits_arg); addarg(&ldrargs, bits_arg); - addarg(&ldargs, crtso); + /* addarg(&ldargs, crt0);*/ + addarg(&ldargs, "-C0"); } #endif /* BAS86 */ #endif /* BCC86 */ #if defined(BAS86) && !defined(BCC86) if (!gnu_objects) - addarg(&ldargs, fixpath(CRTSO, &crtso_prefix, R_OK)); + addarg(&ldargs, fixpath(CRT0, &crt0_prefix, R_OK)); #endif - if (ncisfiles < 2) - echo = FALSE; set_trap(); - /* pass 2 over argv to compile and assemble .c and .s files */ - /* and gather arguments for loader */ + /* Pass 2 over argv to compile and assemble .c, .i, .S and .s files and + * gather arguments for linker. + */ for (argv -= (argc = argcount) - 1, argdone -= argcount - 1; --argc != 0;) { arg = *++argv; if (!*++argdone) { length = strlen(arg); - if (length >= 2 && arg[length - 2] == '.' && - ((ext = arg[length - 1]) == 'c' || ext == 'i' || ext == 's')) + if (length >= 2 && arg[length - 2] == '.' + && ((ext = arg[length - 1]) == 'c' || ext == 'i' || ext == 'S' + || ext == 's')) { - if (echo || verbose) + if (echo || verbosity != 0) { writes(arg); writesn(":"); } - if ((basename = strrchr(arg, DIRCHAR)) == NULL) + if ((basename = strrchr(arg, DIRCHAR)) == NUL_PTR) basename = arg; else ++basename; in_name = arg; if (ext == 'c') { +#ifdef ANSI_SUPPORT + /* If this was done between CPP and CC1 then + * we could define __STDC__ + */ + if (ansi_pass) + { + char *old_tmpdir; + struct arg_s cpargs = { CP, TRUE, }; + + old_tmpdir=tmpdir; + tmpdir="."; + out_name=my_mktemp(TRUE); + tmpdir=old_tmpdir; + run(in_name, out_name, &cpargs); + + addarg(&unprotoargs, out_name); + addarg(&unprotoargs, "-N"); + if (quiet_ansi) + addarg(&unprotoargs, "-q"); + run(NUL_PTR, NUL_PTR, &unprotoargs); + in_name=out_name; + } +#endif if (cpp_pass) { if (prep_only) out_name = f_out; else - out_name = my_mktemp(); + out_name = my_mktemp(FALSE); if (run(in_name, out_name, &cppargs) != 0) continue; in_name = out_name; @@ -452,7 +535,7 @@ char **argv; continue; if (cc_only) { - if (f_out != NULL) + if (f_out != NUL_PTR) out_name = f_out; else { @@ -461,12 +544,33 @@ char **argv; } } else - out_name = my_mktemp(); + out_name = my_mktemp(FALSE); if (run(in_name, out_name, &ccargs) != 0) continue; in_name = out_name; ext = 's'; } + if (ext == 'S') + { + if (prep_only) + out_name = f_out; + else if (cc_only) + { + if (f_out != NUL_PTR) + out_name = f_out; + else + { + out_name = stralloc(basename); + out_name[strlen(out_name) - 1] = 's'; + } + } + else + out_name = my_mktemp(FALSE); + if (run(in_name, out_name, &cppargs) != 0) + continue; + in_name = out_name; + ext = 's'; + } if (ext == 's') { if (prep_only || cc_only) @@ -475,7 +579,7 @@ char **argv; out_name[strlen(out_name) - 1] = 'o'; if (as_only) { - if (f_out != NULL) + if (f_out != NUL_PTR) out_name = f_out; else { @@ -484,16 +588,16 @@ char **argv; } } else - out_name = my_mktemp(); + out_name = my_mktemp(FALSE); addarg(&asargs, "-n"); arg[length - 1] = 's'; addarg(&asargs, arg); -#ifdef BCC86 +#ifdef BAS86 if (gnu_objects) { char *tmp_out_name; - tmp_out_name = my_mktemp(); + tmp_out_name = my_mktemp(FALSE); status = run(in_name, tmp_out_name, &asargs); asargs.argc -= 2; if (status != 0) @@ -526,19 +630,33 @@ char **argv; if (!prep_only && !cc_only && !as_only && !runerror) { - if (f_out == NULL) + if (f_out == NUL_PTR) f_out = "a.out"; -#ifdef BCC86 +#ifdef BAS86 if (gnu_objects) { - ldargs.prog = GCC; - run((char *) NULL, f_out, &ldargs); + /* Remove -i and -i-. */ + for (argc = ldargs.argc - 1; argc >= START_ARGS; --argc) + { + arg = ldargs.argv[argc]; + if (arg[0] == '-' && arg[1] == 'i' + && (arg[2] == 0 || (arg[2] == '-' && arg[3] == 0))) + { + --ldargs.argc; + memmove(ldargs.argv + argc, ldargs.argv + argc + 1, + (ldargs.argc - argc) * sizeof ldargs.argv[0]); + ldargs.argv[ldargs.argc] = NUL_PTR; + } + } + + ldargs.prog = fixpath(GCC, &exec_prefix, X_OK); + run((char *) NUL_PTR, f_out, &ldargs); } else #endif { addarg(&ldargs, "-lc"); - run((char *) NULL, f_out, &ldargs); + run((char *) NUL_PTR, f_out, &ldargs); } } killtemps(); @@ -559,12 +677,12 @@ char *arg; { argp->nr_allocated += ALLOC_UNIT; new_argv = realloc(argp->argv, argp->nr_allocated * sizeof *argp->argv); - if (new_argv == NULL) + if (new_argv == NUL_PTR) outofmemory("addarg"); argp->argv = new_argv; } argp->argv[argp->argc] = arg; - argp->argv[argp->argc = new_argc] = NULL; + argp->argv[argp->argc = new_argc] = NUL_PTR; } PRIVATE void addprefix(prefix, name) @@ -573,13 +691,15 @@ char *name; { struct prefix_s *new_prefix; - if (prefix->name == NULL) + if (prefix->name == NUL_PTR) prefix->name = name; else { new_prefix = my_malloc(sizeof *new_prefix, "addprefix"); new_prefix->name = name; - new_prefix->next = NULL; + new_prefix->next = NUL_PTR; + while (prefix->next != NUL_PTR) + prefix = prefix->next; prefix->next = new_prefix; } } @@ -599,8 +719,19 @@ int mode; { char *ppath; - for (; prefix != NULL; prefix = prefix->next) + for (; prefix != NUL_PTR; prefix = prefix->next) { + if (verbosity > 2) + { + show_who("searching for "); + if (mode == R_OK) + writes("readable file "); + else + writes("executable file "); + writes(path); + writes(" in "); + writesn(prefix->name); + } ppath = stralloc2(prefix->name, path); if (access(ppath, mode) == 0) return ppath; @@ -621,12 +752,13 @@ char *where; { void *block; - if ((block = malloc(size)) == NULL) + if ((block = malloc(size)) == NUL_PTR) outofmemory(where); return block; } -PRIVATE char *my_mktemp() +PRIVATE char *my_mktemp(c_extension) +int c_extension; { char *p; unsigned digit; @@ -634,8 +766,17 @@ PRIVATE char *my_mktemp() char *template; static unsigned tmpnum; - p = template = stralloc2(tmpdir, "/bccYYYYXXXX"); - p += strlen(p); + if (c_extension) + { + p = template = stralloc2(tmpdir, "/bccYYYYXXXX.c"); + p += strlen(p) - 2; + } + else + { + p = template = stralloc2(tmpdir, "/bccYYYYXXXX"); + p += strlen(p); + } + digits = getpid(); while (*--p == 'X') { @@ -660,12 +801,12 @@ PRIVATE char *my_mktemp() PRIVATE void my_unlink(name) char *name; { - if (verbose) + if (verbosity > 1) { show_who("unlinking "); writesn(name); } - if (unlink(name) < 0 && verbose) + if (unlink(name) < 0) { show_who("error unlinking "); writesn(name); @@ -689,9 +830,9 @@ struct arg_s *argp; int status; arg0 = 0; - if (in_name == NULL) + if (in_name == NUL_PTR) ++arg0; - if (out_name == NULL) + if (out_name == NUL_PTR) arg0 += 2; else if (argp->minus_O_broken) ++arg0; @@ -699,15 +840,15 @@ struct arg_s *argp; startarg(argp); argp->argv[arg0] = argp->prog; i = arg0 + 1; - if (in_name != NULL) + if (in_name != NUL_PTR) argp->argv[i++] = in_name; - if (out_name != NULL) + if (out_name != NUL_PTR) { if (!argp->minus_O_broken) argp->argv[i++] = "-o"; argp->argv[i++] = out_name; } - if (verbose) + if (verbosity != 0) { for (i = arg0; i < argp->argc; ++i) { @@ -735,6 +876,7 @@ struct arg_s *argp; --tmpargs.argc; memmove(tmpargs.argv + i, tmpargs.argv + i + 1, (tmpargs.argc - i) * sizeof tmpargs.argv[0]); + tmpargs.argv[tmpargs.argc] = NUL_PTR; break; } if (status != 0) @@ -748,17 +890,28 @@ struct arg_s *argp; PRIVATE void set_trap() { - int signum; +#ifndef NORDB +#ifdef SIGINT + signal(SIGINT, trap); +#endif +#ifdef SIGQUIT + signal(SIGQUIT, trap); +#endif +#else + /* This is being too trap happy! */ #ifndef _NSIG -#define NSIG _NSIG +#define _NSIG NSIG #endif + int signum; + for (signum = 0; signum <= _NSIG; ++signum) #ifdef SIGCHLD if (signum != SIGCHLD) #endif if (signal(signum, SIG_IGN) != SIG_IGN) signal(signum, trap); +#endif } PRIVATE void show_who(message) @@ -775,7 +928,7 @@ struct arg_s *argp; argp->argv = my_malloc((argp->nr_allocated = ALLOC_UNIT) * sizeof *argp->argv, "startarg"); argp->argc = START_ARGS; - argp->argv[START_ARGS] = NULL; + argp->argv[START_ARGS] = NUL_PTR; } PRIVATE char *stralloc(s) @@ -796,8 +949,7 @@ PRIVATE void trap(signum) int signum; { signal(signum, SIG_IGN); - if (verbose) - show_who("caught signal"); + show_who("caught signal"); fatal(""); } diff --git a/bcc-bruce/bcc.doc b/bcc/bcc.doc index 61ccd04..1c5e930 100644 --- a/bcc-bruce/bcc.doc +++ b/bcc/bcc.doc @@ -15,6 +15,7 @@ outfile stdout for preprocessor output somewhere/file.[cis] -> file.o for assembler output a.out for ld output +-ansi Pass the source through '/usr/bin/unprotoize' first -0 8086 target (works even on 80386 host) -3 80386 target (works even on 8086 host) -A pass remainder of option to assembler (e.g. -A-l -Alistfile for a listing) @@ -26,8 +27,11 @@ outfile stdout for preprocessor output -D define (as usual) -E produce preprocessor output (as usual) -G produce gnu-Minix objects (link with gnu ld) --I include search path (as usual) --L pass remainder of option to linker +-Ix include search path (as usual) +-I don't add default include to search list +-Lx add dir name x to the head of the list of library dirs searched +-L don't add default library to search list +-X pass remainder of option to linker -O optimize (does nothing) -P produce preprocessor output with no line numbers (as usual) -Q pass full option to c386 diff --git a/bcc-bruce/byteord.h b/bcc/byteord.h index e7b19e0..e7b19e0 100644 --- a/bcc-bruce/byteord.h +++ b/bcc/byteord.h diff --git a/bcc-bruce/codefrag.c b/bcc/codefrag.c index e98dac4..e42b05b 100644 --- a/bcc-bruce/codefrag.c +++ b/bcc/codefrag.c @@ -616,8 +616,8 @@ offset_t offset; store_pt reg; { #ifdef I8088 - 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 */ { if (reg == ALREG) reg = AXREG; /* shorter and faster */ @@ -1325,7 +1325,7 @@ store_pt reg; { for (lastcount = single1skip; (factor & 1) == 0; factor >>= 1) ++lastcount; - mulstack[++mulsp] = lastcount; + mulstack[(int)++mulsp] = lastcount; /* first time bumps mulsp to 0 even if an unsigned char */ for (count = 0; (factor & 1) != 0; factor >>= 1) ++count; @@ -1333,14 +1333,14 @@ store_pt reg; if (count == 2 && factor == 0) /* 3 = 2 + 1 better than 3 = 4 - 1 */ /* but rest of algorithm messed up unless factor now 0 */ - mulstack[++mulsp] = 1; + mulstack[(int)++mulsp] = 1; else if (count > 1) { single1skip = 0; if (lastcount == 1 && mulsp != 0) - mulstack[mulsp] = -1 - count; + mulstack[(int)mulsp] = -1 - count; else - mulstack[++mulsp] = -count; + mulstack[(int)++mulsp] = -count; } } if (mulsp > 3) @@ -1351,7 +1351,7 @@ store_pt reg; do { finishfactor(); /* finish save/add/subfactor() if nec */ - stackentry = mulstack[mulsp--]; + stackentry = mulstack[(int)mulsp--]; if (stackentry < 0) { #ifdef I8088 diff --git a/bcc-bruce/condcode.h b/bcc/condcode.h index 9b047df..9b047df 100644 --- a/bcc-bruce/condcode.h +++ b/bcc/condcode.h diff --git a/bcc-bruce/const.h b/bcc/const.h index 8df8bcb..8df8bcb 100644 --- a/bcc-bruce/const.h +++ b/bcc/const.h diff --git a/bcc-bruce/debug.c b/bcc/debug.c index 26f7bf8..26f7bf8 100644 --- a/bcc-bruce/debug.c +++ b/bcc/debug.c diff --git a/bcc-bruce/declare.c b/bcc/declare.c index e6b464c..1dd1314 100644 --- a/bcc-bruce/declare.c +++ b/bcc/declare.c @@ -322,7 +322,7 @@ struct typelist **ptypelist; value_t fieldwidth; value_t fwidth; offset_t offset; - scalar_t scalar; + scalar_t scalar=0; offset = *psoffset; declspec(); @@ -713,8 +713,8 @@ PRIVATE void idecllist() } else if (gvarsymptr != NULL && (gvarsymptr->level == level || gvartype->constructor == FUNCTION || - gvarsc == EXTERNDECL && - gvarsymptr->level == GLBLEVEL)) + (gvarsc == EXTERNDECL && + gvarsymptr->level == GLBLEVEL))) { if (gvarsymptr->level != GLBLEVEL || gvarsymptr->flags == KEYWORD) multidecl(gvarname); @@ -723,8 +723,8 @@ PRIVATE void idecllist() if (gvartype->constructor != ARRAY || gvarsymptr->type->constructor != ARRAY || gvartype->nexttype != gvarsymptr->type->nexttype || - gvartype->typesize != 0 && - gvarsymptr->type->typesize != 0) + (gvartype->typesize != 0 && + gvarsymptr->type->typesize != 0)) multidecl(gvarname); else if (gvartype->typesize != 0) gvarsymptr->type = gvartype; diff --git a/bcc-bruce/express.c b/bcc/express.c index e6ee64c..e6ee64c 100644 --- a/bcc-bruce/express.c +++ b/bcc/express.c diff --git a/bcc-bruce/exptree.c b/bcc/exptree.c index 32d9386..c4da1c4 100644 --- a/bcc-bruce/exptree.c +++ b/bcc/exptree.c @@ -62,15 +62,15 @@ register struct nodestruct *nodeptr; if (!(rscalar & DOUBLE)) nodeptr->right = castnode(dtype, right); } - else if (!(bothscalar & DLONG) && (nodeptr->tag == ANDOP && - (redscalar(nodeptr->left.nodeptr) | redscalar(right)) & CHAR || - (nodeptr->tag == EOROP || nodeptr->tag == OROP) && - redscalar(nodeptr->left.nodeptr) & redscalar(right) & CHAR || - nodeptr->tag == MODOP && right->tag == LEAF && + else if (!(bothscalar & DLONG) && ((nodeptr->tag == ANDOP && + (redscalar(nodeptr->left.nodeptr) | redscalar(right)) & CHAR) || + ((nodeptr->tag == EOROP || nodeptr->tag == OROP) && + redscalar(nodeptr->left.nodeptr) & redscalar(right) & CHAR) || + (nodeptr->tag == MODOP && right->tag == LEAF && right->left.symptr->storage == CONSTANT && (divisor = right->left.symptr->offset.offv, (uvalue_t) divisor <= MAXUCHTO + 1) && - bitcount((uvalue_t) divisor) <= 1)) + bitcount((uvalue_t) divisor) <= 1))) { /* result fits in char and extends correctly */ if (bothscalar & UNSIGNED) @@ -237,17 +237,17 @@ struct nodestruct *p2; #if MAXREGS != 1 weight_t rightweight; #endif - double dsourceval; - double dtargval; + double dsourceval = 0; /* for -Wall */ + double dtargval = 0 ; /* for -Wall */ bool_t lflag; scalar_t lscalar; struct nodestruct *pswap; - struct symstruct *source; - value_t sourceval; + struct symstruct *source = NULL; /* for -Wall */ + value_t sourceval = 0 ; /* for -Wall */ struct symstruct *target; offset_t targszdelta; - value_t targval; - scalar_t rscalar; + value_t targval = 0; /* for -Wall */ + scalar_t rscalar = 0; /* for -Wall */ bool_t uflag; switch ((op_t) t) @@ -367,10 +367,11 @@ struct nodestruct *p2; if (lscalar & RSCALAR && !(rscalar & RSCALAR)) { double val; + static double MAXULONG = (double)0xFFFFFFFFL +1; val = *target->offset.offd; if (val > maxlongto) - val -= (double) (unsigned long) 0xFFFFFFFF + 1; /* XXX */ + val -= MAXULONG; target->offset.offv = (value_t) val; } if (!(lscalar & RSCALAR) && rscalar & RSCALAR) @@ -479,8 +480,8 @@ struct nodestruct *p2; case COMMAOP: return p2; case CONDOP: - if (lscalar & RSCALAR && dtargval != FALSE - || !(lscalar & RSCALAR) && targval != FALSE) + if ((lscalar & RSCALAR && dtargval != FALSE) + || (!(lscalar & RSCALAR) && targval != FALSE)) { p2->left.nodeptr->nodetype = p2->nodetype; return p2->left.nodeptr; @@ -488,14 +489,14 @@ struct nodestruct *p2; p2->right->nodetype = p2->nodetype; return p2->right; case LOGANDOP: - if (lscalar & RSCALAR && dtargval != FALSE - || !(lscalar & RSCALAR) && targval != FALSE) + if ((lscalar & RSCALAR && dtargval != FALSE) + || (!(lscalar & RSCALAR) && targval != FALSE)) break; p1->nodetype = target->type = itype; return p1; case LOGOROP: - if (lscalar & RSCALAR && dtargval == FALSE - || !(lscalar & RSCALAR) && targval == FALSE) + if ((lscalar & RSCALAR && dtargval == FALSE) + || (!(lscalar & RSCALAR) && targval == FALSE)) break; target->offset.offv = TRUE; p1->nodetype = target->type = itype; @@ -521,11 +522,11 @@ struct nodestruct *p2; } } if (target->storage != CONSTANT || - !(lscalar & (ISCALAR | RSCALAR)) && (op_t) t != PTRSUBOP || - p2 != NULL && + !((lscalar & (ISCALAR | RSCALAR)) && (op_t) t != PTRSUBOP) || + (p2 != NULL && (p2->tag != LEAF || (source = p2->left.symptr)->storage != CONSTANT || - !((rscalar = source->type->scalar) & (ISCALAR | RSCALAR)) - && (op_t) t != PTRSUBOP)) + (!((rscalar = source->type->scalar) & (ISCALAR | RSCALAR)) + && (op_t) t != PTRSUBOP)))) goto node1; lflag = lscalar & LONG; uflag = lscalar & UNSIGNED; @@ -540,7 +541,7 @@ struct nodestruct *p2; uflag |= rscalar & UNSIGNED; } } - if (lscalar & RSCALAR || p2 != NULL && rscalar & RSCALAR) + if (lscalar & RSCALAR || (p2 != NULL && rscalar & RSCALAR)) { if (!(lscalar & RSCALAR)) { @@ -950,8 +951,8 @@ struct nodestruct *nodeptr; targtype = ctype; if (bothscalar & UNSIGNED) targtype = tounsigned(targtype); - if (!(bothscalar & INT) || left->tag == LEAF && lscalar & INT || - right->tag == LEAF && rscalar & INT) + if ((!(bothscalar & INT) || (left->tag == LEAF && lscalar & INT)) || + (right->tag == LEAF && rscalar & INT)) { /* this is correct even when the if fails (the casts have to */ /* be considered at a lower level) but gives worse code */ @@ -963,12 +964,12 @@ struct nodestruct *nodeptr; return targtype; /* XXX - reduced from promote(targtype) */ } if (targtype->constructor & POINTER && - (isconst0(right) || right->nodetype->constructor & POINTER && - right->nodetype->nexttype->constructor & VOID)) + (isconst0(right) || (right->nodetype->constructor & POINTER && + right->nodetype->nexttype->constructor & VOID))) return targtype; if (right->nodetype->constructor & POINTER && - (isconst0(left) || targtype->constructor & POINTER && - targtype->nexttype->constructor & VOID)) + (isconst0(left) || (targtype->constructor & POINTER && + targtype->nexttype->constructor & VOID))) return right->nodetype; error("mismatched types"); fixnode(left); /* XXX - better to fix the CONDOP */ diff --git a/bcc-bruce/floatop.c b/bcc/floatop.c index fb9c54d..fb9c54d 100644 --- a/bcc-bruce/floatop.c +++ b/bcc/floatop.c diff --git a/bcc-bruce/function.c b/bcc/function.c index 1d48a19..1d48a19 100644 --- a/bcc-bruce/function.c +++ b/bcc/function.c diff --git a/bcc-bruce/gencode.c b/bcc/gencode.c index 55f36df..fa098ea 100644 --- a/bcc-bruce/gencode.c +++ b/bcc/gencode.c @@ -3,7 +3,7 @@ /* Copyright (C) 1992 Bruce Evans */ #define islvalop(op) \ - ((op) >= ASSIGNOP && (op) <= SUBABOP || (op) == PTRADDABOP) + (((op) >= ASSIGNOP && (op) <= SUBABOP) || (op) == PTRADDABOP) #include "const.h" #include "types.h" @@ -291,7 +291,7 @@ struct nodestruct *exp; } if (source->storage & allindregs && source->indcount == 0 && (source->type->scalar & (DLONG | RSCALAR) || - left->tag == FUNCOP && source->flags != REGVAR)) + (left->tag == FUNCOP && source->flags != REGVAR))) push(source); /* XXX - perhaps not float */ else preserve(source); @@ -351,11 +351,11 @@ struct nodestruct *exp; debug(exp); #endif if (commutop - && (target->storage == CONSTANT - && !(target->type->scalar & (DLONG | RSCALAR)) + && ((target->storage == CONSTANT + && !(target->type->scalar & (DLONG | RSCALAR))) || source->storage & ALLDATREGS - || source->type->scalar & (DLONG | RSCALAR) - && source->indcount == 0 && target->indcount != 0)) + || (source->type->scalar & (DLONG | RSCALAR) + && source->indcount == 0 && target->indcount != 0))) { exp->left.nodeptr = right; exp->right = left; @@ -471,12 +471,12 @@ struct nodestruct *exp; ccode_t condtrue; op_pt op; store_t regmark; - offset_t saveargsp; - store_t savelist; - offset_t saveoffset; + offset_t saveargsp = 0; /* for -Wall */ + store_t savelist = 0; /* for -Wall */ + offset_t saveoffset = 0; /* for -Wall */ struct symstruct *source; offset_t spmark; - struct symstruct *structarg; + struct symstruct *structarg = 0; /* for -Wall */ struct symstruct *target; if ((op_t) (op = exp->tag) == LEAF) diff --git a/bcc-bruce/gencode.h b/bcc/gencode.h index 370817a..370817a 100644 --- a/bcc-bruce/gencode.h +++ b/bcc/gencode.h diff --git a/bcc-bruce/genloads.c b/bcc/genloads.c index 9e4f6be..2056cb7 100644 --- a/bcc-bruce/genloads.c +++ b/bcc/genloads.c @@ -434,15 +434,16 @@ struct symstruct *source; { if (source->type->scalar & RSCALAR) load(source, doubleregs & ~DREG); - else if (source->storage == CONSTANT && !(source->type->scalar & DLONG) + else if ((source->storage == CONSTANT && + !(source->type->scalar & DLONG)) || source->type->scalar & CHAR) load(source, DREG); else if (source->storage & ~reguse & allregs) load(source, source->storage); else if (((reguse & allindregs) == allindregs || - !(source->type->constructor & (ARRAY | POINTER)) && + ((!(source->type->constructor & (ARRAY | POINTER)) && source->indcount != 0) && - !(source->type->scalar & DLONG)) + !(source->type->scalar & DLONG)))) load(source, DREG); else load(source, getindexreg()); @@ -1011,10 +1012,10 @@ struct symstruct *source; } } #ifdef I8088 - else if (source->indcount == 1 && + else if ((source->indcount == 1 && (sscalar & (SHORT | INT | LONG | FLOAT) || - source->type->constructor & POINTER) || - source->storage == CONSTANT && i386_32) + source->type->constructor & POINTER)) || + (source->storage == CONSTANT && i386_32)) { size = source->type->typesize; if (size == 1) diff --git a/bcc-bruce/glogcode.c b/bcc/glogcode.c index edbedcd..e2d086b 100644 --- a/bcc-bruce/glogcode.c +++ b/bcc/glogcode.c @@ -90,7 +90,7 @@ ccode_t *pcondtrue; } #endif #endif - sbranch(oppcc[*pcondtrue], falselab = getlabel()); + sbranch(oppcc[(int)*pcondtrue], falselab = getlabel()); loadlogical(target, falselab); } @@ -107,25 +107,25 @@ ccode_t *pcondtrue; reduceconst(target); sscalar = source->type->scalar; tscalar = target->type->scalar; - if (source->storage != CONSTANT && + if ((source->storage != CONSTANT && (target->storage == CONSTANT || - sscalar & CHAR && !(tscalar & CHAR) || - (sscalar & CHAR || !(tscalar & CHAR)) && - source->indcount == 0 && target->indcount != 0) || - tscalar & DLONG && target->indcount != 0) + (sscalar & CHAR && !(tscalar & CHAR)) || + ((sscalar & CHAR || !(tscalar & CHAR)) && + source->indcount == 0 && target->indcount != 0))) || + (tscalar & DLONG && target->indcount != 0)) { swapsym(target, source); - *pcondtrue = reverscc[*pcondtrue]; + *pcondtrue = reverscc[(int)*pcondtrue]; tempscalar = sscalar; sscalar = tscalar; tscalar = tempscalar; } - if (sscalar & CHAR && tscalar & CHAR && - (source->type != sctype || target->type != sctype) || + if ((sscalar & CHAR && tscalar & CHAR && + (source->type != sctype || target->type != sctype)) || (sscalar | tscalar) & UNSIGNED || (source->type->constructor | target->type->constructor) & (ARRAY | POINTER)) - *pcondtrue = unsigncc[*pcondtrue]; + *pcondtrue = unsigncc[(int)*pcondtrue]; if (source->type->scalar & DLONG) { longop(EQOP, source, target); @@ -141,7 +141,7 @@ ccode_t *pcondtrue; if (sscalar & CHAR) { if (tscalar & CHAR) - *pcondtrue = unsigncc[*pcondtrue]; + *pcondtrue = unsigncc[(int)*pcondtrue]; else { source->type = iscalartotype(sscalar); @@ -271,7 +271,7 @@ bool_pt nojump; /* NB if nonzero, is ~0 so complement is 0 */ changesp(spmark, FALSE); reguse = regmark; if ((bool_t) nojump) - lbranch(oppcc[condtrue], falselab); + lbranch(oppcc[(int)condtrue], falselab); else lbranch(condtrue, truelab); } @@ -452,7 +452,7 @@ ccode_t *pcondtrue; store_t targreg; #endif - *pcondtrue = testcc[*pcondtrue]; + *pcondtrue = testcc[(int)*pcondtrue]; if (target->type->scalar & DLONG) { long1op(EQOP, target); @@ -465,7 +465,7 @@ ccode_t *pcondtrue; } #ifdef I8088 if (target->indcount != 0 || - target->storage == LOCAL && target->offset.offi != sp) + (target->storage == LOCAL && target->offset.offi != sp)) load(target, DREG); if (target->storage == GLOBAL) load(target, getindexreg()); @@ -546,7 +546,7 @@ bool_pt nojump; /* NB if nonzero, is ~0 so complement is 0 */ condtrue = NE; test(source, &condtrue); if ((bool_t) nojump) - lbranch(oppcc[condtrue], falselab); + lbranch(oppcc[(int)condtrue], falselab); else lbranch(condtrue, truelab); } diff --git a/bcc-bruce/hardop.c b/bcc/hardop.c index 8121484..098d22b 100644 --- a/bcc-bruce/hardop.c +++ b/bcc/hardop.c @@ -286,8 +286,8 @@ struct symstruct *target; sscalar = source->type->scalar; } if (target->indcount != 0 && - (tscalar & CHAR && !(sscalar & CHAR) && - op != ANDOP || source->indcount == 0 && source->storage != CONSTANT)) + ((tscalar & CHAR && !(sscalar & CHAR) && + op != ANDOP) || (source->indcount == 0 && source->storage != CONSTANT))) { swapsym(target, source); sscalar = tscalar; diff --git a/bcc-bruce/input.c b/bcc/input.c index f321a9d..4cf699a 100644 --- a/bcc-bruce/input.c +++ b/bcc/input.c @@ -47,7 +47,9 @@ PRIVATE struct inclist incfirst; /* between first and last */ PRIVATE struct inclist inclast = { +#ifdef DEFAULT_INCLUDE_DIR DEFAULT_INCLUDE_DIR, +#endif NULL, }; PRIVATE fastin_t inclevel; /* nest level of include files */ @@ -331,7 +333,13 @@ ts_s_pathname_tot -= strlen(fullnameptr) + 1; ourfree(fullnameptr); } while ((incptr = incptr->incnext) != NULL); - error("cannot find include file"); + + fullnameptr = ourmalloc(strlen(fnameptr) + 40); + strcpy(fullnameptr, "cannot find include file "); + strcat(fullnameptr, fnameptr); + error(fullnameptr); + ourfree(fullnameptr); + #ifdef TS ts_s_filename_tot -= charptr - fnameptr; #endif @@ -375,6 +383,40 @@ ts_s_inputbuf_tot += sizeof *inputbuf; ch = *(lineptr = newinputbuf->fbuf - 1) = EOL; } +PUBLIC void linecontol() +{ +static char linename[32]; + char * ptr; + int i=0; + + blanks(); + input.linenumber = atoi(lineptr)-1; + while( SYMOFCHAR(ch) == INTCONST ) gch1(); + blanks(); + if( ch != '"' ) return; + for(ptr=lineptr+1; *ptr + && *ptr != EOL + && *ptr != '"' + && i<sizeof(linename)-1; i++, ptr++) + linename[i] = *ptr; + linename[i] = '\0'; + + if (inputbuf->fname_malloced) +{ +#ifdef TS +ts_s_pathname_tot -= strlen(inputbuf->fname) + 1; +#endif + ourfree(inputbuf->fname); +} + inputbuf->fname_malloced = FALSE; + inputbuf->fname = linename; + + ptr=lineptr; + undefinestring(filemacro); + definefile(inputbuf->fname); + ch = *(lineptr = ptr); +} + /* switch from include file to file which included it */ PRIVATE void leaveinclude() @@ -462,9 +504,9 @@ char *argv[]; case 't': /* print source code in asm output */ case 'w': /* watch location counter */ if (arg[2] == 0) - flag[arg[1]] = TRUE; + flag[(int)arg[1]] = TRUE; else if (arg[2] == '-' && arg[3] == 0) - flag[arg[1]] = FALSE; + flag[(int)arg[1]] = FALSE; else usage(); if (arg[1] == '0') /* flag 0 is negative logic flag 3 */ diff --git a/bcc-bruce/input.h b/bcc/input.h index 0563059..0563059 100644 --- a/bcc-bruce/input.h +++ b/bcc/input.h diff --git a/bcc-bruce/label.c b/bcc/label.c index 8489230..5b07af9 100644 --- a/bcc-bruce/label.c +++ b/bcc/label.c @@ -78,7 +78,7 @@ char *patch; { register struct labdatstruct *labptr; - labptr = &vislab[nextvislab]; + labptr = &vislab[(int)nextvislab]; labptr->labcond = cond; labptr->labnum = label; labptr->lablc = lc; @@ -184,7 +184,7 @@ label_t label; labmin = &vislab[0]; labmax = &vislab[MAXVISLAB]; - labptr = labmid = &vislab[nextvislab]; + labptr = labmid = &vislab[(int)nextvislab]; if (!watchlc) do { @@ -199,7 +199,7 @@ label_t label; #ifdef I8088 /* patch "bcc(c) to j(c)(c)( ) */ *labpatch = 'j'; *(labpatch + 1) = - *(cnameptr = scondnames[labptr->labcond]); + *(cnameptr = scondnames[(int)labptr->labcond]); #endif #ifdef MC6809 # ifdef NEW_MC6809 /* patch JMP\t> or LBCC\t to BCC \t */ @@ -308,7 +308,7 @@ label_t label; { outlbranch(); #ifdef I8088 - outbyte(*(cnameptr = lcondnames[(ccode_t) cond])); + outbyte(*(cnameptr = lcondnames[(int) cond])); outbyte(*(cnameptr + 1)); if ((ccode_t) cond == LS || (ccode_t) cond == HS) outbyte('s'); /* "blos" or "bhis" */ @@ -406,7 +406,7 @@ label_t label; if ((ccode_t) cond != RN) { outsbranch(); - outbyte(*(cnameptr = scondnames[(ccode_t) cond])); + outbyte(*(cnameptr = scondnames[(int) cond])); outbyte(*(cnameptr + 1)); outtab(); outlabel(label); diff --git a/bcc-bruce/label.h b/bcc/label.h index 89c83d7..89c83d7 100644 --- a/bcc-bruce/label.h +++ b/bcc/label.h diff --git a/bcc-bruce/loadexp.c b/bcc/loadexp.c index 781dca0..632c2ad 100644 --- a/bcc-bruce/loadexp.c +++ b/bcc/loadexp.c @@ -56,9 +56,9 @@ struct typestruct *type; makeleaf(node(ASSIGNOP, lhs, exp)); } else if (exp->tag != LEAF || - (symptr = exp->left.symptr)->storage != CONSTANT && + ((symptr = exp->left.symptr)->storage != CONSTANT && (symptr->storage != GLOBAL || symptr->indcount != 0 || - type->scalar & DLONG) || + type->scalar & DLONG)) || (type->constructor | (symptr->type->constructor & ~FUNCTION)) & ~(ARRAY | POINTER)) error("initializer too complicated"); diff --git a/bcc-bruce/longop.c b/bcc/longop.c index 8396392..f678e11 100644 --- a/bcc-bruce/longop.c +++ b/bcc/longop.c @@ -39,7 +39,7 @@ struct symstruct *target; shiftflag = TRUE; else scalar |= source->type->scalar; - if (source->indcount == 0 && !shiftflag || + if ((source->indcount == 0 && !shiftflag) || source->storage & (DREG | OPREG | OPWORKREG)) { pres2(source, target); diff --git a/bcc-bruce/misc/sformat b/bcc/misc/sformat index 3dcb0c4..3dcb0c4 100644 --- a/bcc-bruce/misc/sformat +++ b/bcc/misc/sformat diff --git a/bcc-bruce/misc/test/8queens.pas b/bcc/misc/test/8queens.pas index f4f1b47..f4f1b47 100644 --- a/bcc-bruce/misc/test/8queens.pas +++ b/bcc/misc/test/8queens.pas diff --git a/bcc-bruce/misc/test/8queens.t b/bcc/misc/test/8queens.t index 8d20a4d..8d20a4d 100644 --- a/bcc-bruce/misc/test/8queens.t +++ b/bcc/misc/test/8queens.t diff --git a/bcc-bruce/misc/test/atol.t b/bcc/misc/test/atol.t index 79c78b7..79c78b7 100644 --- a/bcc-bruce/misc/test/atol.t +++ b/bcc/misc/test/atol.t diff --git a/bcc-bruce/misc/test/bigsievec.t b/bcc/misc/test/bigsievec.t index f3f76b2..f3f76b2 100644 --- a/bcc-bruce/misc/test/bigsievec.t +++ b/bcc/misc/test/bigsievec.t diff --git a/bcc-bruce/misc/test/bt.t b/bcc/misc/test/bt.t index b88836c..b88836c 100644 --- a/bcc-bruce/misc/test/bt.t +++ b/bcc/misc/test/bt.t diff --git a/bcc-bruce/misc/test/cast.t b/bcc/misc/test/cast.t index 554cb93..554cb93 100644 --- a/bcc-bruce/misc/test/cast.t +++ b/bcc/misc/test/cast.t diff --git a/bcc-bruce/misc/test/cast1.t b/bcc/misc/test/cast1.t index a4c15d5..a4c15d5 100644 --- a/bcc-bruce/misc/test/cast1.t +++ b/bcc/misc/test/cast1.t diff --git a/bcc-bruce/misc/test/castest.t b/bcc/misc/test/castest.t index ae27f7b..ae27f7b 100644 --- a/bcc-bruce/misc/test/castest.t +++ b/bcc/misc/test/castest.t diff --git a/bcc-bruce/misc/test/ctype.t b/bcc/misc/test/ctype.t index 93b3e4f..93b3e4f 100644 --- a/bcc-bruce/misc/test/ctype.t +++ b/bcc/misc/test/ctype.t diff --git a/bcc-bruce/misc/test/error.t b/bcc/misc/test/error.t index 24e302a..24e302a 100644 --- a/bcc-bruce/misc/test/error.t +++ b/bcc/misc/test/error.t diff --git a/bcc-bruce/misc/test/extern.t b/bcc/misc/test/extern.t index dac5f5c..dac5f5c 100644 --- a/bcc-bruce/misc/test/extern.t +++ b/bcc/misc/test/extern.t diff --git a/bcc-bruce/misc/test/hilbert.t b/bcc/misc/test/hilbert.t index e18dc63..e18dc63 100644 --- a/bcc-bruce/misc/test/hilbert.t +++ b/bcc/misc/test/hilbert.t diff --git a/bcc-bruce/misc/test/longtest.c b/bcc/misc/test/longtest.c index 0c0bfe0..0c0bfe0 100644 --- a/bcc-bruce/misc/test/longtest.c +++ b/bcc/misc/test/longtest.c diff --git a/bcc-bruce/misc/test/longtest.dat b/bcc/misc/test/longtest.dat index a1c7998..a1c7998 100644 --- a/bcc-bruce/misc/test/longtest.dat +++ b/bcc/misc/test/longtest.dat diff --git a/bcc-bruce/misc/test/longtest.mak b/bcc/misc/test/longtest.mak index 454a4e8..454a4e8 100755 --- a/bcc-bruce/misc/test/longtest.mak +++ b/bcc/misc/test/longtest.mak diff --git a/bcc-bruce/misc/test/longtest.sh b/bcc/misc/test/longtest.sh index e76f98a..e76f98a 100755 --- a/bcc-bruce/misc/test/longtest.sh +++ b/bcc/misc/test/longtest.sh diff --git a/bcc-bruce/misc/test/miniltest.t b/bcc/misc/test/miniltest.t index 78097d4..78097d4 100644 --- a/bcc-bruce/misc/test/miniltest.t +++ b/bcc/misc/test/miniltest.t diff --git a/bcc-bruce/misc/test/op1.t b/bcc/misc/test/op1.t index 614e093..614e093 100644 --- a/bcc-bruce/misc/test/op1.t +++ b/bcc/misc/test/op1.t diff --git a/bcc-bruce/misc/test/opcmp.t b/bcc/misc/test/opcmp.t index 28bd1a2..28bd1a2 100644 --- a/bcc-bruce/misc/test/opcmp.t +++ b/bcc/misc/test/opcmp.t diff --git a/bcc-bruce/misc/test/oplong.t b/bcc/misc/test/oplong.t index b452243..b452243 100644 --- a/bcc-bruce/misc/test/oplong.t +++ b/bcc/misc/test/oplong.t diff --git a/bcc-bruce/misc/test/opplus.t b/bcc/misc/test/opplus.t index 88e31e9..88e31e9 100644 --- a/bcc-bruce/misc/test/opplus.t +++ b/bcc/misc/test/opplus.t diff --git a/bcc-bruce/misc/test/opsoft.t b/bcc/misc/test/opsoft.t index 346df4d..346df4d 100644 --- a/bcc-bruce/misc/test/opsoft.t +++ b/bcc/misc/test/opsoft.t diff --git a/bcc-bruce/misc/test/puzzle.t b/bcc/misc/test/puzzle.t index 9d2c4ab..9d2c4ab 100644 --- a/bcc-bruce/misc/test/puzzle.t +++ b/bcc/misc/test/puzzle.t diff --git a/bcc-bruce/misc/test/sierpin.t b/bcc/misc/test/sierpin.t index 79016f7..79016f7 100644 --- a/bcc-bruce/misc/test/sierpin.t +++ b/bcc/misc/test/sierpin.t diff --git a/bcc-bruce/misc/test/sievec.t b/bcc/misc/test/sievec.t index 1b51fdb..1b51fdb 100644 --- a/bcc-bruce/misc/test/sievec.t +++ b/bcc/misc/test/sievec.t diff --git a/bcc-bruce/misc/test/sievecp.t b/bcc/misc/test/sievecp.t index 185b031..185b031 100644 --- a/bcc-bruce/misc/test/sievecp.t +++ b/bcc/misc/test/sievecp.t diff --git a/bcc-bruce/misc/test/sievei.t b/bcc/misc/test/sievei.t index d4910dc..d4910dc 100644 --- a/bcc-bruce/misc/test/sievei.t +++ b/bcc/misc/test/sievei.t diff --git a/bcc-bruce/misc/test/sort.t b/bcc/misc/test/sort.t index 34bcb9e..34bcb9e 100644 --- a/bcc-bruce/misc/test/sort.t +++ b/bcc/misc/test/sort.t diff --git a/bcc-bruce/misc/test/stdio.t b/bcc/misc/test/stdio.t index e7e174d..e7e174d 100644 --- a/bcc-bruce/misc/test/stdio.t +++ b/bcc/misc/test/stdio.t diff --git a/bcc-bruce/os.h b/bcc/os.h index 672ddd8..71dfcef 100644 --- a/bcc-bruce/os.h +++ b/bcc/os.h @@ -26,7 +26,6 @@ #define EOLTO 10 /* target newline */ #define DIRCHAR '/' #define DIRSTRING "/" -#define DEFAULT_INCLUDE_DIR "/usr/include" #define isabspath(fnameptr, tempcptr) \ ((*(tempcptr) = *(fnameptr)) == DIRCHAR) diff --git a/bcc-bruce/output.c b/bcc/output.c index 09e45a2..c44ea3f 100644 --- a/bcc-bruce/output.c +++ b/bcc/output.c @@ -378,7 +378,7 @@ register uoffset_t num; outhexdigs(num / 0x10); num %= 0x10; } - outbyte(hexdigits[(fastin_t) num]); + outbyte(hexdigits[(int) num]); } /* print string terminated by EOL */ diff --git a/bcc-bruce/output.h b/bcc/output.h index 6dc9cf1..6dc9cf1 100644 --- a/bcc-bruce/output.h +++ b/bcc/output.h diff --git a/bcc-bruce/parse.h b/bcc/parse.h index ab67f6c..ab67f6c 100644 --- a/bcc-bruce/parse.h +++ b/bcc/parse.h diff --git a/bcc-bruce/preproc.c b/bcc/preproc.c index 59ed9dc..90f5a8c 100644 --- a/bcc-bruce/preproc.c +++ b/bcc/preproc.c @@ -164,7 +164,7 @@ PRIVATE void control() if (sname[1] == 0 && ch == EOL) return; if (SYMOFCHAR(ch) == INTCONST) - return; /* XXX - # linenumber not implemented */ + { linecontol(); return; } if ((symptr = findlorg(sname)) == NULL) { if (ifstate.ifflag) @@ -201,7 +201,7 @@ PRIVATE void control() include(); break; case LINECNTL: - break; /* XXX - #line not implemented */ + { linecontol(); break; } case UNDEFCNTL: undef(); break; @@ -230,7 +230,7 @@ PUBLIC void define() char sname[NAMESIZE]; char quote; struct symstruct **hashptr; - struct symstruct *locmark; + struct symstruct *locmark = NULL; /* for -Wall */ char *macstring; fastin_t nparnames; char *oldstring; @@ -492,7 +492,7 @@ PRIVATE void endif() { register struct ifstruct *ifptr; - ifptr = &ifstack[--iflevel]; + ifptr = &ifstack[(int)--iflevel]; ifstate.elseflag = ifptr->elseflag; ifstate.ifflag = ifptr->ifflag; } @@ -586,8 +586,8 @@ ts_s_macparam_tot += sizeof *paramlist * nparleft; } else if (ch == '(') ++lpcount; - else if (ch == ')' && --lpcount == 0 || - ch == ',' && lpcount == 1) + else if ((ch == ')' && --lpcount == 0) || + (ch == ',' && lpcount == 1)) break; if (ch == EOL) ch = ' '; @@ -757,7 +757,7 @@ sym_pt ifcase; { register struct ifstruct *ifptr; - ifptr = &ifstack[iflevel++]; + ifptr = &ifstack[(int)iflevel++]; ifptr->elseflag = ifstate.elseflag; ifptr->ifflag = ifstate.ifflag; ifstate.elseflag = FALSE; /* prepare for !(if now)||(if future)*/ @@ -778,8 +778,8 @@ sym_pt ifcase; iftrue = constexpression() != 0; incppexpr = FALSE; } - if (!iftrue && (sym_t) ifcase != IFNDEFCNTL || - iftrue && (sym_t) ifcase == IFNDEFCNTL) + if ((!iftrue && (sym_t) ifcase != IFNDEFCNTL) || + (iftrue && (sym_t) ifcase == IFNDEFCNTL)) { ifstate.elseflag = TRUE; ifstate.ifflag = FALSE; diff --git a/bcc-bruce/preserve.c b/bcc/preserve.c index 0103a43..74b0f34 100644 --- a/bcc-bruce/preserve.c +++ b/bcc/preserve.c @@ -14,10 +14,10 @@ PUBLIC void changesp(newsp, absflag) offset_t newsp; bool_pt absflag; { - if (newsp != sp || (bool_t) absflag && switchnow != NULL) + if (newsp != sp || ((bool_t) absflag && switchnow != NULL)) { #ifdef FRAMEPOINTER - if (newsp != framep || !(bool_t) absflag && switchnow != NULL) + if (newsp != framep || (!(bool_t) absflag && switchnow != NULL)) { outleasp(); if (!(bool_t) absflag && switchnow != NULL) @@ -106,7 +106,8 @@ struct symstruct *target; if (target->storage & allregs) { if (target->storage & (allregs - allindregs) /* XXX */ || - target->indcount == 0 && target->type->scalar & (DLONG | RSCALAR)) + (target->indcount == 0 && + target->type->scalar & (DLONG | RSCALAR))) push(target); /* XXX - perhaps not float */ else if (((target->storage | reguse) & allindregs) == allindregs) { diff --git a/bcc-bruce/proto.h b/bcc/proto.h index 00dc116..0c04044 100644 --- a/bcc-bruce/proto.h +++ b/bcc/proto.h @@ -2,11 +2,12 @@ /* Copyright (C) 1992 Bruce Evans */ -#if __STDC__ +#ifdef __STDC__ #define P(x) x #else #define P(x) () #endif +#include <malloc.h> /* assign.c */ void assign P((struct symstruct *source, struct symstruct *target)); @@ -376,9 +377,6 @@ int open P((const char *_path, int _oflag, ...)); /* library - stdlib.h */ double atof P((const char *_str)); void exit P((int _status)); -void free P((void *_ptr)); -void *malloc P((unsigned _nbytes)); -void *realloc P((void *_ptr, unsigned _nbytes)); /* library - string.h */ void *memcpy P((void *_t, const void *_s, unsigned _length)); diff --git a/bcc-bruce/reg.h b/bcc/reg.h index 822bda7..822bda7 100644 --- a/bcc-bruce/reg.h +++ b/bcc/reg.h diff --git a/bcc-bruce/sc.h b/bcc/sc.h index c17536a..c17536a 100644 --- a/bcc-bruce/sc.h +++ b/bcc/sc.h diff --git a/bcc-bruce/scan.c b/bcc/scan.c index 0baecf8..0baecf8 100644 --- a/bcc-bruce/scan.c +++ b/bcc/scan.c diff --git a/bcc-bruce/scan.h b/bcc/scan.h index 5333e96..5333e96 100644 --- a/bcc-bruce/scan.h +++ b/bcc/scan.h diff --git a/bcc-bruce/sizes.h b/bcc/sizes.h index df0d141..df0d141 100644 --- a/bcc-bruce/sizes.h +++ b/bcc/sizes.h diff --git a/bcc-bruce/softop.c b/bcc/softop.c index d676e18..369ad96 100644 --- a/bcc-bruce/softop.c +++ b/bcc/softop.c @@ -124,14 +124,17 @@ struct symstruct *target; regpushed = (regmark = reguse) & OPREG; workreg = OPREG; - if (sscalar & CHAR && target->storage & WORKDATREGS && - source->storage == OPREG && source->indcount != 0 || - (sscalar & CHAR || source->storage & WORKDATREGS) && - target->storage == OPREG && target->indcount != 0 || - source->storage == OPREG && - target->storage == GLOBAL && target->indcount == 0 + if ((sscalar & CHAR && target->storage & WORKDATREGS && + source->storage == OPREG && source->indcount != 0) || + ((sscalar & CHAR || source->storage & WORKDATREGS) && + target->storage == OPREG && target->indcount != 0) || +#ifdef MC6809 /* for -Wall */ + ( +#endif + (source->storage == OPREG && + target->storage == GLOBAL && target->indcount == 0) #ifdef MC6809 - && posindependent + && posindependent) #endif ) { diff --git a/bcc-bruce/state.c b/bcc/state.c index 526d1f9..cc821e3 100644 --- a/bcc-bruce/state.c +++ b/bcc/state.c @@ -128,8 +128,8 @@ PRIVATE bool_pt isforever(exp) register struct nodestruct *exp; { return exp == NULL || - exp->tag == LEAF && exp->left.symptr->storage == CONSTANT && - exp->left.symptr->offset.offv != 0; + (exp->tag == LEAF && exp->left.symptr->storage == CONSTANT && + exp->left.symptr->offset.offv != 0); } PRIVATE void sort(caselist, count) /* shell sort */ @@ -370,7 +370,7 @@ PRIVATE void dofor() { struct loopstruct forloop; label_t forstatlab; - label_t fortestlab; + label_t fortestlab = 0; /* for -Wall */ struct nodestruct *testexp; struct nodestruct *loopexp; @@ -469,7 +469,7 @@ PRIVATE void doswitch() { struct switchstruct *sw; struct loopstruct switchloop; - offset_t spmark; + offset_t spmark = 0; /* for -Wall */ label_t sdecidelab; sw = (struct switchstruct *) ourmalloc(sizeof *sw); diff --git a/bcc-bruce/table.c b/bcc/table.c index 028950f..5a5c34e 100644 --- a/bcc-bruce/table.c +++ b/bcc/table.c @@ -145,7 +145,7 @@ char *name; struct typestruct *type; { struct symstruct **hashptr; - struct symstruct *oldsymptr; + struct symstruct *oldsymptr = NULL; /* for -Wall */ register struct symstruct *symptr; hashptr = gethashptr(name); diff --git a/bcc-bruce/table.h b/bcc/table.h index f9b2f38..f9b2f38 100644 --- a/bcc-bruce/table.h +++ b/bcc/table.h diff --git a/bcc/tags b/bcc/tags new file mode 100644 index 0000000..c0babfc --- /dev/null +++ b/bcc/tags @@ -0,0 +1,341 @@ +adc0 codefrag.c /^PUBLIC void adc0()$/ +add hardop.c /^PUBLIC void add(source, target)$/ +addconst codefrag.c /^PUBLIC void addconst(offset, reg)$/ +addglb table.c /^PUBLIC struct symstruct *addglb(name, type)$/ +addloc table.c /^PUBLIC struct symstruct *addloc(name, type)$/ +addlorg table.c /^PUBLIC struct symstruct *addlorg(name, type)$/ +addoffset genloads.c /^PUBLIC void addoffset(source)$/ +address genloads.c /^PUBLIC void address(source)$/ +addstruct type.c /^PUBLIC struct typestruct *addstruct(structname)$/ +addsym table.c /^PUBLIC void addsym(name, type, symptr)$/ +adjlc codefrag.c /^PUBLIC void adjlc(offset, reg)$/ +adjsp codefrag.c /^PUBLIC void adjsp(label)$/ +andconst codefrag.c /^PUBLIC void andconst(offset)$/ +assign assign.c /^PUBLIC void assign(source, target)$/ +assignment_exp express.c /^PUBLIC struct nodestruct *assignment_exp()$/ +bileaf gencode.c /^PUBLIC void bileaf(exp)$/ +bitcount gencode.c /^PUBLIC fastin_pt bitcount(number)$/ +blanks scan.c /^PUBLIC void blanks()$/ +blanksident preproc.c /^PUBLIC bool_pt blanksident()$/ +bssseg codefrag.c /^PUBLIC void bssseg()$/ +bugerror output.c /^PUBLIC void bugerror(message)$/ +bumplc label.c /^PUBLIC void bumplc()$/ +bumplc2 label.c /^PUBLIC void bumplc2()$/ +bumplc3 label.c /^PUBLIC void bumplc3()$/ +call function.c /^PUBLIC void call(name)$/ +casejump codefrag.c /^PUBLIC label_t casejump()$/ +cast assign.c /^PUBLIC void cast(type, target)$/ +castnode exptree.c /^PUBLIC struct nodestruct *castnode(type, nodeptr)$/ +changesp preserve.c /^PUBLIC void changesp(newsp, absflag)$/ +checknotinif preproc.c /^PUBLIC void checknotinif()$/ +clearfunclabels label.c /^PUBLIC void clearfunclabels()$/ +clearlabels label.c /^PUBLIC void clearlabels(patchbuf, patchtop)$/ +clearswitchlabels label.c /^PUBLIC void clearswitchlabels()$/ +closein input.c /^PUBLIC void closein()$/ +closeout output.c /^PUBLIC void closeout()$/ +clrBreg codefrag.c /^PUBLIC void clrBreg()$/ +clrBreg codefrag.c /^PUBLIC void clrBreg()$/ +cmp glogcode.c /^PUBLIC void cmp(source, target, pcondtrue)$/ +codeinit gencode.c /^PUBLIC void codeinit()$/ +colon declare.c /^PUBLIC void colon()$/ +comDreg codefrag.c /^PUBLIC void comDreg()$/ +comDreg codefrag.c /^PUBLIC void comDreg()$/ +comment codefrag.c /^PUBLIC void comment()$/ +comment codefrag.c /^PUBLIC void comment()$/ +common codefrag.c /^PUBLIC void common(name)$/ +compound state.c /^PUBLIC void compound() /* have just seen "{" */$/ +condop glogcode.c /^PUBLIC void condop(exp)$/ +constexpression loadexp.c /^PUBLIC value_t constexpression()$/ +constsym table.c /^PUBLIC struct symstruct *constsym(longconst)$/ +cppscan scan.c /^PUBLIC void cppscan()$/ +cseg codefrag.c /^PUBLIC void cseg()$/ +ctoi codefrag.c /^PUBLIC void ctoi()$/ +ctoi codefrag.c /^PUBLIC void ctoi()$/ +dbitem debug.c /^PUBLIC void dbitem(item)$/ +dbtype debug.c /^PUBLIC void dbtype(type)$/ +debug debug.c /^PUBLIC void debug(exp) /* sub-nodes must be leaves */$/ +debugswap debug.c /^PUBLIC void debugswap()$/ +decllist declare.c /^PUBLIC void decllist()$/ +defbyte codefrag.c /^PUBLIC void defbyte()$/ +defbyte codefrag.c /^PUBLIC void defbyte()$/ +defdword codefrag.c /^PUBLIC void defdword()$/ +define preproc.c /^PUBLIC void define()$/ +definestring preproc.c /^PUBLIC void definestring(str)$/ +deflabel label.c /^PUBLIC void deflabel(label)$/ +deflong codefrag.c /^PUBLIC void deflong(value)$/ +defnulls codefrag.c /^PUBLIC void defnulls(nullcount)$/ +defstr codefrag.c /^PUBLIC label_t defstr(sptr, stop, dataflag)$/ +defword codefrag.c /^PUBLIC void defword()$/ +defword codefrag.c /^PUBLIC void defword()$/ +defword codefrag.c /^PUBLIC void defword()$/ +delsym table.c /^PUBLIC void delsym(symptr)$/ +diveasy codefrag.c /^PUBLIC bool_pt diveasy(divisor, uflag)$/ +docontrol preproc.c /^PUBLIC void docontrol()$/ +dpseg codefrag.c /^PUBLIC void dpseg()$/ +dseg codefrag.c /^PUBLIC void dseg()$/ +dumpglbs table.c /^PUBLIC void dumpglbs()$/ +dumplocs table.c /^PUBLIC void dumplocs()$/ +dumpstrings table.c /^PUBLIC void dumpstrings()$/ +entermac preproc.c /^PUBLIC void entermac()$/ +eofin scan.c /^PUBLIC void eofin(message)$/ +equ codefrag.c /^PUBLIC void equ(name, string)$/ +equlab codefrag.c /^PUBLIC void equlab(label, offset)$/ +error output.c /^PUBLIC void error(message)$/ +error2error output.c /^PUBLIC void error2error(message1, message2)$/ +errorloc input.c /^PUBLIC void errorloc()$/ +etreeinit exptree.c /^PUBLIC void etreeinit()$/ +even codefrag.c /^PUBLIC void even()$/ +exchange genloads.c /^PUBLIC void exchange(source, target)$/ +expression express.c /^PUBLIC struct nodestruct *expression()$/ +exprsym table.c /^PUBLIC struct symstruct *exprsym(symptr)$/ +extend assign.c /^PUBLIC void extend(target)$/ +f_indirect floatop.c /^PUBLIC bool_pt f_indirect(target)$/ +fatalerror output.c /^PUBLIC void fatalerror(message)$/ +findlorg table.c /^PUBLIC struct symstruct *findlorg(name)$/ +findstruct table.c /^PUBLIC struct symstruct *findstruct(name)$/ +finishup output.c /^PUBLIC void finishup()$/ +float1op floatop.c /^PUBLIC void float1op(op, source)$/ +floatop floatop.c /^PUBLIC void floatop(op, source, target)$/ +flushout output.c /^PUBLIC void flushout()$/ +for table.c /^ for (i = 0; i < HASHTABSIZE; ++i)$/ +for table.c /^for (tp = &ts[0]; tp < &ts[sizeof ts / sizeof ts[0]]; ++tp)$/ +fpush floatop.c /^PUBLIC void fpush(source)$/ +function function.c /^PUBLIC void function(source)$/ +gch1 input.c /^PUBLIC void gch1()$/ +gethashptr table.c /^PUBLIC struct symstruct **gethashptr(sname)$/ +gethighlabel label.c /^PUBLIC label_t gethighlabel()$/ +getindexreg genloads.c /^PUBLIC store_pt getindexreg()$/ +getlabel label.c /^PUBLIC label_t getlabel()$/ +getlc label.c /^PUBLIC uoffset_t getlc()$/ +globl codefrag.c /^PUBLIC void globl(name)$/ +growheap table.c /^PUBLIC void growheap(size)$/ +growobject table.c /^PUBLIC void *growobject(object, extra)$/ +highbit gencode.c /^PUBLIC fastin_pt highbit(number)$/ +holdstr table.c /^PUBLIC label_t holdstr(sptr, stop)$/ +ifinit preproc.c /^PUBLIC void ifinit()$/ +import codefrag.c /^PUBLIC void import(name)$/ +incdec hardop.c /^PUBLIC void incdec(op, source)$/ +include input.c /^PUBLIC void include()$/ +indexadr genloads.c /^PUBLIC void indexadr(source, target)$/ +indirec genloads.c /^PUBLIC void indirec(source)$/ +initexpression loadexp.c /^PUBLIC void initexpression(type)$/ +initout output.c /^PUBLIC void initout()$/ +iscalartotype type.c /^PUBLIC struct typestruct *iscalartotype(scalar)$/ +isident scan.c /^PUBLIC bool_pt isident()$/ +itol codefrag.c /^PUBLIC void itol(reg)$/ +jump label.c /^PUBLIC void jump(label)$/ +jumpfalse glogcode.c /^PUBLIC void jumpfalse(exp, label)$/ +jumptrue glogcode.c /^PUBLIC void jumptrue(exp, label)$/ +justpushed floatop.c /^PUBLIC void justpushed(target)$/ +lbranch label.c /^PUBLIC void lbranch(cond, label)$/ +lcommlab codefrag.c /^PUBLIC void lcommlab(label)$/ +lcommon codefrag.c /^PUBLIC void lcommon(name)$/ +ldregargs function.c /^PUBLIC void ldregargs()$/ +lea codefrag.c /^PUBLIC void lea(offset, sourcereg, targreg)$/ +leafnode exptree.c /^PUBLIC struct nodestruct *leafnode(source)$/ +leavemac preproc.c /^PUBLIC void leavemac()$/ +limiterror output.c /^PUBLIC void limiterror(message)$/ +listo function.c /^PUBLIC void listo(target, lastargsp)$/ +listroot function.c /^PUBLIC void listroot(target)$/ +load genloads.c /^PUBLIC void load(source, targreg)$/ +loadany genloads.c /^PUBLIC void loadany(source)$/ +loadconst codefrag.c /^PUBLIC void loadconst(offset, reg)$/ +loadexpression loadexp.c /^PUBLIC struct typestruct *loadexpression(targreg, targtype)$/ +loadpres preserve.c /^PUBLIC void loadpres(source, target)$/ +loadreg genloads.c /^PUBLIC void loadreg(source, targreg)$/ +loadretexpression function.c /^PUBLIC void loadretexpression()$/ +logop glogcode.c /^PUBLIC void logop(exp)$/ +long1op longop.c /^PUBLIC void long1op(op, target)$/ +longop longop.c /^PUBLIC void longop(op, source, target)$/ +lparen declare.c /^PUBLIC void lparen()$/ +lslconst codefrag.c /^PUBLIC int lslconst(shift, reg)$/ +lsrconst codefrag.c /^PUBLIC int lsrconst(shift, reg, uflag)$/ +main bcc-cc1.c /^PUBLIC int main(argc, argv)$/ +main bcc.c /^PUBLIC int main(argc, argv)$/ +makeleaf gencode.c /^PUBLIC void makeleaf(exp)$/ +makelessindirect genloads.c /^PUBLIC void makelessindirect(source)$/ +modeasy codefrag.c /^PUBLIC bool_pt modeasy(divisor, uflag)$/ +modstk preserve.c /^PUBLIC void modstk(newsp)$/ +movereg genloads.c /^PUBLIC void movereg(source, targreg)$/ +muleasy codefrag.c /^PUBLIC bool_pt muleasy(factor, reg)$/ +namedlabel label.c /^PUBLIC struct symstruct *namedlabel()$/ +needvarname declare.c /^PUBLIC void needvarname()$/ +neg hardop.c /^PUBLIC void neg(target)$/ +negDreg codefrag.c /^PUBLIC void negDreg()$/ +negDreg codefrag.c /^PUBLIC void negDreg()$/ +negreg codefrag.c /^PUBLIC void negreg(reg)$/ +newlevel table.c /^PUBLIC void newlevel()$/ +newtype type.c /^PUBLIC struct typestruct *newtype()$/ +nextsym scan.c /^PUBLIC void nextsym()$/ +node exptree.c /^PUBLIC struct nodestruct *node(t, p1, p2)$/ +not hardop.c /^PUBLIC void not(target)$/ +oldlevel table.c /^PUBLIC void oldlevel()$/ +onstack genloads.c /^PUBLIC void onstack(target)$/ +op1 hardop.c /^PUBLIC void op1(op, source, target)$/ +openio input.c /^PUBLIC void openio(argc, argv)$/ +openout output.c /^PUBLIC void openout(oname)$/ +opstring codefrag.c /^PUBLIC char *opstring(op)$/ +ourfree table.c /^PUBLIC void ourfree(ptr)$/ +ourmalloc table.c /^PUBLIC void *ourmalloc(nbytes)$/ +outABX codefrag.c /^PUBLIC void outABX()$/ +outadd codefrag.c /^PUBLIC void outadd()$/ +outadd codefrag.c /^PUBLIC void outadd()$/ +outaddsp codefrag.c /^PUBLIC void outaddsp()$/ +outaddsp codefrag.c /^PUBLIC void outaddsp()$/ +outadr genloads.c /^PUBLIC void outadr(adr)$/ +outbyte output.c /^PUBLIC void outbyte(c)$/ +outcalladr codefrag.c /^PUBLIC void outcalladr()$/ +outcalladr codefrag.c /^PUBLIC void outcalladr()$/ +outcalladr codefrag.c /^PUBLIC void outcalladr()$/ +outccname codefrag.c /^PUBLIC void outccname(name)$/ +outcmp codefrag.c /^PUBLIC void outcmp()$/ +outcmp codefrag.c /^PUBLIC void outcmp()$/ +outcomma output.c /^PUBLIC void outcomma()$/ +outcond label.c /^PUBLIC void outcond(cond)$/ +outcpplinenumber output.c /^PUBLIC void outcpplinenumber(nr, fname, str)$/ +outcregname genloads.c /^PUBLIC void outcregname(reg)$/ +outdec codefrag.c /^PUBLIC void outdec()$/ +outdec codefrag.c /^PUBLIC void outdec()$/ +outdirectpage codefrag.c /^PUBLIC void outdirectpage()$/ +outdword codefrag.c /^PUBLIC void outdword()$/ +outextended codefrag.c /^PUBLIC void outextended()$/ +outfail codefrag.c /^PUBLIC void outfail()$/ +outfail codefrag.c /^PUBLIC void outfail()$/ +outhex output.c /^PUBLIC void outhex(num)$/ +outhexdigs output.c /^PUBLIC void outhexdigs(num)$/ +outhiaccum codefrag.c /^PUBLIC void outhiaccum()$/ +outimadj codefrag.c /^PUBLIC void outimadj(offset, targreg)$/ +outimmadr codefrag.c /^PUBLIC void outimmadr(offset)$/ +outimmed codefrag.c /^PUBLIC void outimmed()$/ +outinc codefrag.c /^PUBLIC void outinc()$/ +outinc codefrag.c /^PUBLIC void outinc()$/ +outindframereg codefrag.c /^PUBLIC void outindframereg()$/ +outindleft codefrag.c /^PUBLIC void outindleft()$/ +outindleft codefrag.c /^PUBLIC void outindleft()$/ +outindleft codefrag.c /^PUBLIC void outindleft()$/ +outindright codefrag.c /^PUBLIC void outindright()$/ +outindright codefrag.c /^PUBLIC void outindright()$/ +outindright codefrag.c /^PUBLIC void outindright()$/ +outindstackreg codefrag.c /^PUBLIC void outindstackreg()$/ +outjumpstring codefrag.c /^PUBLIC void outjumpstring()$/ +outlabel label.c /^PUBLIC void outlabel(label)$/ +outldaccum codefrag.c /^PUBLIC void outldaccum()$/ +outldaccum codefrag.c /^PUBLIC void outldaccum()$/ +outldmulreg codefrag.c /^PUBLIC void outldmulreg()$/ +outldmulreg codefrag.c /^PUBLIC void outldmulreg()$/ +outlea codefrag.c /^PUBLIC void outlea()$/ +outlea codefrag.c /^PUBLIC void outlea()$/ +outleasp codefrag.c /^PUBLIC void outleasp()$/ +outleasp codefrag.c /^PUBLIC void outleasp()$/ +outline output.c /^PUBLIC void outline(s)$/ +outload codefrag.c /^PUBLIC void outload()$/ +outload codefrag.c /^PUBLIC void outload()$/ +outlongendian longop.c /^PUBLIC void outlongendian()$/ +outminus output.c /^PUBLIC void outminus()$/ +outmulmulreg codefrag.c /^PUBLIC void outmulmulreg()$/ +outmulmulreg codefrag.c /^PUBLIC void outmulmulreg()$/ +outnbyte output.c /^PUBLIC void outnbyte(byte)$/ +outnccname codefrag.c /^PUBLIC void outnccname(name)$/ +outncimmadr codefrag.c /^PUBLIC void outncimmadr(offset)$/ +outncregname genloads.c /^PUBLIC void outncregname(reg)$/ +outncspregname codefrag.c /^PUBLIC void outncspregname()$/ +outnhex output.c /^PUBLIC void outnhex(num)$/ +outnl output.c /^PUBLIC void outnl()$/ +outnlabel label.c /^PUBLIC void outnlabel(label)$/ +outnop1str output.c /^PUBLIC void outnop1str(s)$/ +outnop2str output.c /^PUBLIC void outnop2str(s)$/ +outnregname genloads.c /^PUBLIC void outnregname(reg)$/ +outnstr output.c /^PUBLIC void outnstr(s)$/ +outntypechar type.c /^PUBLIC void outntypechar(type)$/ +outoffset codefrag.c /^PUBLIC void outoffset(offset)$/ +outofmemoryerror table.c /^PUBLIC void outofmemoryerror(message)$/ +outop0str output.c /^PUBLIC void outop0str(s)$/ +outop1str output.c /^PUBLIC void outop1str(s)$/ +outop2str output.c /^PUBLIC void outop2str(s)$/ +outop3str output.c /^PUBLIC void outop3str(s)$/ +outopsep codefrag.c /^PUBLIC void outopsep()$/ +outopsep codefrag.c /^PUBLIC void outopsep()$/ +outplus output.c /^PUBLIC void outplus()$/ +outpshs codefrag.c /^PUBLIC void outpshs()$/ +outpshs codefrag.c /^PUBLIC void outpshs()$/ +outpuls codefrag.c /^PUBLIC void outpuls()$/ +outpuls codefrag.c /^PUBLIC void outpuls()$/ +outregname genloads.c /^PUBLIC void outregname(reg)$/ +outreturn codefrag.c /^PUBLIC void outreturn()$/ +outreturn codefrag.c /^PUBLIC void outreturn()$/ +outshex output.c /^PUBLIC void outshex(num)$/ +outshortregname genloads.c /^PUBLIC void outshortregname(reg)$/ +outstore codefrag.c /^PUBLIC void outstore()$/ +outstore codefrag.c /^PUBLIC void outstore()$/ +outstr output.c /^PUBLIC void outstr(s)$/ +outsub codefrag.c /^PUBLIC void outsub()$/ +outsub codefrag.c /^PUBLIC void outsub()$/ +outswoffset state.c /^PUBLIC void outswoffset (offset)$/ +outswstacklab state.c /^PUBLIC void outswstacklab()$/ +outtab output.c /^PUBLIC void outtab()$/ +outtest codefrag.c /^PUBLIC void outtest()$/ +outtest codefrag.c /^PUBLIC void outtest()$/ +outudec output.c /^PUBLIC void outudec(num)$/ +outuvalue output.c /^PUBLIC void outuvalue(num)$/ +outvalue output.c /^PUBLIC void outvalue(num)$/ +outword codefrag.c /^PUBLIC void outword()$/ +pointat genloads.c /^PUBLIC void pointat(target)$/ +pointype type.c /^PUBLIC struct typestruct *pointype(type)$/ +popframe function.c /^PUBLIC void popframe()$/ +poplist genloads.c /^PUBLIC void poplist(reglist)$/ +predefine preproc.c /^PUBLIC void predefine()$/ +prefix type.c /^PUBLIC struct typestruct *prefix(constructor, size, type)$/ +pres2 preserve.c /^PUBLIC void pres2(source, target)$/ +preserve preserve.c /^PUBLIC void preserve(source)$/ +preslval preserve.c /^PUBLIC store_pt preslval(source, target)$/ +program declare.c /^PUBLIC void program()$/ +promote type.c /^PUBLIC struct typestruct *promote(type)$/ +ptrsub hardop.c /^PUBLIC void ptrsub(source, target)$/ +public codefrag.c /^PUBLIC void public(name)$/ +push genloads.c /^PUBLIC void push(source)$/ +pushlist genloads.c /^PUBLIC void pushlist(reglist)$/ +pushreg genloads.c /^PUBLIC void pushreg(reg)$/ +pushudec output.c /^PUBLIC char *pushudec(s, num)$/ +qmalloc table.c /^PUBLIC void *qmalloc(size)$/ +rbrace declare.c /^PUBLIC void rbrace()$/ +rbracket declare.c /^PUBLIC void rbracket()$/ +recovlist preserve.c /^PUBLIC void recovlist(reglist)$/ +regexchange codefrag.c /^PUBLIC void regexchange(sourcereg, targreg)$/ +regtransfer codefrag.c /^PUBLIC void regtransfer(sourcereg, targreg)$/ +reslocals function.c /^PUBLIC void reslocals()$/ +restoreopreg codefrag.c /^PUBLIC void restoreopreg()$/ +ret function.c /^PUBLIC void ret()$/ +rparen declare.c /^PUBLIC void rparen()$/ +savedlineptr preproc.c /^PUBLIC char *savedlineptr()$/ +saveopreg codefrag.c /^PUBLIC void saveopreg()$/ +savereturn preserve.c /^PUBLIC void savereturn(savelist, saveoffset)$/ +sbc0 codefrag.c /^PUBLIC void sbc0()$/ +sbranch label.c /^PUBLIC void sbranch(cond, label)$/ +sctoi codefrag.c /^PUBLIC void sctoi()$/ +sctoi codefrag.c /^PUBLIC void sctoi()$/ +semicolon declare.c /^PUBLIC void semicolon()$/ +set codefrag.c /^PUBLIC void set(name, value)$/ +setoutbufs output.c /^PUBLIC void setoutbufs()$/ +skipcomment preproc.c /^PUBLIC void skipcomment()$/ +skipeol input.c /^PUBLIC void skipeol()$/ +skipline preproc.c /^PUBLIC void skipline()$/ +sl1 codefrag.c /^PUBLIC void sl1(reg)$/ +slconst codefrag.c /^PUBLIC void slconst(shift, reg)$/ +softop softop.c /^PUBLIC void softop(op, source, target)$/ +specialchar input.c /^PUBLIC void specialchar()$/ +srconst codefrag.c /^PUBLIC void srconst(shift, uflag)$/ +stoi codefrag.c /^PUBLIC void stoi()$/ +storereg genloads.c /^PUBLIC void storereg(sourcereg, target)$/ +stringorcharconst scan.c /^PUBLIC void stringorcharconst()$/ +struc genloads.c /^PUBLIC void struc(source, target)$/ +sub hardop.c /^PUBLIC void sub(source, target)$/ +swapsym table.c /^PUBLIC void swapsym(sym1, sym2)$/ +syminit table.c /^PUBLIC void syminit()$/ +tounsigned type.c /^PUBLIC struct typestruct *tounsigned(type)$/ +transfer genloads.c /^PUBLIC void transfer(source, targreg)$/ +typeinit type.c /^PUBLIC void typeinit()$/ +typename declare.c /^PUBLIC struct typestruct *typename()$/ +uitol codefrag.c /^PUBLIC void uitol(reg)$/ +unbumplc label.c /^PUBLIC void unbumplc()$/ +undefinestring preproc.c /^PUBLIC void undefinestring(str)$/ +ustoi codefrag.c /^PUBLIC void ustoi()$/ diff --git a/bcc-bruce/type.c b/bcc/type.c index 4852c9d..4852c9d 100644 --- a/bcc-bruce/type.c +++ b/bcc/type.c diff --git a/bcc-bruce/type.h b/bcc/type.h index c451283..c451283 100644 --- a/bcc-bruce/type.h +++ b/bcc/type.h diff --git a/bcc-bruce/types.h b/bcc/types.h index 547637c..755b8b1 100644 --- a/bcc-bruce/types.h +++ b/bcc/types.h @@ -34,7 +34,7 @@ typedef unsigned store_pt; /* promoted store_t */ typedef unsigned store_t; /* storage class flags */ #endif #ifdef MC6809 -# if __STDC__ +#ifdef __STDC__ typedef int store_pt; # else typedef unsigned store_pt; @@ -71,7 +71,7 @@ typedef char smalin_t; /* small int - a small integer value */ /* change to fastin_t if this is not true */ /* or if char has < 8 bits */ /* or if space is not a limiting factor */ -#if __STDC__ +#ifdef __STDC__ typedef int smalu_pt; #else typedef unsigned smalu_pt; diff --git a/bin86-0.3/ChangeLog b/bin86-0.3/ChangeLog deleted file mode 100644 index 1e6d936..0000000 --- a/bin86-0.3/ChangeLog +++ /dev/null @@ -1,67 +0,0 @@ -Tue May 16 22:01:05 1995 H.J. Lu (hjl@nynexst.com) - - * version 0.3 is released. - - * Makefile: fix a few typos. - - * as/const.h: include "endian.h". - (LOW_BYTE): check the byte order. - - * Makefile (endian.h): new target. - (const.h): depend on endian.h. - - * as/det_endian.c: new from glibc. - -Sat Mar 18 16:39:19 1995 Francois-Rene Rideau (rideau@clipper.ens.fr) - - * as/pops.c (doif): support nested conditionals. - -Mon Nov 21 22:48:26 1994 H.J. Lu (hlu@nighthawk) - - * version 0.2 is released. - - * Makefile (MFLAGS): new. add BINDIR and CC. - -Fri Nov 18 22:25:24 1994 Package Maintainer (opt@calum.csclub.uwaterloo.ca) - - * ./as/Makefile: - * ./as/const.h: - * ./as/proto.h: - * ./as/readsrc.c: - * ./as/type.h: - * ./ld/Makefile: - * ./ld/align.h: - * ./ld/config.h: - * ./ld/type.h: - * ./ld/typeconv.c: remove endian dependency. - -Thu Mar 3 15:12:23 1994 H.J. Lu (hlu@nighthawk) - - * version 0.1 is released. - - * Makefile: new. - - * a.out.h/bsd-a.out.h (struct exec): use short form if - __linux__ is defined. - - * as/Makefile: minor changes. - (CLFAGS): add -I../a.out.h. - - * ld/Makefile: minor changes. - (CLFAGS): add -I../a.out.h. - - * ld/io.c (MY_STAT_H): don't define it if __linux__ is - defined. - - * ld/ld.c (flag['z']): initialized to 0 if __linux__ is - defined. - - * ld/obj.h (roundup): - * ld/writebin.c (roundup): - ld/readobj.c (roundup): change that to ld_roundup to avoid the - conflict with the system's roundup. - - * ld/writebin.c: cleanup for the latest Linux C library. - (FILEHEADERLENGTH): change to sizeof (struct exec). - don't write a_trsize and its friends. - diff --git a/bin86-0.3/Makefile b/bin86-0.3/Makefile deleted file mode 100644 index 62a0730..0000000 --- a/bin86-0.3/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -CC=gcc -CFLAGS=-O6 -fomit-frame-pointer -LDFLAGS= -# Where to get strtoul ()? -#LIBS=-liberty -DIRS=ld as - -BINDIR=/usr/gnu/i486-linux/bin -AS86=i486-linux-ld86 -LD86=i486-linux-ld86 - -BINDIR=/usr/bin -AS86=as86 -LD86=ld86 - -STRIP=strip - -MFLAGS= "LIBS=$(LIBS)" \ - "CFLAGS=$(CFLAGS)" \ - "LDFLAGS=$(LDFLAGS)" \ - "CC=$(CC)" - -all: - for d in $(DIRS); do \ - (cd $$d; $(MAKE) $(MFLAGS) $@;); \ - done - -install: all - cp as/as86 $(BINDIR)/$(AS86) - cp ld/ld86 $(BINDIR)/$(LD86) - $(STRIP) $(BINDIR)/$(AS86) $(BINDIR)/$(LD86) - -depend clean clobber: - for d in $(DIRS); do \ - (cd $$d; $(MAKE) $(MFLAGS) $@;); \ - done diff --git a/bin86-0.3/README b/bin86-0.3/README deleted file mode 100644 index f91a9dc..0000000 --- a/bin86-0.3/README +++ /dev/null @@ -1,79 +0,0 @@ -To build this real mode as/ld for x86, just edit Makefile and then -do - -make install - -It is only tested under SunOS 4.1.3 and Linux. - -H.J. Lu -hjl@nynexst.com -11/21/94 ------- -We seem to have cross bin86 for Solaris working. The most important -changes involve alignment (it needs to be on) and byte ordering. -Some of the patches just eliminate compiler warnings (conversion of -pointer to integer without a cast, etc.) and some (in the Makefiles) -reflect the local setup, and can probably be ignored (the change to $BINDIR, -for example). - - - Ian (iagoldbe@csclub.uwaterloo.ca) - ----- -I modified it for the latest Linux C library 4.5.21 and released it as -bin86 0.1. It is only tested for building the Linux kernel and is not -intended for any other purposes. To build it under Linux, just type - -make all -make install - -It is not tested for cross-compiling. If you have any patches for -cross-compiling, please send them to me. - -Thanks. - - -H.J. Lu -hjl@nynexst.com -03/03/94 -------------- -This is the as86 and ld86 distribution written by Bruce Evans. It's -copyright Bruce Evans, all rights reserved although you may use and copy -it for your personal use. It's a complete 8086 assembler and loader -which can make 32-bit code for the 386+ processors (under linux it's -used only to create the 16-bit bootsector and setup binaries). The -syntax is not compatible with the GNU assembler, but closer to intel -syntax ("wrong" order of operands etc). - -Hints for compiling: - - - you'll need the a.out.h-files from the a.out.h directory for the -linker. These aren't really part of the distribution, but I included -them for ease of setup (in case you need to crosscompile etc). Do a - cp a.out.h/* ld/ -or similar before compiling the linker. - - - the assembler needs the typeconv.o file produced by the linker -compilation. So compile the linker first, and then do a - cp ld/typeconv.o as/ -before making the assembler. - -This distribution also contains some test-files etc that aren't actually -needed, but as they also give some idea of the assembler syntax, I left -them in. The directories are as follows: - - as - the assembler sources (minus typeconv.c) - ld - linker sources - bcc - bruce evans' cc frontend sources (the actual compiler isn't - included). - bccfp - assembly floating point routines written by bruce evans. Note - that these use integer register returns, and won't work with the - linux libraries. They can be used as examples of as86 code. - a.out.h - header files for crosscompilation. - -Note that I am NOT the author of this package, but I'll forward any -comments to bruce evans and I'll try to answer any questions about the -assembler/linker I can. I just made it available as bde doesn't have -ftp capability right now. Bruce Evans does have mail as -<bde@runx.oz.au>. - - Linus Torvalds diff --git a/bin86-0.3/a.out.h/a.out.gnu.h b/bin86-0.3/a.out.h/a.out.gnu.h deleted file mode 100644 index bf6d4d9..0000000 --- a/bin86-0.3/a.out.h/a.out.gnu.h +++ /dev/null @@ -1,276 +0,0 @@ -#ifndef __A_OUT_GNU_H__ -#define __A_OUT_GNU_H__ - -#if defined(sequent) && defined(i386) -#define a_magic a_info -#include <a.out.h> -#undef a_magic -#define __STRUCT_EXEC_OVERRIDE__ -#define N_NLIST_DECLARED -#define N_RELOCATION_INFO_DECLARED -#endif - -#define __GNU_EXEC_MACROS__ - -#ifndef __STRUCT_EXEC_OVERRIDE__ - -struct exec -{ - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned long a_text; /* length of text, in bytes */ - unsigned long a_data; /* length of data, in bytes */ - unsigned long a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned long a_syms; /* length of symbol table data in file, in bytes */ - unsigned long a_entry; /* start address */ - unsigned long a_trsize; /* length of relocation info for text, in bytes */ - unsigned long a_drsize; /* length of relocation info for data, in bytes */ -}; - -#endif /* __STRUCT_EXEC_OVERRIDE__ */ - -/* these go in the N_MACHTYPE field */ -enum machine_type { -#if defined (M_OLDSUN2) - M__OLDSUN2 = M_OLDSUN2, -#else - M_OLDSUN2 = 0, -#endif -#if defined (M_68010) - M__68010 = M_68010, -#else - M_68010 = 1, -#endif -#if defined (M_68020) - M__68020 = M_68020, -#else - M_68020 = 2, -#endif -#if defined (M_SPARC) - M__SPARC = M_SPARC, -#else - M_SPARC = 3, -#endif - /* skip a bunch so we don't run into any of sun's numbers */ - M_386 = 100, -}; - -#if !defined (N_MAGIC) -#define N_MAGIC(exec) ((exec).a_info & 0xffff) -#endif -#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff)) -#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff) -#define N_SET_INFO(exec, magic, type, flags) \ - ((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0xff) << 16) \ - | (((flags) & 0xff) << 24)) -#define N_SET_MAGIC(exec, magic) \ - ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff))) - -#define N_SET_MACHTYPE(exec, machtype) \ - ((exec).a_info = \ - ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16)) - -#define N_SET_FLAGS(exec, flags) \ - ((exec).a_info = \ - ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24)) - -#ifndef OMAGIC -/* Code indicating object file or impure executable. */ -#define OMAGIC 0407 -/* Code indicating pure executable. */ -#define NMAGIC 0410 -/* Code indicating demand-paged executable. */ -#define ZMAGIC 0413 -#endif /* not OMAGIC */ - -#if !defined (N_BADMAG) -#define N_BADMAG(x) \ - (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC) -#endif - -#define _N_BADMAG(x) \ - (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC) - -#define _N_HDROFF(x) (SEGMENT_SIZE - sizeof (struct exec)) - -#if !defined (N_TXTOFF) -#define N_TXTOFF(x) \ - (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec)) -#endif - -#if !defined (N_DATOFF) -#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text) -#endif - -#if !defined (N_TRELOFF) -#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data) -#endif - -#if !defined (N_DRELOFF) -#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize) -#endif - -#if !defined (N_SYMOFF) -#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize) -#endif - -#if !defined (N_STROFF) -#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms) -#endif - -/* Address of text segment in memory after it is loaded. */ -#if !defined (N_TXTADDR) -#define N_TXTADDR(x) 0 -#endif - -/* Address of data segment in memory after it is loaded. - Note that it is up to you to define SEGMENT_SIZE - on machines not listed here. */ -#if defined(vax) || defined(hp300) || defined(pyr) -#define SEGMENT_SIZE PAGE_SIZE -#endif -#ifdef hp300 -#define PAGE_SIZE 4096 -#endif -#ifdef sony -#define SEGMENT_SIZE 0x2000 -#endif /* Sony. */ -#ifdef is68k -#define SEGMENT_SIZE 0x20000 -#endif -#if defined(m68k) && defined(PORTAR) -#define PAGE_SIZE 0x400 -#define SEGMENT_SIZE PAGE_SIZE -#endif - -#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1)) - -#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text) - -#ifndef N_DATADDR -#define N_DATADDR(x) \ - (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \ - : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x)))) -#endif - -/* Address of bss segment in memory after it is loaded. */ -#if !defined (N_BSSADDR) -#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) -#endif - -#if !defined (N_NLIST_DECLARED) -struct nlist { - union { - char *n_name; - struct nlist *n_next; - long n_strx; - } n_un; - unsigned char n_type; - char n_other; - short n_desc; - unsigned long n_value; -}; -#endif /* no N_NLIST_DECLARED. */ - -#if !defined (N_UNDF) -#define N_UNDF 0 -#endif -#if !defined (N_ABS) -#define N_ABS 2 -#endif -#if !defined (N_TEXT) -#define N_TEXT 4 -#endif -#if !defined (N_DATA) -#define N_DATA 6 -#endif -#if !defined (N_BSS) -#define N_BSS 8 -#endif -#if !defined (N_COMM) -#define N_COMM 18 -#endif -#if !defined (N_FN) -#define N_FN 15 -#endif - -#if !defined (N_EXT) -#define N_EXT 1 -#endif -#if !defined (N_TYPE) -#define N_TYPE 036 -#endif -#if !defined (N_STAB) -#define N_STAB 0340 -#endif - -/* The following type indicates the definition of a symbol as being - an indirect reference to another symbol. The other symbol - appears as an undefined reference, immediately following this symbol. - - Indirection is asymmetrical. The other symbol's value will be used - to satisfy requests for the indirect symbol, but not vice versa. - If the other symbol does not have a definition, libraries will - be searched to find a definition. */ -#define N_INDR 0xa - -/* The following symbols refer to set elements. - All the N_SET[ATDB] symbols with the same name form one set. - Space is allocated for the set in the text section, and each set - element's value is stored into one word of the space. - The first word of the space is the length of the set (number of elements). - - The address of the set is made into an N_SETV symbol - whose name is the same as the name of the set. - This symbol acts like a N_DATA global symbol - in that it can satisfy undefined external references. */ - -/* These appear as input to LD, in a .o file. */ -#define N_SETA 0x14 /* Absolute set element symbol */ -#define N_SETT 0x16 /* Text set element symbol */ -#define N_SETD 0x18 /* Data set element symbol */ -#define N_SETB 0x1A /* Bss set element symbol */ - -/* This is output from LD. */ -#define N_SETV 0x1C /* Pointer to set vector in data area. */ - -#if !defined (N_RELOCATION_INFO_DECLARED) -/* This structure describes a single relocation to be performed. - The text-relocation section of the file is a vector of these structures, - all of which apply to the text section. - Likewise, the data-relocation section applies to the data section. */ - -struct relocation_info -{ - /* Address (within segment) to be relocated. */ - unsigned long r_address; -#if 0 - /* The meaning of r_symbolnum depends on r_extern. */ - unsigned int r_symbolnum:24; - /* Nonzero means value is a pc-relative offset - and it should be relocated for changes in its own address - as well as for changes in the symbol or section specified. */ - unsigned int r_pcrel:1; - /* Length (as exponent of 2) of the field to be relocated. - Thus, a value of 2 indicates 1<<2 bytes. */ - unsigned int r_length:2; - /* 1 => relocate with value of symbol. - r_symbolnum is the index of the symbol - in file's the symbol table. - 0 => relocate with the address of a segment. - r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS - (the N_EXT bit may be set also, but signifies nothing). */ - unsigned int r_extern:1; - /* Four bits that aren't used, but when writing an object file - it is desirable to clear them. */ - unsigned int r_pad:4; -#else - unsigned long foo; -#endif -}; -#endif /* no N_RELOCATION_INFO_DECLARED. */ - - -#endif /* __A_OUT_GNU_H__ */ diff --git a/bin86-0.3/a.out.h/bsd-a.out.h b/bin86-0.3/a.out.h/bsd-a.out.h deleted file mode 100644 index b59435b..0000000 --- a/bin86-0.3/a.out.h/bsd-a.out.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef _BSD_A_OUT_H -#define _BSD_A_OUT_H - -struct exec { /* a.out header */ - unsigned char a_magic[2]; /* magic number */ - unsigned char a_flags; /* flags, see below */ - unsigned char a_cpu; /* cpu id */ - unsigned char a_hdrlen; /* length of header */ - unsigned char a_unused; /* reserved for future use */ - unsigned short a_version; /* version stamp (not used at present) */ - 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 */ - long a_entry; /* entry point */ - long a_total; /* total memory allocated */ - long a_syms; /* size of symbol table */ - /* SHORT FORM ENDS HERE */ -#ifndef __linux__ - long a_trsize; /* text relocation size */ - long a_drsize; /* data relocation size */ - long a_tbase; /* text relocation base */ - long a_dbase; /* data relocation base */ -#endif -}; - -#define A_MAGIC0 ((unsigned char) 0x01) -#define A_MAGIC1 ((unsigned char) 0x03) -#define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 || (X).a_magic[1] != A_MAGIC1) - -/* CPU Id of TARGET machine (byte order coded in low order two bits) */ -#define A_NONE 0x00 /* unknown */ -#define A_I8086 0x04 /* intel i8086/8088 */ -#define A_M68K 0x0B /* motorola m68000 */ -#define A_NS16K 0x0C /* national semiconductor 16032 */ -#define A_I80386 0x10 /* intel i80386 */ -#define A_SPARC 0x17 /* Sun SPARC */ - -#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */ -#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ - -/* Flags. */ -#define A_UZP 0x01 /* unmapped zero page (pages) */ -#define A_EXEC 0x10 /* executable */ -#define A_SEP 0x20 /* separate I/D */ -#define A_PURE 0x40 /* pure text */ /* not used */ -#define A_TOVLY 0x80 /* text overlay */ /* not used */ - -/* Tell a.out.gnu.h not to define `struct exec'. */ -#define __STRUCT_EXEC_OVERRIDE__ - -/* Hide M_386 from enum declaration in a.out.h. */ -#define M_386 HIDE_M_386 - -#include "a.out.gnu.h" - -#undef M_386 -#define M_386 A_I80386 - -#undef N_MAGIC -#define N_MAGIC3(magic0, magic1, type) \ - ((magic0) | ((magic1) << 8) | ((type) << 16)) -#define N_MAGIC(exec) \ - N_MAGIC3((exec).a_magic[0], (exec).a_magic[1], (exec).a_flags) - -#undef N_MACHTYPE -#define N_MACHTYPE(exec) ((enum machine_type)((exec).a_cpu)) - -#undef N_FLAGS -#define N_FLAGS(exec) 0 - -#undef N_SET_INFO -#define N_SET_INFO(exec, magic, type, flags) \ - ((exec).a_magic[0] = (magic) & 0xff, \ - (exec).a_magic[1] = ((magic) >> 8) & 0xff, \ - (exec).a_flags = ((magic) >> 16) & 0xff, \ - (exec).a_cpu = (type) & 0xff) - -#undef N_SET_MAGIC -#define N_SET_MAGIC(exec, magic) \ - ((exec).a_magic[0] = (magic) & 0xff, \ - (exec).a_magic[1] = ((magic) >> 8) & 0xff, \ - (exec).a_flags = ((magic) >> 16) & 0xff) - -#undef N_SET_MACHTYPE -#define N_SET_MACHTYPE(exec, machtype) \ - ((exec).a_cpu = (machtype) & 0xff, \ - (exec).a_hdrlen = sizeof (exec)) - -#undef N_SET_FLAGS -#define N_SET_FLAGS(exec, flags) /* nothing */ - -#undef OMAGIC -#define OMAGIC N_MAGIC3(A_MAGIC0, A_MAGIC1, 0) - -#undef NMAGIC -#define NMAGIC N_MAGIC3(A_MAGIC0, A_MAGIC1, A_EXEC) - -#undef ZMAGIC -#define ZMAGIC N_MAGIC3(A_MAGIC0, A_MAGIC1, A_EXEC) - -#undef _N_HDROFF -#define _N_HDROFF(x) 0 - -#define PAGE_SIZE 16 -#define SEGMENT_SIZE PAGE_SIZE -#define getpagesize() PAGE_SIZE - -#endif /* _BSD_A_OUT_H */ diff --git a/bin86-0.3/as/6809/const.h b/bin86-0.3/as/6809/const.h deleted file mode 100644 index 512c348..0000000 --- a/bin86-0.3/as/6809/const.h +++ /dev/null @@ -1,507 +0,0 @@ -/* - * bin86/as/6809/const.h - * - * Copyright (C) 1992 Bruce Evans - */ - -#define align(x) /* ((x) = ((int) (x) + (4-1)) & ~(4-1)) */ -#define LOW_BYTE 0 /* must be changed for big-endian */ - -/* const.h - constants for assembler */ - -/* major switches */ - -#undef I80386 /* generate 80386 code */ -#define MC6809 /* generate 6809 code */ -#define MNSIZE /* allow byte size in mnemonic, e.g. "movb" */ -#undef SOS_EDOS /* source OS is EDOS */ - -/* defaults */ - -#define DIRCHAR '/' /* character separating filename from dir */ -#define INBUFSIZE 8192 -#define SOS_EOLSTR "\012" - -/* defaults modified by switches */ - -#ifdef SOS_EDOS -# undef INBUFSIZE -# define INBUFSIZE 512 -# undef SOS_EOLSTR -# define SOS_EOLSTR "\015\012" -# define STAKSIZ 256 /* table grows up to stack less this */ -#endif - -/* booleans */ - -#define FALSE 0 -#define TRUE 1 - -/* ASCII constants */ - -#define ETB 23 - -/* C tricks */ - -#define EXTERN extern -#define FORWARD static -#define PRIVATE static -#define PUBLIC -#define NULL 0 - -/* O/S constants */ - -#define CREAT_PERMS 0666 -#define EOF (-1) -#define STDIN 0 -#define STDOUT 1 - -/* register codes (internal to assembler) */ - -#ifdef I80386 - -/* index regs must be first */ - -#define BPREG 0 -#define BXREG 1 -#define DIREG 2 -#define SIREG 3 -#define MAX16BITINDREG 3 - -#define EAXREG 4 -#define EBPREG 5 -#define EBXREG 6 -#define ECXREG 7 -#define EDIREG 8 -#define EDXREG 9 -#define ESIREG 10 -#define ESPREG 11 -#define MAXINDREG 11 - -#define AXREG 12 -#define CXREG 13 -#define DXREG 14 -#define SPREG 15 - -#define AHREG 16 -#define ALREG 17 -#define BHREG 18 -#define BLREG 19 -#define CHREG 20 -#define CLREG 21 -#define DHREG 22 -#define DLREG 23 - -#define CSREG 24 -#define DSREG 25 -#define ESREG 26 -#define FSREG 27 -#define GSREG 28 -#define SSREG 29 - -#define CR0REG 30 -#define CR2REG 31 -#define CR3REG 32 -#define DR0REG 33 -#define DR1REG 34 -#define DR2REG 35 -#define DR3REG 36 -#define DR6REG 37 -#define DR7REG 38 -#define TR6REG 39 -#define TR7REG 40 - -#define NOREG 41 - -#endif /* I80386 */ - -#ifdef MC6809 - -/* index regs must be first, then PC, then other regs */ - -#define AREG 5 -#define BREG 6 -#define CCREG 7 -#define DPREG 8 -#define DREG 9 -#define MAXINDREG 3 -#define NOREG 10 -#define PCREG 4 -#define SREG 0 -#define UREG 1 -#define XREG 2 -#define YREG 3 - -#endif - -#ifdef I80386 - -/* type and size keywords */ - -#define BYTEOP 0 -#define DWORDOP 1 -#define FWORDOP 2 -#define FAROP 3 -#define PTROP 4 -#define PWORDOP 5 -#define QWORDOP 6 -#define TBYTEOP 7 -#define WORDOP 8 -#endif - -/* special chars */ - -#define EOL 0 -#define MACROCHAR '?' - -/* symbol codes */ - -/* the first 2 must be from chars in identifiers */ -#define IDENT 0 -#define INTCONST 1 - -/* the next few are best for other possibly-multi-char tokens */ -#define ADDOP 2 /* also ++ */ -#define BINCONST 3 -#define CHARCONST 4 -#define GREATERTHAN 5 /* also >> and context-sensitive */ -#define HEXCONST 6 -#define LESSTHAN 7 /* also << and context-sensitive */ -#define SUBOP 8 /* also -- */ -#define WHITESPACE 9 - -#define ANDOP 10 -#define COMMA 11 -#define EOLSYM 12 -#define EQOP 13 -#define IMMEDIATE 14 -#define INDIRECT 15 -#define LBRACKET 16 -#define LPAREN 17 -#define MACROARG 18 -#define NOTOP 19 -#define OROP 20 -#define OTHERSYM 21 -#define POSTINCOP 22 -#define PREDECOP 23 -#define RBRACKET 24 -#define RPAREN 25 -#define SLASH 26 /* context-sensitive */ -#define SLOP 27 -#define SROP 28 -#define STAR 29 /* context-sensitive */ -#define STRINGCONST 30 -#define COLON 31 - -/* these are from assembler errors module */ - -/* syntax errors */ - -#define COMEXP 0 -#define DELEXP 1 -#define FACEXP 2 -#define IREGEXP 3 -#define LABEXP 4 -#define LPEXP 5 -#define OPEXP 6 -#define RBEXP 7 -#define REGEXP 8 -#define RPEXP 9 -#define SPEXP 10 - -/* expression errors */ - -#define ABSREQ 11 -#define NONIMPREQ 12 -#define RELBAD 13 - -/* label errors */ - -#define ILLAB 14 -#define MACUID 15 -#define MISLAB 16 -#define MNUID 17 -#define REGUID 18 -#define RELAB 19 -#define UNBLAB 20 -#define UNLAB 21 -#define VARLAB 22 - -/* addressing errors */ - -#define ABOUNDS 23 -#define DBOUNDS 24 -#define ILLMOD 25 -#define ILLREG 26 - -/* control structure errors */ - -#define ELSEBAD 27 -#define ELSEIFBAD 27 -#define ENDBBAD 28 -#define ENDIFBAD 27 -#define EOFBLOCK 29 -#define EOFIF 30 - -#define EOFLC 31 -#define EOFMAC 32 -#define FAILERR 33 - -/* overflow errors */ - -#define BLOCKOV 34 -#define BWRAP 35 -#define COUNTOV 36 -#define COUNTUN 37 -#define GETOV 38 -#define IFOV 39 - -#define LINLONG 40 -#define MACOV 41 -#define OBJSYMOV 42 -#define OWRITE 43 -#define PAROV 44 -#define SYMOV 45 -#define SYMOUTOV 46 - -/* i/o errors */ - -#define OBJOUT 47 - -/* miscellaneous errors */ - -#define CTLINS 48 -#define FURTHER 49 -#define NOIMPORT 50 -#define NOTIMPLEMENTED 51 -#define REENTER 52 -#define SEGREL 53 - -/* warnings */ - -#define MINWARN 54 -#define ALREADY 54 -#define SHORTB 55 - -/* symbol table entry */ - - /* type entry contains following flags */ -#define ENTBIT (1<<0) /* entry point (=OBJ_N_MASK) */ -#define COMMBIT (1<<1) /* common */ -#define LABIT (1<<2) /* label (a PC location or defined by EQU) */ -#define MNREGBIT (1<<3) /* mnemonic for op or pseudo-op, or register */ -#define MACBIT (1<<4) /* macro */ -#define REDBIT (1<<5) /* redefined */ -#define VARBIT (1<<6) /* variable (i.e. something defined by SET) */ -#define EXPBIT (1<<7) /* exported (= OBJ_E_MASK) */ - - /* data entry contains following flags, valid */ - /* for expressions as well as syms */ -#define PAGE1 (1<<0) /* page 1 machine op = MNREGBIT \ PAGE1 */ -#define PAGE2 (1<<1) /* page 2 machine op = MNREGBIT \ PAGE2 */ -#define REGBIT (1<<2) /* register = MNREGBIT \ REGBIT */ -#define SIZEBIT (1<<3) /* sizing mnemonic = MNREGBIT \ SIZEBIT */ -#define SEGM 15 /* 1st 4 bits reused for segment if !MNREGBIT */ -#define RELBIT (1<<4) /* relative (= OBJ_A_MASK) */ -#define FORBIT (1<<5) /* forward referenced */ -#define IMPBIT (1<<6) /* imported (= OBJ_I_MASK) */ -#define UNDBIT (1<<7) /* undefined */ - -/* pseudo-op routine numbers */ -/* conditionals are first, this is used to test if op is a conditional */ - -#define ELSEOP 0 -#define ELSEIFOP 1 -#define ELSEIFCOP 2 -#define ENDIFOP 3 -#define IFOP 4 -#define IFCOP 5 -#define MAXCOND 6 /* limit of conditionals */ - -#define BLOCKOP 6 -#define COMMOP 7 -#define ENDOP 8 -#define ENDBOP 9 -#define ENTEROP 10 -#define ENTRYOP 11 -#define EQUOP 12 -#define EXPORTOP 13 -#define FAILOP 14 -#define FCBOP 15 -#define FCCOP 16 -#define FDBOP 17 -#define GETOP 18 -#define IDENTOP 19 -#define IMPORTOP 20 -#define _LISTOP 21 -#define LOCOP 22 -#define _MACLISTOP 23 -#define MACROOP 24 -#define _MAPOP 25 -#define ORGOP 26 -#define RMBOP 27 -#define SETOP 28 -#define SETDPOP 29 -#define _WARNOP 30 - -#ifdef I80386 - -/* further pseudo-ops */ - -#define BSSOP 31 -#define COMMOP1 32 -#define DATAOP 33 -#define TEXTOP 34 -#define USE16OP 35 -#define USE32OP 36 - -/* machine-op routine numbers */ - -#define ARPL 37 -#define BCC 38 -#define BOUND 39 -#define CALL 40 -#define DIVMUL 41 -#define ENTER 42 -#define GROUP1 43 -#define GROUP2 44 -#define GROUP6 45 -#define GROUP7 46 -#define GROUP8 47 -#define GvEv 48 -#define IMUL 49 -#define IN 50 -#define INCDEC 51 -#define INHER 52 -#define INHER16 53 -#define INHER32 54 -#define INHER_A 55 -#define INT 56 -#define JCC 57 -#define JCXZ 58 -#define LEA 59 -#define LOAD_FULL_POINTER 60 -#define MOV 61 -#define MOVX 62 -#define NEGNOT 63 -#define OUT 64 -#define PUSHPOP 65 -#define RET 66 -#define RETF 67 -#define SEG 68 -#define SETCC 69 -#define SH_DOUBLE 70 -#define TEST 71 -#define XCHG 72 - -/* further pseudo-ops */ - -#define BLKWOP 73 -#define EVENOP 74 -#define FQBOP 75 -#define ALIGNOP 76 - -/* further machine-ops */ - -#define CALLI 77 - -/* yet further pseudo-ops */ - -#define LCOMMOP 78 -#define LCOMMOP1 79 - -#endif /* I80386 */ - -#ifdef MC6809 - -/* machine-op routine numbers */ - -#define ALL 31 /* all address modes allowed, like LDA */ -#define ALTER 32 /* all but immediate, like STA */ -#define IMMED 33 /* immediate only (ANDCC, ORCC) */ -#define INDEXD 34 /* indexed (LEA's) */ -#define INHER 35 /* inherent, like CLC or CLRA */ -#define LONG 36 /* long branches */ -#define SHORT 37 /* short branches */ -#define SSTAK 38 /* S-stack (PSHS, PULS) */ -#define SWAP 39 /* TFR, EXG */ -#define USTAK 40 /* U-stack (PSHU,PULU) */ - -/* yet further pseudo-ops */ - -#define LCOMMOP 41 - -#endif - -/* object code format (Introl) */ - -#define OBJ_SEGSZ_TWO 0x02 /* size 2 code for segment size descriptor */ - -#define OBJ_MAX_ABS_LEN 64 /* max length of chunk of absolute code */ - -#define OBJ_ABS 0x40 /* absolute code command */ -#define OBJ_OFFSET_REL 0x80 /* offset relocation command */ -#define OBJ_SET_SEG 0x20 /* set segment command */ -#define OBJ_SKIP_1 0x11 /* skip with 1 byte count */ -#define OBJ_SKIP_2 0x12 /* skip with 2 byte count */ -#define OBJ_SKIP_4 0x13 /* skip with 4 byte count */ -#define OBJ_SYMBOL_REL 0xC0 /* symbol relocation command */ - -#define OBJ_A_MASK 0x10 /* absolute bit(symbols) */ -#if OBJ_A_MASK - RELBIT /* must match internal format (~byte 1 -> 0) */ -oops - RELBIT misplaced -#endif -#define OBJ_E_MASK 0x80 /* exported bit (symbols) */ -#if OBJ_E_MASK - EXPBIT /* must match internal format (byte 0 -> 0) */ -oops - EXPBIT misplaced -#endif -#define OBJ_I_MASK 0x40 /* imported bit (symbols) */ -#if OBJ_I_MASK - IMPBIT /* must match internal format (byte 1 -> 0) */ -oops - IMPBIT misplaced -#endif -#define OBJ_N_MASK 0x01 /* entry bit (symbols) */ -#if OBJ_N_MASK - ENTBIT /* must match internal format (byte 0 -> 1) */ -oops - ENTBIT misplaced -#endif -#define OBJ_SA_MASK 0x20 /* size allocation bit (symbols) */ -#define OBJ_SZ_ONE 0x40 /* size one code for symbol value */ -#define OBJ_SZ_TWO 0x80 /* size two code for symbol value */ -#define OBJ_SZ_FOUR 0xC0 /* size four code for symbol value */ - -#define OBJ_R_MASK 0x20 /* PC-rel bit (off & sym reloc commands) */ -#define OBJ_SEGM_MASK 0x0F /* segment mask (symbols, off reloc command) */ - -#define OBJ_OF_MASK 0x03 /* offset size code for symbol reloc */ -#define OBJ_S_MASK 0x04 /* symbol number size code for symbol reloc */ - -#define SYMLIS_NAMELEN 26 -#define SYMLIS_LEN (sizeof (struct sym_listing_s)) - -#define FILNAMLEN 64 /* max length of a file name */ -#define LINLEN 256 /* max length of input line */ -#define LINUM_LEN 5 /* length of formatted line number */ - -#define SPTSIZ 1024 /* number of symbol ptrs */ - /* pseudo-op flags */ -#define POPHI 1 /* set to print hi byte of adr */ -#define POPLO 2 /* to print lo byte of ADR */ -#define POPLC 4 /* to print LC */ -#define POPLONG 8 /* to print high word of ADR */ -#define MAXBLOCK 8 /* max nesting level of BLOCK stack */ -#define MAXGET 8 /* max nesting level of GET stack */ -#define MAXIF 8 /* max nesting level of IF stack */ -#define MACPSIZ (128/sizeof (struct schain_s)) - /* size of macro param buffer */ -#define MAXMAC 8 /* max nesting level of macro stack */ -#define NLOC 16 /* number of location counters */ -#ifdef I80386 -#define NO_SIB 0340 /* illegal sib (3 with 4) to mean no sib */ -#endif - -/* special segments */ - -#define BSSLOC 3 -#define DATALOC 3 -#define DPLOC 2 -#define STRLOC 1 -#define TEXTLOC 0 diff --git a/bin86-0.3/as/Makefile b/bin86-0.3/as/Makefile deleted file mode 100644 index 70104e8..0000000 --- a/bin86-0.3/as/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -CC =gcc -CFLAGS =-O1 -fomit-frame-pointer -Dwarn=as_warn -INC_CFLAGS =-I../a.out.h -LDFLAGS =-s - -OBJS =as.o assemble.o error.o express.o \ - genbin.o genlist.o genobj.o gensym.o \ - keywords.o macro.o mops.o pops.o \ - readsrc.o scan.o table.o ../ld/typeconv.o - -.SUFFIXES: -.SUFFIXES: .c .o - -.c.o: - $(CC) $(CFLAGS) $(INC_CFLAGS) -c $< - -all: as86 - -as86: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) - -clean: - $(RM) *.o as86 core endian.h - -as.o: const.h type.h byteord.h macro.h file.h flag.h globvar.h -assemble.o: const.h type.h address.h globvar.h opcode.h scan.h -error.o: const.h type.h -express.o: const.h type.h address.h globvar.h scan.h source.h -genbin.o: const.h type.h address.h file.h globvar.h -genlist.o: const.h type.h address.h flag.h file.h globvar.h macro.h scan.h \ - source.h -genobj.o: const.h type.h address.h file.h globvar.h -gensym.o: const.h type.h flag.h file.h globvar.h -keywords.o: const.h type.h opcode.h -macro.o: const.h type.h globvar.h scan.h macro.h -mops.o: const.h type.h globvar.h opcode.h scan.h address.h -pops.o: const.h type.h address.h flag.h globvar.h opcode.h scan.h -readsrc.o: const.h type.h flag.h file.h globvar.h macro.h scan.h source.h -scan.o: const.h type.h scan.h -table.o: const.h type.h globvar.h scan.h - -const.h: endian.h - -endian.h: det_endian.c - $(CC) -o det_endian det_endian.c - -@if [ $$? = 0 ]; then \ - det_endian > $@; \ - if [ $$? = 0 ]; then \ - rm -f det_endian; \ - else \ - echo Failed to create $@; \ - exit 1; \ - fi; \ - else \ - echo Failed to compile det_endian.c; \ - exit 1; \ - fi diff --git a/bin86-0.3/as/address.h b/bin86-0.3/as/address.h deleted file mode 100644 index e310535..0000000 --- a/bin86-0.3/as/address.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * bin86/as/address.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* address.h - global variables involving addresses for assembler */ - -EXTERN struct address_s lastexp;/* last expression parsed */ - -EXTERN union -{ - char fcbuf[LINLEN - 6]; /* buffer for fcb and fcc data */ - /* data is absolute in 1 char pieces */ - /* limited by FCC\t"" etc on line */ - struct address_s fdbuf[(LINLEN - 4) / 2]; - /* buffer for fdb data */ - /* data can be of any 2-byte adr type */ - /* limited by FDB\t and commas on line */ -#if SIZEOF_OFFSET_T > 2 - struct address_s fqbuf[(LINLEN - 4) / 4]; - /* buffer for fqb data */ - /* data can be of any 4-byte adr type */ - /* limited by FQB\t and commas on line */ -#endif -} - databuf; - -EXTERN bool_t fcflag; -EXTERN bool_t fdflag; -#if SIZEOF_OFFSET_T > 2 -EXTERN bool_t fqflag; -#endif - -EXTERN struct address_s immadr; -EXTERN smallcount_t immcount; diff --git a/bin86-0.3/as/as.c b/bin86-0.3/as/as.c deleted file mode 100644 index 9f91639..0000000 --- a/bin86-0.3/as/as.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * bin86/as/as.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* as.c - assembler */ - -/* - usage: as source [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] [-guw] - in any order (but no repeated file options) -*/ - -#include <sys/types.h> -#include <fcntl.h> -#include "const.h" -#include "type.h" -#include "byteord.h" -#include "macro.h" -#undef EXTERN -#define EXTERN -#include "file.h" -#include "flag.h" -#include "globvar.h" - -PRIVATE struct block_s hid_blockstak[MAXBLOCK]; /* block stack */ -PRIVATE struct lc_s hid_lctab[NLOC]; /* location counter table */ -PRIVATE struct if_s hid_ifstak[MAXBLOCK]; /* if stack */ -PRIVATE struct schain_s hid_mcpar[MACPSIZ]; /* MACRO params */ -PRIVATE struct macro_s hid_macstak[MAXBLOCK]; /* macro stack */ -PRIVATE struct sym_s *hid_spt[SPTSIZ]; /* hash table */ - -FORWARD void initp1 P((void)); -FORWARD int my_creat P((char *name, char *message)); -FORWARD void process_args P((int argc, char **argv)); -FORWARD void summary P((fd_t fd)); -FORWARD void summ_number P((unsigned num)); -FORWARD void usage P((void)); - -#define USERMEM (sizeof(int) <= 2 ? (unsigned) 0xAC00 : (unsigned) 0x20000L) - -PUBLIC int main(argc, argv) -int argc; -char **argv; -{ - heapptr = malloc(USERMEM); - heapend = heapptr + USERMEM; - if (heapptr == 0) - as_abort("cannot allocate memory"); -#ifdef SOS_EDOS - heapend = stackreg() - STAKSIZ; -#endif - initp1(); - initp1p2(); - inst_keywords(); - initbin(); - initobj(); - initsource(); /* only nec to init for unsupported mem file */ - typeconv_init(BIG_ENDIAN, LONG_BIG_ENDIAN); - warn.global = TRUE; /* constant */ - process_args(argc, argv); - initscan(); - - assemble(); /* doesn't return, maybe use setjmp */ - - /* NOTREACHED */ - return 0; -} - -PUBLIC void as_abort(message) -char *message; -{ - write(STDOUT, "as: ", 4); - write(STDOUT, message, strlen(message)); - write(STDOUT, "\n", 1); - exit(1); -} - -PUBLIC void finishup() -{ - bintrailer(); - objtrailer(); - if (list.global ||symgen) - gensym(); /* output to lstfil and/or symfil */ - if (list.global ||toterr != 0 || totwarn != 0) - summary(lstfil); - if (lstfil != STDOUT && (toterr != 0 || totwarn != 0)) - summary(STDOUT); - statistics(); - exit(toterr != 0 ? 1 : 0); /* should close output files and check */ -} - -/* initialise constant nonzero values */ - -PRIVATE void initp1() -{ -#ifdef I80386 - idefsize = defsize = sizeof (char *) > 2 ? 4 : 2; -#endif - lctabtop = lctab + NLOC; - lstfil = STDOUT; - mapnum = 15; /* default map number for symbol table */ - spt_top = (spt = hid_spt) + SPTSIZ; -} - -/* initialise nonzero values which start same each pass */ - -PUBLIC void initp1p2() -{ - register struct lc_s *lcp; - - ifflag = TRUE; - pedata = UNDBIT; /* program entry point not defined */ - blockstak = hid_blockstak + MAXBLOCK; - ifstak = hid_ifstak + MAXIF; - macstak = hid_macstak + MAXMAC; - macptop = (macpar = hid_mcpar) + MACPSIZ; - lctabtop = (lcptr = lctab = hid_lctab) + NLOC; - for (lcp = lctab; lcp < lctabtop; ++lcp) - /* init of lcdata/lc (many times) in loop to save space */ - { - lcp->data = lcdata = RELBIT; /* lc relocatable until 1st ORG */ - lcp->lc = lc = 0; - } -} - -PRIVATE int my_creat(name, message) -char *name; -char *message; -{ - int fd; - - if ((fd = creat(name, CREAT_PERMS)) < 0 || fd > 255) - as_abort(message); - return fd; -} - -PRIVATE void process_args(argc, argv) -int argc; -char **argv; -{ - char *arg; - bool_t isnextarg; - char *nextarg; - - if (argc <= 1) - usage(); - do - { - arg = *++argv; - if (arg[0] == '-') - { - if (arg[2] != 0) - usage(); /* no multiple options */ - isnextarg = FALSE; - if (argc > 2) - { - nextarg = argv[1]; - if (nextarg[0] != 0 && nextarg[0] != '-') - isnextarg = TRUE; - } - switch (arg[1]) - { -#ifdef I80386 - case '0': - idefsize = defsize = 0x2; - break; - case '3': - idefsize = defsize = 0x4; - break; - case 'a': - asld_compatible = TRUE; - break; -#endif - case 'b': - if (!isnextarg || binfil != 0) - usage(); - binfil = my_creat(nextarg, "error creating binary file"); - binaryg = TRUE; - --argc; - ++argv; - break; - case 'g': - globals_only_in_obj = TRUE; - break; -#ifdef I80386 - case 'j': - jumps_long = TRUE; - break; -#endif - case 'l': - list.global = TRUE; - goto get_any_list_file; - case 'm': - maclist.global = TRUE; - get_any_list_file: - if (isnextarg) - { - if (lstfil != STDOUT) - usage(); - lstfil = my_creat(nextarg, "error creating list file"); - --argc; - ++argv; - } - break; - case 'n': - if (!isnextarg) - usage(); - truefilename = nextarg; - --argc; - ++argv; - break; - case 'o': - if (!isnextarg || objfil != 0) - usage(); - objectg = TRUE; - objfil = my_creat(nextarg, "error creating object file"); - --argc; - ++argv; - break; - case 's': - if (!isnextarg || symfil != 0) - usage(); - symgen = TRUE; - symfil = my_creat(nextarg, "error creating symbol file"); - --argc; - ++argv; - break; - case 'u': - inidata = IMPBIT | SEGM; - break; - case 'w': - warn.semaphore = -1; - break; - default: - usage(); /* bad option */ - } - } - else if (infil != 0) - usage(); /* no multiple sources */ - else - { - if (strlen(arg) > FILNAMLEN) - as_abort("source file name too long"); - infil = open_input(strcpy(filnamptr, arg)); - infiln = infil0 = 1; - } - } - while (--argc != 1); - inidata = (~binaryg & inidata) | (RELBIT | UNDBIT); -} /* IMPBIT from inidata unless binaryg */ - -PRIVATE void summary(fd) -int fd; -{ - innum = fd; - writenl(); - summ_number(toterr); - writesn(" errors"); - summ_number(totwarn); - writesn(" warnings"); -} - -PRIVATE void summ_number(num) -unsigned num; -{ - /* format number like line numbers, build it at free spot heapptr */ - *build_number(num, LINUM_LEN, heapptr) = 0; - writes(heapptr); -} - -PRIVATE void usage() -{ - as_abort( -#ifdef I80386 -"usage: as [-03agjuw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); -#else - "usage: as [-guw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); -#endif -} diff --git a/bin86-0.3/as/asm/calljmp.asm b/bin86-0.3/as/asm/calljmp.asm deleted file mode 100644 index 36a6ea4..0000000 --- a/bin86-0.3/as/asm/calljmp.asm +++ /dev/null @@ -1,70 +0,0 @@ - CALL 0x10:0x20 ; not implemented - CALL AL; ; illeg - CALL DS ; illeg - - CALL REL16 - - CALL AX - CALL BX - CALL CX - CALL DX - CALL SP - CALL BP - CALL SI - CALL DI - - CALL BYTE [BX] ; illeg - CALL [BX] - CALL WORD [BX] - - USE32 - CALL REL32 - - USE16 - CALL EAX - CALL EBX - CALL ECX - CALL EDX - CALL ESP - CALL EBP - CALL ESI - CALL EDI - - CALL DWORD [BX] - - JMP 0x10:0x20 ; not implemented - JMP AL; ; illeg - JMP DS ; illeg - - JMP REL16 - - JMP AX - JMP BX - JMP CX - JMP DX - JMP SP - JMP BP - JMP SI - JMP DI - - JMP BYTE [BX] ; illeg - JMP [BX] - JMP WORD [BX] - - USE32 - JMP REL32 - - USE16 - JMP EAX - JMP EBX - JMP ECX - JMP EDX - JMP ESP - JMP EBP - JMP ESI - JMP EDI - - JMP DWORD [BX] - -REL16: -REL32: diff --git a/bin86-0.3/as/asm/ea.asm b/bin86-0.3/as/asm/ea.asm deleted file mode 100644 index 8717a73..0000000 --- a/bin86-0.3/as/asm/ea.asm +++ /dev/null @@ -1,109 +0,0 @@ - MOV AX,[BX+SI] - MOV AX,[BX+DI] - MOV AX,[BP+SI] - MOV AX,[BP+DI] - MOV AX,[SI] - MOV AX,[DI] - MOV AX,[0x1234] - MOV AX,[BX] - - MOV AX,[BX+SI+0x12] - MOV AX,[BX+DI+0x12] - MOV AX,[BP+SI+0x12] - MOV AX,[BP+DI+0x12] - MOV AX,[SI+0x12] - MOV AX,[DI+0x12] - MOV AX,[BP+0x12] - MOV AX,[BX+0x12] - - MOV AX,[BX+SI+0x1234] - MOV AX,[BX+DI+0x1234] - MOV AX,[BP+SI+0x1234] - MOV AX,[BP+DI+0x1234] - MOV AX,[SI+0x1234] - MOV AX,[DI+0x1234] - MOV AX,[BP+0x1234] - MOV AX,[BX+0x1234] - - MOV AL,AL - MOV AL,AH - MOV AL,BL - MOV AL,BH - MOV AL,CL - MOV AL,CH - MOV AL,DL - MOV AL,DH - - MOV AX,AX - MOV AX,CX - MOV AX,DX - MOV AX,BX - MOV AX,SP - MOV AX,BP - MOV AX,SI - MOV AX,DI - - MOV AX,[EAX] - MOV AX,[ECX] - MOV AX,[EDX] - MOV AX,[EBX] - - MOV AX,[0x12345678] - MOV AX,[ESI] - MOV AX,[EDI] - - MOV AX,[EAX+0x12] - MOV AX,[ECX+0x12] - MOV AX,[EDX+0x12] - MOV AX,[EBX+0x12] - - MOV AX,[EBP+0x12] - MOV AX,[ESI+0x12] - MOV AX,[EDI+0x12] - - MOV AX,[EAX+0x12345678] - MOV AX,[ECX+0x12345678] - MOV AX,[EDX+0x12345678] - MOV AX,[EBX+0x12345678] - - MOV AX,[EBP+0x12345678] - MOV AX,[ESI+0x12345678] - MOV AX,[EDI+0x12345678] - - MOV EAX,EAX - MOV EAX,ECX - MOV EAX,EDX - MOV EAX,EBX - MOV EAX,ESP - MOV EAX,EBP - MOV EAX,ESI - MOV EAX,EDI - - MOV AX,[EAX+ESI*2] - MOV AX,[ECX+ESI*2] - MOV AX,[EDX+ESI*2] - MOV AX,[EBX+ESI*2] - MOV AX,[ESP+ESI*2] - MOV AX,[ESI*2+0x12345678] - MOV AX,[ESI+ESI*2] - MOV AX,[EDI+ESI*2] - - MOV AX,[EAX+ESI*2+0x12] - MOV AX,[ECX+ESI*2+0x12] - MOV AX,[EDX+ESI*2+0x12] - MOV AX,[EBX+ESI*2+0x12] - MOV AX,[ESP+ESI*2+0x12] - MOV AX,[ESP+0x12] - MOV AX,[EBP+ESI*2+0x12] - MOV AX,[ESI+ESI*2+0x12] - MOV AX,[EDI+ESI*2+0x12] - - MOV AX,[EAX+ESI*2+0x12345678] - MOV AX,[ECX+ESI*2+0x12345678] - MOV AX,[EDX+ESI*2+0x12345678] - MOV AX,[EBX+ESI*2+0x12345678] - MOV AX,[ESP+ESI*2+0x12345678] - MOV AX,[ESP+0x12345678] - MOV AX,[EBP+ESI*2+0x12345678] - MOV AX,[ESI+ESI*2+0x12345678] - MOV AX,[EDI+ESI*2+0x12345678] diff --git a/bin86-0.3/as/asm/each.asm b/bin86-0.3/as/asm/each.asm deleted file mode 100644 index 2145489..0000000 --- a/bin86-0.3/as/asm/each.asm +++ /dev/null @@ -1,145 +0,0 @@ -aaa -aad -aam -aas -adc bx,[esi*4] -add bx,[esi*4] -and bx,[esi*4] -arpl [esi*4],bx -bound bx,[esi*4] -bsf bx,[esi*4] -bsr bx,[esi*4] -bswap ebx -bt [esi*4],bx -btc [esi*4],bx -btr [esi*4],bx -bts [esi*4],bx -call [esi*4] -cbw -cwde -clc -cld -cli -clts -cmc -cmp bx,[esi*4] -cmpsb -cmpsw -cmpsd -cmpxchg [esi*4],bx -cwd -cdq -daa -das -dec [esi*4] -div [esi*4] -enter 0x200,3 -hlt -idiv [esi*4] -imul [esi*4] -in al,0x20 -inc [esi*4] -insb -insw -insd -int 0x20 -into -invd -invlpg [esi*4] -iret -iretd -jnz many -many: -jmp [esi*4] -lahf -lar bx,[esi*4] -lea bx,[esi*4] -leave -lgdt [esi*4] -lidt [esi*4] -lds bx,[esi*4] -les bx,[esi*4] -lfs bx,[esi*4] -lgs bx,[esi*4] -lss bx,[esi*4] -lldt [esi*4] -lmsw [esi*4] -lock -lodsb -lodsw -lodsd -loop alot -alot: -lsl bx,[esi*4] -ltr [esi*4] -mov ax,[esi*4] -mov bx,[esi*4] -mov cr0,eax -movsb -movsw -movsd -movsx bx,byte [esi*4] -movzx bx,byte [esi*4] -mul [esi*4] -neg [esi*4] -nop -not [esi*4] -or bx,[esi*4] -out 0x20,al -outsb -outsw -outsd -pop [esi*4] -popa -popad -popf -popfd -push [esi*4] -pusha -pushad -pushf -pushfd -rcl [esi*4],1 -rcr [esi*4],1 -rol [esi*4],1 -ror [esi*4],1 -rep -repe -repz -repne -repnz -ret -retf -sahf -sal [esi*4],1 -sar [esi*4],1 -shl [esi*4],1 -shr [esi*4],1 -sbb bx,[esi*4] -scasb -scasw -scasd -setnz byte [esi*4] -sgdt [esi*4] -sidt [esi*4] -shld [esi*4],bx,1 -shrd [esi*4],bx,1 -sldt [esi*4] -smsw [esi*4] -stc -std -sti -stosb -stosw -stosd -str [esi*4] -sub bx,[esi*4] -test bx,[esi*4] -verr [esi*4] -verw [esi*4] -wait -wbinvd -xadd [esi*4],bx -xchg bx,[esi*4] -xlat -xor bx,[esi*4] diff --git a/bin86-0.3/as/asm/easlow.as b/bin86-0.3/as/asm/easlow.as deleted file mode 100644 index 75d71e2..0000000 --- a/bin86-0.3/as/asm/easlow.as +++ /dev/null @@ -1,1219 +0,0 @@ - MOV AL,[0] - MOV AH,[1] - MOV BL,[-1] ; illeg - MOV BH,[127] - MOV CL,[-128] ; illeg - MOV CH,[128] - MOV DL,[-129] ; illeg - MOV DH,[32767] - MOV AL,[-32768] ; illeg - MOV AH,[32768] - MOV BL,[-32769] ; illeg - MOV BH,[$7FFFFFFF] ; illeg - MOV CL,[$80000000] ; illeg - - MOV AL,AL - MOV AL,AH - MOV AL,BL - MOV AL,BH - MOV AL,CL - MOV AL,CH - MOV AL,DL - MOV AL,DH - - MOV AL,AX ; illeg - MOV AL,BX ; illeg - MOV AL,CX ; illeg - MOV AL,DX ; illeg - MOV AL,BP ; illeg - MOV AL,DI ; illeg - MOV AL,SI ; illeg - MOV AL,SP ; illeg - - MOV AH,AL - MOV AH,AH - MOV AH,BL - MOV AH,BH - MOV AH,CL - MOV AH,CH - MOV AH,DL - MOV AH,DH - - MOV AH,AX ; illeg - MOV AH,BX ; illeg - MOV AH,CX ; illeg - MOV AH,DX ; illeg - MOV AH,BP ; illeg - MOV AH,DI ; illeg - MOV AH,SI ; illeg - MOV AH,SP ; illeg - - MOV BL,AL - MOV BL,AH - MOV BL,BL - MOV BL,BH - MOV BL,CL - MOV BL,CH - MOV BL,DL - MOV BL,DH - - MOV BL,AX ; illeg - MOV BL,BX ; illeg - MOV BL,CX ; illeg - MOV BL,DX ; illeg - MOV BL,BP ; illeg - MOV BL,DI ; illeg - MOV BL,SI ; illeg - MOV BL,SP ; illeg - - MOV BH,AL - MOV BH,AH - MOV BH,BL - MOV BH,BH - MOV BH,CL - MOV BH,CH - MOV BH,DL - MOV BH,DH - - MOV BH,AX ; illeg - MOV BH,BX ; illeg - MOV BH,CX ; illeg - MOV BH,DX ; illeg - MOV BH,BP ; illeg - MOV BH,DI ; illeg - MOV BH,SI ; illeg - MOV BH,SP ; illeg - - MOV CL,AL - MOV CL,AH - MOV CL,BL - MOV CL,BH - MOV CL,CL - MOV CL,CH - MOV CL,DL - MOV CL,DH - - MOV CL,AX ; illeg - MOV CL,BX ; illeg - MOV CL,CX ; illeg - MOV CL,DX ; illeg - MOV CL,BP ; illeg - MOV CL,DI ; illeg - MOV CL,SI ; illeg - MOV CL,SP ; illeg - - MOV CH,AL - MOV CH,AH - MOV CH,BL - MOV CH,BH - MOV CH,CL - MOV CH,CH - MOV CH,DL - MOV CH,DH - - MOV CH,AX ; illeg - MOV CH,BX ; illeg - MOV CH,CX ; illeg - MOV CH,DX ; illeg - MOV CH,BP ; illeg - MOV CH,DI ; illeg - MOV CH,SI ; illeg - MOV CH,SP ; illeg - - MOV DL,AL - MOV DL,AH - MOV DL,BL - MOV DL,BH - MOV DL,CL - MOV DL,CH - MOV DL,DL - MOV DL,DH - - MOV DL,AX ; illeg - MOV DL,BX ; illeg - MOV DL,CX ; illeg - MOV DL,DX ; illeg - MOV DL,BP ; illeg - MOV DL,DI ; illeg - MOV DL,SI ; illeg - MOV DL,SP ; illeg - - MOV DH,AL - MOV DH,AH - MOV DH,BL - MOV DH,BH - MOV DH,CL - MOV DH,CH - MOV DH,DL - MOV DH,DH - - MOV DH,AX ; illeg - MOV DH,BX ; illeg - MOV DH,CX ; illeg - MOV DH,DX ; illeg - MOV DH,BP ; illeg - MOV DH,DI ; illeg - MOV DH,SI ; illeg - MOV DH,SP ; illeg - - MOV AL,[AL] ; illeg - MOV AH,[AH] ; illeg - MOV BL,[BL] ; illeg - MOV BH,[BH] ; illeg - MOV CL,[CL] ; illeg - MOV CH,[CH] ; illeg - MOV DL,[DL] ; illeg - MOV DH,[DH] ; illeg - - MOV AL,[AX] ; illeg - MOV AH,[BX] - MOV BL,[CX] ; illeg - MOV BH,[DX] ; illeg - MOV CL,[BP] - MOV CH,[DI] - MOV DL,[SI] - MOV DH,[SP] ; illeg - - MOV AL,[AX+1] ; illeg - MOV AH,[BX+1] - MOV BL,[CX+1] ; illeg - MOV BH,[DX+1] ; illeg - MOV CL,[BP+1] - MOV CH,[DI+1] - MOV DL,[SI+1] - MOV DH,[SP+1] ; illeg - - MOV AL,[AX-1] ; illeg - MOV AH,[BX-1] - MOV BL,[CX-1] ; illeg - MOV BH,[DX-1] ; illeg - MOV CL,[BP-1] - MOV CH,[DI-1] - MOV DL,[SI-1] - MOV DH,[SP-1] ; illeg - - MOV AL,[AX+127] ; illeg - MOV AH,[BX+127] - MOV BL,[CX+127] ; illeg - MOV BH,[DX+127] ; illeg - MOV CL,[BP+127] - MOV CH,[DI+127] - MOV DL,[SI+127] - MOV DH,[SP+127] ; illeg - - MOV AL,[AX-128] ; illeg - MOV AH,[BX-128] - MOV BL,[CX-128] ; illeg - MOV BH,[DX-128] ; illeg - MOV CL,[BP-128] - MOV CH,[DI-128] - MOV DL,[SI-128] - MOV DH,[SP-128] ; illeg - - MOV AL,[AX+128] ; illeg - MOV AH,[BX+128] - MOV BL,[CX+128] ; illeg - MOV BH,[DX+128] ; illeg - MOV CL,[BP+128] - MOV CH,[DI+128] - MOV DL,[SI+128] - MOV DH,[SP+128] ; illeg - - MOV AL,[AX-129] ; illeg - MOV AH,[BX-129] - MOV BL,[CX-129] ; illeg - MOV BH,[DX-129] ; illeg - MOV CL,[BP-129] - MOV CH,[DI-129] - MOV DL,[SI-129] - MOV DH,[SP-129] ; illeg - - MOV AL,[AX+32767] ; illeg - MOV AH,[BX+32767] - MOV BL,[CX+32767] ; illeg - MOV BH,[DX+32767] ; illeg - MOV CL,[BP+32767] - MOV CH,[DI+32767] - MOV DL,[SI+32767] - MOV DH,[SP+32767] ; illeg - - MOV AL,[AX-32768] ; illeg - MOV AH,[BX-32768] - MOV BL,[CX-32768] ; illeg - MOV BH,[DX-32768] ; illeg - MOV CL,[BP-32768] - MOV CH,[DI-32768] - MOV DL,[SI-32768] - MOV DH,[SP-32768] ; illeg - - MOV AL,[AX+32768] ; illeg - MOV AH,[BX+32768] - MOV BL,[CX+32768] ; illeg - MOV BH,[DX+32768] ; illeg - MOV CL,[BP+32768] - MOV CH,[DI+32768] - MOV DL,[SI+32768] - MOV DH,[SP+32768] ; illeg - - MOV AL,[AX-32769] ; illeg - MOV AH,[BX-32769] - MOV BL,[CX-32769] ; illeg - MOV BH,[DX-32769] ; illeg - MOV CL,[BP-32769] - MOV CH,[DI-32769] - MOV DL,[SI-32769] - MOV DH,[SP-32769] ; illeg - - MOV AL,[AX+$7FFFFFFF] ; illeg - MOV AH,[BX+$7FFFFFFF] ; illeg (bounds) - MOV BL,[CX+$7FFFFFFF] ; illeg - MOV BH,[DX+$7FFFFFFF] ; illeg - MOV CL,[BP+$7FFFFFFF] ; illeg (bounds) - MOV CH,[DI+$7FFFFFFF] ; illeg (bounds) - MOV DL,[SI+$7FFFFFFF] ; illeg (bounds) - MOV DH,[SP+$7FFFFFFF] ; illeg - - MOV AL,[AX-$80000000] ; illeg - MOV AH,[BX-$80000000] ; illeg (bounds) - MOV BL,[CX-$80000000] ; illeg - MOV BH,[DX-$80000000] ; illeg - MOV CL,[BP-$80000000] ; illeg (bounds) - MOV CH,[DI-$80000000] ; illeg (bounds) - MOV DL,[SI-$80000000] ; illeg (bounds) - MOV DH,[SP-$80000000] ; illeg - - MOV AL,[AX+AX] ; illeg - MOV AH,[AX+BX] ; illeg - MOV BL,[AX+CX] ; illeg - MOV BH,[AX+DX] ; illeg - MOV CL,[AX+BP] ; illeg - MOV CH,[AX+DI] ; illeg - MOV DL,[AX+SI] ; illeg - MOV DH,[AX+SP] ; illeg - - MOV AL,[BX+AX] ; illeg - MOV AH,[BX+BX] ; illeg - MOV BL,[BX+CX] ; illeg - MOV BH,[BX+DX] ; illeg - MOV CL,[BX+BP] ; illeg - MOV CH,[BX+DI] - MOV DL,[BX+SI] - MOV DH,[BX+SP] ; illeg - - MOV AL,[CX+AX] ; illeg - MOV AH,[CX+BX] ; illeg - MOV BL,[CX+CX] ; illeg - MOV BH,[CX+DX] ; illeg - MOV CL,[CX+BP] ; illeg - MOV CH,[CX+DI] ; illeg - MOV DL,[CX+SI] ; illeg - MOV DH,[CX+SP] ; illeg - - MOV AL,[DX+AX] ; illeg - MOV AH,[DX+BX] ; illeg - MOV BL,[DX+CX] ; illeg - MOV BH,[DX+DX] ; illeg - MOV CL,[DX+BP] ; illeg - MOV CH,[DX+DI] ; illeg - MOV DL,[DX+SI] ; illeg - MOV DH,[DX+SP] ; illeg - - MOV AL,[BP+AX] ; illeg - MOV AH,[BP+BX] ; illeg - MOV BL,[BP+CX] ; illeg - MOV BH,[BP+DX] ; illeg - MOV CL,[BP+BP] ; illeg - MOV CH,[BP+DI] - MOV DL,[BP+SI] - MOV DH,[BP+SP] ; illeg - - MOV AL,[DI+AX] ; illeg - MOV AH,[DI+BX] - MOV BL,[DI+CX] ; illeg - MOV BH,[DI+DX] ; illeg - MOV CL,[DI+BP] - MOV CH,[DI+DI] ; illeg - MOV DL,[DI+SI] ; illeg - MOV DH,[DI+SP] ; illeg - - MOV AL,[SI+AX] ; illeg - MOV AH,[SI+BX] - MOV BL,[SI+CX] ; illeg - MOV BH,[SI+DX] ; illeg - MOV CL,[SI+BP] - MOV CH,[SI+DI] ; illeg - MOV DL,[SI+SI] ; illeg - MOV DH,[SI+SP] ; illeg - - MOV AL,[SP+AX] ; illeg - MOV AH,[SP+BX] ; illeg - MOV BL,[SP+CX] ; illeg - MOV BH,[SP+DX] ; illeg - MOV CL,[SP+BP] ; illeg - MOV CH,[SP+DI] ; illeg - MOV DL,[SP+SI] ; illeg - MOV DH,[SP+SP] ; illeg - - MOV AL,[AX+AX+1] ; illeg - MOV AH,[AX+BX+1] ; illeg - MOV BL,[AX+CX+1] ; illeg - MOV BH,[AX+DX+1] ; illeg - MOV CL,[AX+BP+1] ; illeg - MOV CH,[AX+DI+1] ; illeg - MOV DL,[AX+SI+1] ; illeg - MOV DH,[AX+SP+1] ; illeg - - MOV AL,[BX+AX+1] ; illeg - MOV AH,[BX+BX+1] ; illeg - MOV BL,[BX+CX+1] ; illeg - MOV BH,[BX+DX+1] ; illeg - MOV CL,[BX+BP+1] ; illeg - MOV CH,[BX+DI+1] - MOV DL,[BX+SI+1] - MOV DH,[BX+SP+1] ; illeg - - MOV AL,[CX+AX+1] ; illeg - MOV AH,[CX+BX+1] ; illeg - MOV BL,[CX+CX+1] ; illeg - MOV BH,[CX+DX+1] ; illeg - MOV CL,[CX+BP+1] ; illeg - MOV CH,[CX+DI+1] ; illeg - MOV DL,[CX+SI+1] ; illeg - MOV DH,[CX+SP+1] ; illeg - - MOV AL,[DX+AX+1] ; illeg - MOV AH,[DX+BX+1] ; illeg - MOV BL,[DX+CX+1] ; illeg - MOV BH,[DX+DX+1] ; illeg - MOV CL,[DX+BP+1] ; illeg - MOV CH,[DX+DI+1] ; illeg - MOV DL,[DX+SI+1] ; illeg - MOV DH,[DX+SP+1] ; illeg - - MOV AL,[BP+AX+1] ; illeg - MOV AH,[BP+BX+1] ; illeg - MOV BL,[BP+CX+1] ; illeg - MOV BH,[BP+DX+1] ; illeg - MOV CL,[BP+BP+1] ; illeg - MOV CH,[BP+DI+1] - MOV DL,[BP+SI+1] - MOV DH,[BP+SP+1] ; illeg - - MOV AL,[DI+AX+1] ; illeg - MOV AH,[DI+BX+1] - MOV BL,[DI+CX+1] ; illeg - MOV BH,[DI+DX+1] ; illeg - MOV CL,[DI+BP+1] - MOV CH,[DI+DI+1] ; illeg - MOV DL,[DI+SI+1] ; illeg - MOV DH,[DI+SP+1] ; illeg - - MOV AL,[SI+AX+1] ; illeg - MOV AH,[SI+BX+1] - MOV BL,[SI+CX+1] ; illeg - MOV BH,[SI+DX+1] ; illeg - MOV CL,[SI+BP+1] - MOV CH,[SI+DI+1] ; illeg - MOV DL,[SI+SI+1] ; illeg - MOV DH,[SI+SP+1] ; illeg - - MOV AL,[SP+AX+1] ; illeg - MOV AH,[SP+BX+1] ; illeg - MOV BL,[SP+CX+1] ; illeg - MOV BH,[SP+DX+1] ; illeg - MOV CL,[SP+BP+1] ; illeg - MOV CH,[SP+DI+1] ; illeg - MOV DL,[SP+SI+1] ; illeg - MOV DH,[SP+SP+1] ; illeg - - MOV AL,[AX+AX-1] ; illeg - MOV AH,[AX+BX-1] ; illeg - MOV BL,[AX+CX-1] ; illeg - MOV BH,[AX+DX-1] ; illeg - MOV CL,[AX+BP-1] ; illeg - MOV CH,[AX+DI-1] ; illeg - MOV DL,[AX+SI-1] ; illeg - MOV DH,[AX+SP-1] ; illeg - - MOV AL,[BX+AX-1] ; illeg - MOV AH,[BX+BX-1] ; illeg - MOV BL,[BX+CX-1] ; illeg - MOV BH,[BX+DX-1] ; illeg - MOV CL,[BX+BP-1] ; illeg - MOV CH,[BX+DI-1] - MOV DL,[BX+SI-1] - MOV DH,[BX+SP-1] ; illeg - - MOV AL,[CX+AX-1] ; illeg - MOV AH,[CX+BX-1] ; illeg - MOV BL,[CX+CX-1] ; illeg - MOV BH,[CX+DX-1] ; illeg - MOV CL,[CX+BP-1] ; illeg - MOV CH,[CX+DI-1] ; illeg - MOV DL,[CX+SI-1] ; illeg - MOV DH,[CX+SP-1] ; illeg - - MOV AL,[DX+AX-1] ; illeg - MOV AH,[DX+BX-1] ; illeg - MOV BL,[DX+CX-1] ; illeg - MOV BH,[DX+DX-1] ; illeg - MOV CL,[DX+BP-1] ; illeg - MOV CH,[DX+DI-1] ; illeg - MOV DL,[DX+SI-1] ; illeg - MOV DH,[DX+SP-1] ; illeg - - MOV AL,[BP+AX-1] ; illeg - MOV AH,[BP+BX-1] ; illeg - MOV BL,[BP+CX-1] ; illeg - MOV BH,[BP+DX-1] ; illeg - MOV CL,[BP+BP-1] ; illeg - MOV CH,[BP+DI-1] - MOV DL,[BP+SI-1] - MOV DH,[BP+SP-1] ; illeg - - MOV AL,[DI+AX-1] ; illeg - MOV AH,[DI+BX-1] - MOV BL,[DI+CX-1] ; illeg - MOV BH,[DI+DX-1] ; illeg - MOV CL,[DI+BP-1] - MOV CH,[DI+DI-1] ; illeg - MOV DL,[DI+SI-1] ; illeg - MOV DH,[DI+SP-1] ; illeg - - MOV AL,[SI+AX-1] ; illeg - MOV AH,[SI+BX-1] - MOV BL,[SI+CX-1] ; illeg - MOV BH,[SI+DX-1] ; illeg - MOV CL,[SI+BP-1] - MOV CH,[SI+DI-1] ; illeg - MOV DL,[SI+SI-1] ; illeg - MOV DH,[SI+SP-1] ; illeg - - MOV AL,[SP+AX-1] ; illeg - MOV AH,[SP+BX-1] ; illeg - MOV BL,[SP+CX-1] ; illeg - MOV BH,[SP+DX-1] ; illeg - MOV CL,[SP+BP-1] ; illeg - MOV CH,[SP+DI-1] ; illeg - MOV DL,[SP+SI-1] ; illeg - MOV DH,[SP+SP-1] ; illeg - - MOV AL,[AX+AX+127] ; illeg - MOV AH,[AX+BX+127] ; illeg - MOV BL,[AX+CX+127] ; illeg - MOV BH,[AX+DX+127] ; illeg - MOV CL,[AX+BP+127] ; illeg - MOV CH,[AX+DI+127] ; illeg - MOV DL,[AX+SI+127] ; illeg - MOV DH,[AX+SP+127] ; illeg - - MOV AL,[BX+AX+127] ; illeg - MOV AH,[BX+BX+127] ; illeg - MOV BL,[BX+CX+127] ; illeg - MOV BH,[BX+DX+127] ; illeg - MOV CL,[BX+BP+127] ; illeg - MOV CH,[BX+DI+127] - MOV DL,[BX+SI+127] - MOV DH,[BX+SP+127] ; illeg - - MOV AL,[CX+AX+127] ; illeg - MOV AH,[CX+BX+127] ; illeg - MOV BL,[CX+CX+127] ; illeg - MOV BH,[CX+DX+127] ; illeg - MOV CL,[CX+BP+127] ; illeg - MOV CH,[CX+DI+127] ; illeg - MOV DL,[CX+SI+127] ; illeg - MOV DH,[CX+SP+127] ; illeg - - MOV AL,[DX+AX+127] ; illeg - MOV AH,[DX+BX+127] ; illeg - MOV BL,[DX+CX+127] ; illeg - MOV BH,[DX+DX+127] ; illeg - MOV CL,[DX+BP+127] ; illeg - MOV CH,[DX+DI+127] ; illeg - MOV DL,[DX+SI+127] ; illeg - MOV DH,[DX+SP+127] ; illeg - - MOV AL,[BP+AX+127] ; illeg - MOV AH,[BP+BX+127] ; illeg - MOV BL,[BP+CX+127] ; illeg - MOV BH,[BP+DX+127] ; illeg - MOV CL,[BP+BP+127] ; illeg - MOV CH,[BP+DI+127] - MOV DL,[BP+SI+127] - MOV DH,[BP+SP+127] ; illeg - - MOV AL,[DI+AX+127] ; illeg - MOV AH,[DI+BX+127] - MOV BL,[DI+CX+127] ; illeg - MOV BH,[DI+DX+127] ; illeg - MOV CL,[DI+BP+127] - MOV CH,[DI+DI+127] ; illeg - MOV DL,[DI+SI+127] ; illeg - MOV DH,[DI+SP+127] ; illeg - - MOV AL,[SI+AX+127] ; illeg - MOV AH,[SI+BX+127] - MOV BL,[SI+CX+127] ; illeg - MOV BH,[SI+DX+127] ; illeg - MOV CL,[SI+BP+127] - MOV CH,[SI+DI+127] ; illeg - MOV DL,[SI+SI+127] ; illeg - MOV DH,[SI+SP+127] ; illeg - - MOV AL,[SP+AX+127] ; illeg - MOV AH,[SP+BX+127] ; illeg - MOV BL,[SP+CX+127] ; illeg - MOV BH,[SP+DX+127] ; illeg - MOV CL,[SP+BP+127] ; illeg - MOV CH,[SP+DI+127] ; illeg - MOV DL,[SP+SI+127] ; illeg - MOV DH,[SP+SP+127] ; illeg - - MOV AL,[AX+AX-128] ; illeg - MOV AH,[AX+BX-128] ; illeg - MOV BL,[AX+CX-128] ; illeg - MOV BH,[AX+DX-128] ; illeg - MOV CL,[AX+BP-128] ; illeg - MOV CH,[AX+DI-128] ; illeg - MOV DL,[AX+SI-128] ; illeg - MOV DH,[AX+SP-128] ; illeg - - MOV AL,[BX+AX-128] ; illeg - MOV AH,[BX+BX-128] ; illeg - MOV BL,[BX+CX-128] ; illeg - MOV BH,[BX+DX-128] ; illeg - MOV CL,[BX+BP-128] ; illeg - MOV CH,[BX+DI-128] - MOV DL,[BX+SI-128] - MOV DH,[BX+SP-128] ; illeg - - MOV AL,[CX+AX-128] ; illeg - MOV AH,[CX+BX-128] ; illeg - MOV BL,[CX+CX-128] ; illeg - MOV BH,[CX+DX-128] ; illeg - MOV CL,[CX+BP-128] ; illeg - MOV CH,[CX+DI-128] ; illeg - MOV DL,[CX+SI-128] ; illeg - MOV DH,[CX+SP-128] ; illeg - - MOV AL,[DX+AX-128] ; illeg - MOV AH,[DX+BX-128] ; illeg - MOV BL,[DX+CX-128] ; illeg - MOV BH,[DX+DX-128] ; illeg - MOV CL,[DX+BP-128] ; illeg - MOV CH,[DX+DI-128] ; illeg - MOV DL,[DX+SI-128] ; illeg - MOV DH,[DX+SP-128] ; illeg - - MOV AL,[BP+AX-128] ; illeg - MOV AH,[BP+BX-128] ; illeg - MOV BL,[BP+CX-128] ; illeg - MOV BH,[BP+DX-128] ; illeg - MOV CL,[BP+BP-128] ; illeg - MOV CH,[BP+DI-128] - MOV DL,[BP+SI-128] - MOV DH,[BP+SP-128] ; illeg - - MOV AL,[DI+AX-128] ; illeg - MOV AH,[DI+BX-128] - MOV BL,[DI+CX-128] ; illeg - MOV BH,[DI+DX-128] ; illeg - MOV CL,[DI+BP-128] - MOV CH,[DI+DI-128] ; illeg - MOV DL,[DI+SI-128] ; illeg - MOV DH,[DI+SP-128] ; illeg - - MOV AL,[SI+AX-128] ; illeg - MOV AH,[SI+BX-128] - MOV BL,[SI+CX-128] ; illeg - MOV BH,[SI+DX-128] ; illeg - MOV CL,[SI+BP-128] - MOV CH,[SI+DI-128] ; illeg - MOV DL,[SI+SI-128] ; illeg - MOV DH,[SI+SP-128] ; illeg - - MOV AL,[SP+AX-128] ; illeg - MOV AH,[SP+BX-128] ; illeg - MOV BL,[SP+CX-128] ; illeg - MOV BH,[SP+DX-128] ; illeg - MOV CL,[SP+BP-128] ; illeg - MOV CH,[SP+DI-128] ; illeg - MOV DL,[SP+SI-128] ; illeg - MOV DH,[SP+SP-128] ; illeg - - MOV AL,[AX+AX+128] ; illeg - MOV AH,[AX+BX+128] ; illeg - MOV BL,[AX+CX+128] ; illeg - MOV BH,[AX+DX+128] ; illeg - MOV CL,[AX+BP+128] ; illeg - MOV CH,[AX+DI+128] ; illeg - MOV DL,[AX+SI+128] ; illeg - MOV DH,[AX+SP+128] ; illeg - - MOV AL,[BX+AX+128] ; illeg - MOV AH,[BX+BX+128] ; illeg - MOV BL,[BX+CX+128] ; illeg - MOV BH,[BX+DX+128] ; illeg - MOV CL,[BX+BP+128] ; illeg - MOV CH,[BX+DI+128] - MOV DL,[BX+SI+128] - MOV DH,[BX+SP+128] ; illeg - - MOV AL,[CX+AX+128] ; illeg - MOV AH,[CX+BX+128] ; illeg - MOV BL,[CX+CX+128] ; illeg - MOV BH,[CX+DX+128] ; illeg - MOV CL,[CX+BP+128] ; illeg - MOV CH,[CX+DI+128] ; illeg - MOV DL,[CX+SI+128] ; illeg - MOV DH,[CX+SP+128] ; illeg - - MOV AL,[DX+AX+128] ; illeg - MOV AH,[DX+BX+128] ; illeg - MOV BL,[DX+CX+128] ; illeg - MOV BH,[DX+DX+128] ; illeg - MOV CL,[DX+BP+128] ; illeg - MOV CH,[DX+DI+128] ; illeg - MOV DL,[DX+SI+128] ; illeg - MOV DH,[DX+SP+128] ; illeg - - MOV AL,[BP+AX+128] ; illeg - MOV AH,[BP+BX+128] ; illeg - MOV BL,[BP+CX+128] ; illeg - MOV BH,[BP+DX+128] ; illeg - MOV CL,[BP+BP+128] ; illeg - MOV CH,[BP+DI+128] - MOV DL,[BP+SI+128] - MOV DH,[BP+SP+128] ; illeg - - MOV AL,[DI+AX+128] ; illeg - MOV AH,[DI+BX+128] - MOV BL,[DI+CX+128] ; illeg - MOV BH,[DI+DX+128] ; illeg - MOV CL,[DI+BP+128] - MOV CH,[DI+DI+128] ; illeg - MOV DL,[DI+SI+128] ; illeg - MOV DH,[DI+SP+128] ; illeg - - MOV AL,[SI+AX+128] ; illeg - MOV AH,[SI+BX+128] - MOV BL,[SI+CX+128] ; illeg - MOV BH,[SI+DX+128] ; illeg - MOV CL,[SI+BP+128] - MOV CH,[SI+DI+128] ; illeg - MOV DL,[SI+SI+128] ; illeg - MOV DH,[SI+SP+128] ; illeg - - MOV AL,[SP+AX+128] ; illeg - MOV AH,[SP+BX+128] ; illeg - MOV BL,[SP+CX+128] ; illeg - MOV BH,[SP+DX+128] ; illeg - MOV CL,[SP+BP+128] ; illeg - MOV CH,[SP+DI+128] ; illeg - MOV DL,[SP+SI+128] ; illeg - MOV DH,[SP+SP+128] ; illeg - - MOV AL,[AX+AX-129] ; illeg - MOV AH,[AX+BX-129] ; illeg - MOV BL,[AX+CX-129] ; illeg - MOV BH,[AX+DX-129] ; illeg - MOV CL,[AX+BP-129] ; illeg - MOV CH,[AX+DI-129] ; illeg - MOV DL,[AX+SI-129] ; illeg - MOV DH,[AX+SP-129] ; illeg - - MOV AL,[BX+AX-129] ; illeg - MOV AH,[BX+BX-129] ; illeg - MOV BL,[BX+CX-129] ; illeg - MOV BH,[BX+DX-129] ; illeg - MOV CL,[BX+BP-129] ; illeg - MOV CH,[BX+DI-129] - MOV DL,[BX+SI-129] - MOV DH,[BX+SP-129] ; illeg - - MOV AL,[CX+AX-129] ; illeg - MOV AH,[CX+BX-129] ; illeg - MOV BL,[CX+CX-129] ; illeg - MOV BH,[CX+DX-129] ; illeg - MOV CL,[CX+BP-129] ; illeg - MOV CH,[CX+DI-129] ; illeg - MOV DL,[CX+SI-129] ; illeg - MOV DH,[CX+SP-129] ; illeg - - MOV AL,[DX+AX-129] ; illeg - MOV AH,[DX+BX-129] ; illeg - MOV BL,[DX+CX-129] ; illeg - MOV BH,[DX+DX-129] ; illeg - MOV CL,[DX+BP-129] ; illeg - MOV CH,[DX+DI-129] ; illeg - MOV DL,[DX+SI-129] ; illeg - MOV DH,[DX+SP-129] ; illeg - - MOV AL,[BP+AX-129] ; illeg - MOV AH,[BP+BX-129] ; illeg - MOV BL,[BP+CX-129] ; illeg - MOV BH,[BP+DX-129] ; illeg - MOV CL,[BP+BP-129] ; illeg - MOV CH,[BP+DI-129] - MOV DL,[BP+SI-129] - MOV DH,[BP+SP-129] ; illeg - - MOV AL,[DI+AX-129] ; illeg - MOV AH,[DI+BX-129] - MOV BL,[DI+CX-129] ; illeg - MOV BH,[DI+DX-129] ; illeg - MOV CL,[DI+BP-129] - MOV CH,[DI+DI-129] ; illeg - MOV DL,[DI+SI-129] ; illeg - MOV DH,[DI+SP-129] ; illeg - - MOV AL,[SI+AX-129] ; illeg - MOV AH,[SI+BX-129] - MOV BL,[SI+CX-129] ; illeg - MOV BH,[SI+DX-129] ; illeg - MOV CL,[SI+BP-129] - MOV CH,[SI+DI-129] ; illeg - MOV DL,[SI+SI-129] ; illeg - MOV DH,[SI+SP-129] ; illeg - - MOV AL,[SP+AX-129] ; illeg - MOV AH,[SP+BX-129] ; illeg - MOV BL,[SP+CX-129] ; illeg - MOV BH,[SP+DX-129] ; illeg - MOV CL,[SP+BP-129] ; illeg - MOV CH,[SP+DI-129] ; illeg - MOV DL,[SP+SI-129] ; illeg - MOV DH,[SP+SP-129] ; illeg - - MOV AL,[AX+AX+32767] ; illeg - MOV AH,[AX+BX+32767] ; illeg - MOV BL,[AX+CX+32767] ; illeg - MOV BH,[AX+DX+32767] ; illeg - MOV CL,[AX+BP+32767] ; illeg - MOV CH,[AX+DI+32767] ; illeg - MOV DL,[AX+SI+32767] ; illeg - MOV DH,[AX+SP+32767] ; illeg - - MOV AL,[BX+AX+32767] ; illeg - MOV AH,[BX+BX+32767] ; illeg - MOV BL,[BX+CX+32767] ; illeg - MOV BH,[BX+DX+32767] ; illeg - MOV CL,[BX+BP+32767] ; illeg - MOV CH,[BX+DI+32767] - MOV DL,[BX+SI+32767] - MOV DH,[BX+SP+32767] ; illeg - - MOV AL,[CX+AX+32767] ; illeg - MOV AH,[CX+BX+32767] ; illeg - MOV BL,[CX+CX+32767] ; illeg - MOV BH,[CX+DX+32767] ; illeg - MOV CL,[CX+BP+32767] ; illeg - MOV CH,[CX+DI+32767] ; illeg - MOV DL,[CX+SI+32767] ; illeg - MOV DH,[CX+SP+32767] ; illeg - - MOV AL,[DX+AX+32767] ; illeg - MOV AH,[DX+BX+32767] ; illeg - MOV BL,[DX+CX+32767] ; illeg - MOV BH,[DX+DX+32767] ; illeg - MOV CL,[DX+BP+32767] ; illeg - MOV CH,[DX+DI+32767] ; illeg - MOV DL,[DX+SI+32767] ; illeg - MOV DH,[DX+SP+32767] ; illeg - - MOV AL,[BP+AX+32767] ; illeg - MOV AH,[BP+BX+32767] ; illeg - MOV BL,[BP+CX+32767] ; illeg - MOV BH,[BP+DX+32767] ; illeg - MOV CL,[BP+BP+32767] ; illeg - MOV CH,[BP+DI+32767] - MOV DL,[BP+SI+32767] - MOV DH,[BP+SP+32767] ; illeg - - MOV AL,[DI+AX+32767] ; illeg - MOV AH,[DI+BX+32767] - MOV BL,[DI+CX+32767] ; illeg - MOV BH,[DI+DX+32767] ; illeg - MOV CL,[DI+BP+32767] - MOV CH,[DI+DI+32767] ; illeg - MOV DL,[DI+SI+32767] ; illeg - MOV DH,[DI+SP+32767] ; illeg - - MOV AL,[SI+AX+32767] ; illeg - MOV AH,[SI+BX+32767] - MOV BL,[SI+CX+32767] ; illeg - MOV BH,[SI+DX+32767] ; illeg - MOV CL,[SI+BP+32767] - MOV CH,[SI+DI+32767] ; illeg - MOV DL,[SI+SI+32767] ; illeg - MOV DH,[SI+SP+32767] ; illeg - - MOV AL,[SP+AX+32767] ; illeg - MOV AH,[SP+BX+32767] ; illeg - MOV BL,[SP+CX+32767] ; illeg - MOV BH,[SP+DX+32767] ; illeg - MOV CL,[SP+BP+32767] ; illeg - MOV CH,[SP+DI+32767] ; illeg - MOV DL,[SP+SI+32767] ; illeg - MOV DH,[SP+SP+32767] ; illeg - - MOV AL,[AX+AX-32768] ; illeg - MOV AH,[AX+BX-32768] ; illeg - MOV BL,[AX+CX-32768] ; illeg - MOV BH,[AX+DX-32768] ; illeg - MOV CL,[AX+BP-32768] ; illeg - MOV CH,[AX+DI-32768] ; illeg - MOV DL,[AX+SI-32768] ; illeg - MOV DH,[AX+SP-32768] ; illeg - - MOV AL,[BX+AX-32768] ; illeg - MOV AH,[BX+BX-32768] ; illeg - MOV BL,[BX+CX-32768] ; illeg - MOV BH,[BX+DX-32768] ; illeg - MOV CL,[BX+BP-32768] ; illeg - MOV CH,[BX+DI-32768] - MOV DL,[BX+SI-32768] - MOV DH,[BX+SP-32768] ; illeg - - MOV AL,[CX+AX-32768] ; illeg - MOV AH,[CX+BX-32768] ; illeg - MOV BL,[CX+CX-32768] ; illeg - MOV BH,[CX+DX-32768] ; illeg - MOV CL,[CX+BP-32768] ; illeg - MOV CH,[CX+DI-32768] ; illeg - MOV DL,[CX+SI-32768] ; illeg - MOV DH,[CX+SP-32768] ; illeg - - MOV AL,[DX+AX-32768] ; illeg - MOV AH,[DX+BX-32768] ; illeg - MOV BL,[DX+CX-32768] ; illeg - MOV BH,[DX+DX-32768] ; illeg - MOV CL,[DX+BP-32768] ; illeg - MOV CH,[DX+DI-32768] ; illeg - MOV DL,[DX+SI-32768] ; illeg - MOV DH,[DX+SP-32768] ; illeg - - MOV AL,[BP+AX-32768] ; illeg - MOV AH,[BP+BX-32768] ; illeg - MOV BL,[BP+CX-32768] ; illeg - MOV BH,[BP+DX-32768] ; illeg - MOV CL,[BP+BP-32768] ; illeg - MOV CH,[BP+DI-32768] - MOV DL,[BP+SI-32768] - MOV DH,[BP+SP-32768] ; illeg - - MOV AL,[DI+AX-32768] ; illeg - MOV AH,[DI+BX-32768] - MOV BL,[DI+CX-32768] ; illeg - MOV BH,[DI+DX-32768] ; illeg - MOV CL,[DI+BP-32768] - MOV CH,[DI+DI-32768] ; illeg - MOV DL,[DI+SI-32768] ; illeg - MOV DH,[DI+SP-32768] ; illeg - - MOV AL,[SI+AX-32768] ; illeg - MOV AH,[SI+BX-32768] - MOV BL,[SI+CX-32768] ; illeg - MOV BH,[SI+DX-32768] ; illeg - MOV CL,[SI+BP-32768] - MOV CH,[SI+DI-32768] ; illeg - MOV DL,[SI+SI-32768] ; illeg - MOV DH,[SI+SP-32768] ; illeg - - MOV AL,[SP+AX-32768] ; illeg - MOV AH,[SP+BX-32768] ; illeg - MOV BL,[SP+CX-32768] ; illeg - MOV BH,[SP+DX-32768] ; illeg - MOV CL,[SP+BP-32768] ; illeg - MOV CH,[SP+DI-32768] ; illeg - MOV DL,[SP+SI-32768] ; illeg - MOV DH,[SP+SP-32768] ; illeg - - MOV AL,[AX+AX+32768] ; illeg - MOV AH,[AX+BX+32768] ; illeg - MOV BL,[AX+CX+32768] ; illeg - MOV BH,[AX+DX+32768] ; illeg - MOV CL,[AX+BP+32768] ; illeg - MOV CH,[AX+DI+32768] ; illeg - MOV DL,[AX+SI+32768] ; illeg - MOV DH,[AX+SP+32768] ; illeg - - MOV AL,[BX+AX+32768] ; illeg - MOV AH,[BX+BX+32768] ; illeg - MOV BL,[BX+CX+32768] ; illeg - MOV BH,[BX+DX+32768] ; illeg - MOV CL,[BX+BP+32768] ; illeg - MOV CH,[BX+DI+32768] - MOV DL,[BX+SI+32768] - MOV DH,[BX+SP+32768] ; illeg - - MOV AL,[CX+AX+32768] ; illeg - MOV AH,[CX+BX+32768] ; illeg - MOV BL,[CX+CX+32768] ; illeg - MOV BH,[CX+DX+32768] ; illeg - MOV CL,[CX+BP+32768] ; illeg - MOV CH,[CX+DI+32768] ; illeg - MOV DL,[CX+SI+32768] ; illeg - MOV DH,[CX+SP+32768] ; illeg - - MOV AL,[DX+AX+32768] ; illeg - MOV AH,[DX+BX+32768] ; illeg - MOV BL,[DX+CX+32768] ; illeg - MOV BH,[DX+DX+32768] ; illeg - MOV CL,[DX+BP+32768] ; illeg - MOV CH,[DX+DI+32768] ; illeg - MOV DL,[DX+SI+32768] ; illeg - MOV DH,[DX+SP+32768] ; illeg - - MOV AL,[BP+AX+32768] ; illeg - MOV AH,[BP+BX+32768] ; illeg - MOV BL,[BP+CX+32768] ; illeg - MOV BH,[BP+DX+32768] ; illeg - MOV CL,[BP+BP+32768] ; illeg - MOV CH,[BP+DI+32768] - MOV DL,[BP+SI+32768] - MOV DH,[BP+SP+32768] ; illeg - - MOV AL,[DI+AX+32768] ; illeg - MOV AH,[DI+BX+32768] - MOV BL,[DI+CX+32768] ; illeg - MOV BH,[DI+DX+32768] ; illeg - MOV CL,[DI+BP+32768] - MOV CH,[DI+DI+32768] ; illeg - MOV DL,[DI+SI+32768] ; illeg - MOV DH,[DI+SP+32768] ; illeg - - MOV AL,[SI+AX+32768] ; illeg - MOV AH,[SI+BX+32768] - MOV BL,[SI+CX+32768] ; illeg - MOV BH,[SI+DX+32768] ; illeg - MOV CL,[SI+BP+32768] - MOV CH,[SI+DI+32768] ; illeg - MOV DL,[SI+SI+32768] ; illeg - MOV DH,[SI+SP+32768] ; illeg - - MOV AL,[SP+AX+32768] ; illeg - MOV AH,[SP+BX+32768] ; illeg - MOV BL,[SP+CX+32768] ; illeg - MOV BH,[SP+DX+32768] ; illeg - MOV CL,[SP+BP+32768] ; illeg - MOV CH,[SP+DI+32768] ; illeg - MOV DL,[SP+SI+32768] ; illeg - MOV DH,[SP+SP+32768] ; illeg - - MOV AL,[AX+AX-32769] ; illeg - MOV AH,[AX+BX-32769] ; illeg - MOV BL,[AX+CX-32769] ; illeg - MOV BH,[AX+DX-32769] ; illeg - MOV CL,[AX+BP-32769] ; illeg - MOV CH,[AX+DI-32769] ; illeg - MOV DL,[AX+SI-32769] ; illeg - MOV DH,[AX+SP-32769] ; illeg - - MOV AL,[BX+AX-32769] ; illeg - MOV AH,[BX+BX-32769] ; illeg - MOV BL,[BX+CX-32769] ; illeg - MOV BH,[BX+DX-32769] ; illeg - MOV CL,[BX+BP-32769] ; illeg - MOV CH,[BX+DI-32769] - MOV DL,[BX+SI-32769] - MOV DH,[BX+SP-32769] ; illeg - - MOV AL,[CX+AX-32769] ; illeg - MOV AH,[CX+BX-32769] ; illeg - MOV BL,[CX+CX-32769] ; illeg - MOV BH,[CX+DX-32769] ; illeg - MOV CL,[CX+BP-32769] ; illeg - MOV CH,[CX+DI-32769] ; illeg - MOV DL,[CX+SI-32769] ; illeg - MOV DH,[CX+SP-32769] ; illeg - - MOV AL,[DX+AX-32769] ; illeg - MOV AH,[DX+BX-32769] ; illeg - MOV BL,[DX+CX-32769] ; illeg - MOV BH,[DX+DX-32769] ; illeg - MOV CL,[DX+BP-32769] ; illeg - MOV CH,[DX+DI-32769] ; illeg - MOV DL,[DX+SI-32769] ; illeg - MOV DH,[DX+SP-32769] ; illeg - - MOV AL,[BP+AX-32769] ; illeg - MOV AH,[BP+BX-32769] ; illeg - MOV BL,[BP+CX-32769] ; illeg - MOV BH,[BP+DX-32769] ; illeg - MOV CL,[BP+BP-32769] ; illeg - MOV CH,[BP+DI-32769] - MOV DL,[BP+SI-32769] - MOV DH,[BP+SP-32769] ; illeg - - MOV AL,[DI+AX-32769] ; illeg - MOV AH,[DI+BX-32769] - MOV BL,[DI+CX-32769] ; illeg - MOV BH,[DI+DX-32769] ; illeg - MOV CL,[DI+BP-32769] - MOV CH,[DI+DI-32769] ; illeg - MOV DL,[DI+SI-32769] ; illeg - MOV DH,[DI+SP-32769] ; illeg - - MOV AL,[SI+AX-32769] ; illeg - MOV AH,[SI+BX-32769] - MOV BL,[SI+CX-32769] ; illeg - MOV BH,[SI+DX-32769] ; illeg - MOV CL,[SI+BP-32769] - MOV CH,[SI+DI-32769] ; illeg - MOV DL,[SI+SI-32769] ; illeg - MOV DH,[SI+SP-32769] ; illeg - - MOV AL,[SP+AX-32769] ; illeg - MOV AH,[SP+BX-32769] ; illeg - MOV BL,[SP+CX-32769] ; illeg - MOV BH,[SP+DX-32769] ; illeg - MOV CL,[SP+BP-32769] ; illeg - MOV CH,[SP+DI-32769] ; illeg - MOV DL,[SP+SI-32769] ; illeg - MOV DH,[SP+SP-32769] ; illeg - - MOV AL,[AX+AX+$7FFFFFFF] ; illeg - MOV AH,[AX+BX+$7FFFFFFF] ; illeg - MOV BL,[AX+CX+$7FFFFFFF] ; illeg - MOV BH,[AX+DX+$7FFFFFFF] ; illeg - MOV CL,[AX+BP+$7FFFFFFF] ; illeg - MOV CH,[AX+DI+$7FFFFFFF] ; illeg - MOV DL,[AX+SI+$7FFFFFFF] ; illeg - MOV DH,[AX+SP+$7FFFFFFF] ; illeg - - MOV AL,[BX+AX+$7FFFFFFF] ; illeg - MOV AH,[BX+BX+$7FFFFFFF] ; illeg - MOV BL,[BX+CX+$7FFFFFFF] ; illeg - MOV BH,[BX+DX+$7FFFFFFF] ; illeg - MOV CL,[BX+BP+$7FFFFFFF] ; illeg - MOV CH,[BX+DI+$7FFFFFFF] ; illeg (bounds) - MOV DL,[BX+SI+$7FFFFFFF] ; illeg (bounds) - MOV DH,[BX+SP+$7FFFFFFF] ; illeg - - MOV AL,[CX+AX+$7FFFFFFF] ; illeg - MOV AH,[CX+BX+$7FFFFFFF] ; illeg - MOV BL,[CX+CX+$7FFFFFFF] ; illeg - MOV BH,[CX+DX+$7FFFFFFF] ; illeg - MOV CL,[CX+BP+$7FFFFFFF] ; illeg - MOV CH,[CX+DI+$7FFFFFFF] ; illeg - MOV DL,[CX+SI+$7FFFFFFF] ; illeg - MOV DH,[CX+SP+$7FFFFFFF] ; illeg - - MOV AL,[DX+AX+$7FFFFFFF] ; illeg - MOV AH,[DX+BX+$7FFFFFFF] ; illeg - MOV BL,[DX+CX+$7FFFFFFF] ; illeg - MOV BH,[DX+DX+$7FFFFFFF] ; illeg - MOV CL,[DX+BP+$7FFFFFFF] ; illeg - MOV CH,[DX+DI+$7FFFFFFF] ; illeg - MOV DL,[DX+SI+$7FFFFFFF] ; illeg - MOV DH,[DX+SP+$7FFFFFFF] ; illeg - - MOV AL,[BP+AX+$7FFFFFFF] ; illeg - MOV AH,[BP+BX+$7FFFFFFF] ; illeg - MOV BL,[BP+CX+$7FFFFFFF] ; illeg - MOV BH,[BP+DX+$7FFFFFFF] ; illeg - MOV CL,[BP+BP+$7FFFFFFF] ; illeg - MOV CH,[BP+DI+$7FFFFFFF] ; illeg (bounds) - MOV DL,[BP+SI+$7FFFFFFF] ; illeg (bounds) - MOV DH,[BP+SP+$7FFFFFFF] ; illeg - - MOV AL,[DI+AX+$7FFFFFFF] ; illeg - MOV AH,[DI+BX+$7FFFFFFF] ; illeg (bounds) - MOV BL,[DI+CX+$7FFFFFFF] ; illeg - MOV BH,[DI+DX+$7FFFFFFF] ; illeg - MOV CL,[DI+BP+$7FFFFFFF] ; illeg (bounds) - MOV CH,[DI+DI+$7FFFFFFF] ; illeg - MOV DL,[DI+SI+$7FFFFFFF] ; illeg - MOV DH,[DI+SP+$7FFFFFFF] ; illeg - - MOV AL,[SI+AX+$7FFFFFFF] ; illeg - MOV AH,[SI+BX+$7FFFFFFF] ; illeg (bounds) - MOV BL,[SI+CX+$7FFFFFFF] ; illeg - MOV BH,[SI+DX+$7FFFFFFF] ; illeg - MOV CL,[SI+BP+$7FFFFFFF] ; illeg (bounds) - MOV CH,[SI+DI+$7FFFFFFF] ; illeg - MOV DL,[SI+SI+$7FFFFFFF] ; illeg - MOV DH,[SI+SP+$7FFFFFFF] ; illeg - - MOV AL,[SP+AX+$7FFFFFFF] ; illeg - MOV AH,[SP+BX+$7FFFFFFF] ; illeg - MOV BL,[SP+CX+$7FFFFFFF] ; illeg - MOV BH,[SP+DX+$7FFFFFFF] ; illeg - MOV CL,[SP+BP+$7FFFFFFF] ; illeg - MOV CH,[SP+DI+$7FFFFFFF] ; illeg - MOV DL,[SP+SI+$7FFFFFFF] ; illeg - MOV DH,[SP+SP+$7FFFFFFF] ; illeg - - MOV AL,[AX+AX-$80000000] ; illeg - MOV AH,[AX+BX-$80000000] ; illeg - MOV BL,[AX+CX-$80000000] ; illeg - MOV BH,[AX+DX-$80000000] ; illeg - MOV CL,[AX+BP-$80000000] ; illeg - MOV CH,[AX+DI-$80000000] ; illeg - MOV DL,[AX+SI-$80000000] ; illeg - MOV DH,[AX+SP-$80000000] ; illeg - - MOV AL,[BX+AX-$80000000] ; illeg - MOV AH,[BX+BX-$80000000] ; illeg - MOV BL,[BX+CX-$80000000] ; illeg - MOV BH,[BX+DX-$80000000] ; illeg - MOV CL,[BX+BP-$80000000] ; illeg - MOV CH,[BX+DI-$80000000] ; illeg (bounds) - MOV DL,[BX+SI-$80000000] ; illeg (bounds) - MOV DH,[BX+SP-$80000000] ; illeg - - MOV AL,[CX+AX-$80000000] ; illeg - MOV AH,[CX+BX-$80000000] ; illeg - MOV BL,[CX+CX-$80000000] ; illeg - MOV BH,[CX+DX-$80000000] ; illeg - MOV CL,[CX+BP-$80000000] ; illeg - MOV CH,[CX+DI-$80000000] ; illeg - MOV DL,[CX+SI-$80000000] ; illeg - MOV DH,[CX+SP-$80000000] ; illeg - - MOV AL,[DX+AX-$80000000] ; illeg - MOV AH,[DX+BX-$80000000] ; illeg - MOV BL,[DX+CX-$80000000] ; illeg - MOV BH,[DX+DX-$80000000] ; illeg - MOV CL,[DX+BP-$80000000] ; illeg - MOV CH,[DX+DI-$80000000] ; illeg - MOV DL,[DX+SI-$80000000] ; illeg - MOV DH,[DX+SP-$80000000] ; illeg - - MOV AL,[BP+AX-$80000000] ; illeg - MOV AH,[BP+BX-$80000000] ; illeg - MOV BL,[BP+CX-$80000000] ; illeg - MOV BH,[BP+DX-$80000000] ; illeg - MOV CL,[BP+BP-$80000000] ; illeg - MOV CH,[BP+DI-$80000000] ; illeg (bounds) - MOV DL,[BP+SI-$80000000] ; illeg (bounds) - MOV DH,[BP+SP-$80000000] ; illeg - - MOV AL,[DI+AX-$80000000] ; illeg - MOV AH,[DI+BX-$80000000] ; illeg (bounds) - MOV BL,[DI+CX-$80000000] ; illeg - MOV BH,[DI+DX-$80000000] ; illeg - MOV CL,[DI+BP-$80000000] ; illeg (bounds) - MOV CH,[DI+DI-$80000000] ; illeg - MOV DL,[DI+SI-$80000000] ; illeg - MOV DH,[DI+SP-$80000000] ; illeg - - MOV AL,[SI+AX-$80000000] ; illeg - MOV AH,[SI+BX-$80000000] ; illeg (bounds) - MOV BL,[SI+CX-$80000000] ; illeg - MOV BH,[SI+DX-$80000000] ; illeg - MOV CL,[SI+BP-$80000000] ; illeg (bounds) - MOV CH,[SI+DI-$80000000] ; illeg - MOV DL,[SI+SI-$80000000] ; illeg - MOV DH,[SI+SP-$80000000] ; illeg - - MOV AL,[SP+AX-$80000000] ; illeg - MOV AH,[SP+BX-$80000000] ; illeg - MOV BL,[SP+CX-$80000000] ; illeg - MOV BH,[SP+DX-$80000000] ; illeg - MOV CL,[SP+BP-$80000000] ; illeg - MOV CH,[SP+DI-$80000000] ; illeg - MOV DL,[SP+SI-$80000000] ; illeg - MOV DH,[SP+SP-$80000000] ; illeg diff --git a/bin86-0.3/as/asm/f.asm b/bin86-0.3/as/asm/f.asm deleted file mode 100644 index c067bf9..0000000 --- a/bin86-0.3/as/asm/f.asm +++ /dev/null @@ -1,114 +0,0 @@ -; [fadd fdiv fdivr fmul fsub fsubr] [mem4r mem8r st,st(i) st(i),st] - fadd qword [ebx] - fadd dword [ebx] - fadd st,st(1) - fadd st(1),st - fdiv qword [ebx] - fdiv dword [ebx] - fdiv st,st(1) ; special swapping for this - -; [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st - faddp st(1),st - -; [fbld fbstp] mem10r - fbld tbyte [ebx] - fbstp tbyte [ebx] - -; [fcom fcomp] [mem4r mem8r optional-st(i)] - fcom dword [ebx] - fcom qword [ebx] - fcom - fcom st(1) - -; ffree st(i) - ffree st(1) - -; [fucom fucomp fxch] optional-st(i) - fucom - fucom st(1) - -; [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i] - fiadd word [ebx] - fiadd dword [ebx] - -; [fild fistp] [mem2i mem4i mem8i] - fild word [ebx] - fild dword [ebx] - fild qword [ebx] - -; [fld fstp] [mem4r mem8r mem10r st(i)] - fld dword [ebx] - fld qword [ebx] - fld tbyte [ebx] - fld st(1) - -; [fldcw fnstcw] mem2i - fldcw word [ebx] - fnstcw word [ebx] - -; [fldenv fnsave fnstenv frstor] mem - fldenv [ebx] - fnsave [ebx] - fnstenv [ebx] - frstor [ebx] - -; fnstsw [mem2i ax] - fnstsw word [ebx] - fnstsw ax - -; fst [mem4r mem8r st(i)] - fst dword [ebx] - fst qword [ebx] - fst st(1) - -; fstcw mem2i (wait) - fstcw word [ebx] - -; fstsw [mem2i ax] (wait) - fstsw word [ebx] - fstsw ax - -; [fsave fstenv] mem (wait) - fsave [ebx] - fstenv [ebx] - -; [fxxx] (no operands) - fnop ; D9D0 - fchs ; D9E0 - fabs ; D9E1 - ftst ; D9E4 - fxam ; D9E5 - fld1 ; D9E8 - fldl2t ; D9E9 - fldl2e ; D9EA - fldpi ; D9EB - fldlg2 ; D9EC - fldln2 ; D9ED - fldz ; D9EE - f2xm1 ; D9F0 - fyl2x ; D9F1 - fptan ; D9F2 - fpatan ; D9F3 - fxtract ; D9F4 - fprem1 ; D9F5 - fdecstp ; D9F6 - fincstp ; D9F7 - fprem ; D9F8 - fyl2xp1 ; D9F9 - fsqrt ; D9FA - fsincos ; D9FB - frndint ; D9FC - fscale ; D9FD - fsin ; D9FE - fcos ; D9FF - fucompp ; DAE9 - feni ; 9BDBE0 - fneni ; DBE0 - fdisi ; 9BDBE1 - fndisi ; DBE1 - fclex ; 9BDBE2 - fnclex ; DBE2 - finit ; 9BDBE3 - fninit ; DBE3 - fsetpm ; DBE4 - fcompp ; DED9 diff --git a/bin86-0.3/as/asm/fadd.asm b/bin86-0.3/as/asm/fadd.asm deleted file mode 100644 index d18f002..0000000 --- a/bin86-0.3/as/asm/fadd.asm +++ /dev/null @@ -1,271 +0,0 @@ -_fadd: - PUSH BP - MOV BP,SP - MOV EAX,DWORD PTR [BP+4] - MOV EDX,DWORD PTR [BP+8] - MOV EBX,DWORD PTR [BP+12] - MOV ECX,DWORD PTR [BP+16] - CALL faddfxfy - MOV DWORD PTR _facc,EAX - MOV DWORD PTR _facc+4,EDX - POP BP - RET - -fsubfxfy: - XOR ECX,#$80000000 ; complement sign bit, fall into add routine -faddfxfy: - PUSH EBP - PUSH EDI - PUSH ESI - MOV EDI,ECX ; free CL for shifts - MOV ESI,EDX ; this mainly for consistent naming - AND ESI,#$7FFFFFFF ; discard sign so comparison is simple - AND EDI,#$7FFFFFFF - - CMP ESI,EDI - JA XBIG - JB SWAP - CMP EAX,EBX - JAE XBIG -SWAP: - XCHG EDX,ECX - XCHG ESI,EDI - XCHG EAX,EBX -XBIG: - AND ESI,#$000FFFFF ; discard exponent - AND EDI,#$000FFFFF - OR ESI,#$00100000 ; normalize - OR EDI,#$00100000 - - SHR ECX,32-(1+11) - SHR EDX,32-(1+11) - MOV EBP,ECX ; prepare to compare signs (want high bits 0) - SUB CX,DX ; get difference of signs in CX - NEG CX ; D holds sign and exponent of both throughout - CMP CX,#(64-11)+2 - JAE TO_DONE1 ; x dominates y - XOR BP,DX - AND BP,#$0800 ; see if signs are same - JNZ TO_SUBTRACT ; else roundoff reg EBP is 0 - - CMP CL,#32 - JAE TO_ADD_BIGSHIFT - SHRD EBP,EBX,CL - SHRD EBX,EDI,CL - SHR EDI,CL - ADD EAX,EBX - ADC ESI,EDI - SUB EBX,EBX - -; result DX(1+11):SI:AX:BP:BX but needs normalization - -NORMALIZE: - MOV CX,DX - AND CX,#$07FF - TEST ESI,#$00200000 - JZ NORMALIZE2 - BR LOVERFLOW - -TO_DONE1: - JMP DONE1 - -TO_SUBTRACT: - BR SUBTRACT - -TO_ADD_BIGSHIFT: - BR ADD_BIGSHIFT - -TO_NORMLITTLE: - BR NORMLITTLE - -; result DX(1):CX(11):SI:AX:BP:BX - -NORMALIZE2: - SHRD EDI,ESI,32-11 - ; top 11 bits of ESI known 0 and BSR is slooow - BSR EDI,EDI ; index of leading 1 bit in EDI is 11..31 in DI - JZ TO_NORMLITTLE ; ESI is zero (flag wrong in Intel Manual) - SUB DI,#31 - NEG DI - PUSH CX ; gr - MOV CX,DI ; rr - SHLD ESI,EAX,CL - SHLD EAX,EBP,CL - SHLD EBP,EBX,CL - SHL EBX,CL - POP CX ; rr - SUB CX,DI - JC UNDERFLOW - -ROUND: - CMP EBP,#$80000000 ; test roundoff register - JA ROUNDUP - JB DONE ; no rounding - TEST EBX,EBX - JNZ ROUNDUP - TEST AL,#1 ; ambiguous case, round to even - JZ DONE ; even, no rounding -ROUNDUP: - ADD EAX,#1 - ADC ESI,#0 - SUB EBP,EBP - SUB EBX,EBX - TEST ESI,#$00200000 - JNZ LOVERFLOW ; rounding may cause overflow! - -DONE: - AND DX,#$0800 ; extract sign of largest and result - OR DX,CX ; include exponent with sign -DONE1: - SHL EDX,32-(1+11) - AND ESI,#$000FFFFF ; discard normalization bit - OR EDX,ESI - POP ESI - POP EDI - POP EBP - RET - -UNDERFLOW: ; should have error message here -ANSWER0: - SUB EDX,EDX - MOV EAX,EDX - POP ESI - POP EDI - POP EBP - RET - -LOVERFLOW: ; carry bit must be right-shifted back in - SHR ESI,1 - RCR EAX,1 - RCR EBP,1 - RCR EBX,1 - INC CX - CMP CX,#$0800 - JNZ ROUND - -OVERFLOW: ; should have error message here - MOV EDX,#$FFE00000 ; + infinity - SUB EAX,EAX - POP ESI - POP EDI - POP EBP - RET - -ADD_BIGSHIFT: - SUB CL,#32 - SHRD EBP,EBX,CL - SHRD EBX,EDI,CL - SHR EDI,CL - ADD EAX,EDI - ADC ESI,#0 - XCHG EBP,EBX - BR NORMALIZE - -NORMLITTLE: - SHLD ESI,EAX,32-(1+11) - SHLD EAX,EBP,32-(1+11) - SHLD EBP,EBX,32-(1+11) - SHL EBX,20 - SUB CL,#32-(1+11) - JC UNDERFLOW - BR NORMALIZE2 - -SUBTRACT: - SUB EBP,EBP ; set up roundoff register - CMP CL,#32 - JAE SUBTRACT_BIGSHIFT - SHRD EBP,EBX,CL - SHRD EBX,EDI,CL - SHR EDI,CL - NEG EBP - SBB EAX,EBX - SBB ESI,EDI - SUB EBX,EBX - MOV CX,DX - AND CX,#$07FF - BR NORMALIZE2 - -SUBTRACT_BIGSHIFT: - SUB CL,#32 - SHRD EBP,EBX,CL - SHRD EBX,EDI,CL - SHR EDI,CL - NEG EBX - NEG EBP - SBB EBX,#0 - SBB EAX,EDI - SBB ESI,#0 - XCHG EBP,EBX - MOV CX,DX - AND CX,#$07FF - BR NORMALIZE2 - -TO_ANSWER0: - BR ANSWER0 - -TO_OVERFLOW: - JMP TO_OVERFLOW - -TO_UNDERFLOW: - BR UNDERFLOW - -fmulfxfy: - PUSH EBP - PUSH EDI - PUSH ESI - MOV ESI,EDX ; free DX for multiplications - MOV EDI,ECX ; this mainly for consistent naming - SHR EDX,32-(1+11) - SHR ECX,32-(1+11) - MOV BP,DX - XOR BP,CX - AND BP,#$0800 ; extract sign - AND DX,#$07FF ; exp(x) - JZ TO_ANSWER0 - AND CX,#$07FF ; exp(y) - JZ TO_ANSWER0 - ADD CX,DX - SUB CX,#$0400 - JB TO_UNDERFLOW - CMP CX,#$07FF - JA TO_OVERFLOW ; probably not quite right - - AND ESI,#$000FFFFF ; discard sign and exponent - AND EDI,#$000FFFFF - OR ESI,#$00100000 ; normalize - OR EDI,#$00100000 - -; exponent is in CX, sign in BP, operands in ESI:EAX and EDI:EBX, DX is free -; product to go in ESI:EAX:EBP:EBX -; terminology: x * y = (x32:x0) * (y32:y0) = x32y32 + x32y0 + x0y32 +x0y0 - - PUSH CX - PUSH BP - MOV ECX,EAX - MUL EBX ; x0y0 - MOV EBP,EDX ; x0y0.high in EBP - XCHG EBX,EAX ; x0y0.low in EBX (final), y0 in EAX - MUL ESI ; x32y0 - PUSH EAX ; x32y0.low on stack - PUSH EDX ; x32y0.high on stack - MOV EAX,ESI - MUL EDI ; x32y32 - MOV ESI,EDX ; x32y32.high in ESI (final except carries) - XCHG ECX,EAX ; x32y32.low in ECX, x0 in EAX - MUL EDI ; x0y32 - - ADD EBP,EAX ; x0y0.high + x0y32.low - POP EAX ; x32y0.high - ADC EAX,EDX ; x32y0.high + x0y32.high - ADC ESI,#0 - POP EDX ; x32y0.low - ADD EBP,EDX ; (x0y0.high + x0y32.low) + x32y0.low - ADC EAX,ECX ; (x32y0.high + x0y32.high) + x32y32.low - ADC ESI,#0 - POP DX ; sign - POP CX ; exponent - ADD CX,#13 ; temp fixup - BR NORMALIZE2 - -_facc: - .word 0,0 diff --git a/bin86-0.3/as/asm/farcall.asm b/bin86-0.3/as/asm/farcall.asm deleted file mode 100644 index 6a779d9..0000000 --- a/bin86-0.3/as/asm/farcall.asm +++ /dev/null @@ -1,10 +0,0 @@ -call 1:2 -call far [1] -use32 -call far [1] - -use16 -jmp 1:2 -jmp far [1] -use32 -jmp far [1] diff --git a/bin86-0.3/as/asm/group1.asm b/bin86-0.3/as/asm/group1.asm deleted file mode 100644 index fe2fb45..0000000 --- a/bin86-0.3/as/asm/group1.asm +++ /dev/null @@ -1,31 +0,0 @@ - ADD AL,#3 - ADD AX,#$1234 - ADD EAX,#$12345678 - ADD BL,#3 - ADD BX,#$1234 - ADD EBX,#$12345678 - ADD BYTE [BX],#3 - ADD BYTE 3[BX],#4 - ADD BYTE [BX+SI],#4 - ADD WORD [BX],#$1234 - ADD DWORD [BX],#$12345678 - ADD BYTE [BX],#3 - ADD WORD [BX],#-3 - ADD DWORD [BX],#-3 - ADD CL,BL - ADD CX,BX - ADD ECX,EBX - ADD [BX],CL - ADD [BX],CX - ADD [BX],ECX - ADD CL,[BX] - ADD CX,[BX] - ADD ECX,[BX] - - ADC CL,BL - AND CL,BL - CMP CL,BL - OR CL,BL - SUB CL,BL - SBB CL,BL - XOR CL,BL diff --git a/bin86-0.3/as/asm/group6.asm b/bin86-0.3/as/asm/group6.asm deleted file mode 100644 index f742672..0000000 --- a/bin86-0.3/as/asm/group6.asm +++ /dev/null @@ -1,24 +0,0 @@ -; group6.asm -; 0F 00 /nnn - -; LLDT r/m16 nnn = 010 -; LTR r/m16 nnn = 011 -; SLDT r/m16 nnn = 000 -; STR r/m16 nnn = 001 -; VERR r/m16 nnn = 100 -; VERW r/m16 nnn = 101 - - LLDT AL ; illeg size - LLDT EAX ; illeg size - LLDT WORD $1234 ; immed not allowed - LLDT DS ; segreg not allowed - - LLDT AX - LLDT [BX] - LLDT [EAX] - - LTR BX - SLDT [BP] - STR [EBX] - VERR CX - VERW [SI] diff --git a/bin86-0.3/as/asm/group7.asm b/bin86-0.3/as/asm/group7.asm deleted file mode 100644 index 0df497c..0000000 --- a/bin86-0.3/as/asm/group7.asm +++ /dev/null @@ -1,34 +0,0 @@ -; group7.asm -; 0F 01 /nnn - -; INVLPG m nnn = 111 -; LGDT m16&32 nnn = 010 -; LIDT m16&32 nnn = 011 -; LMSW r/m16 nnn = 110 -; SGDT m nnn = 000 -; SIDT m nnn = 001 -; SMSW r/m16 nnn = 100 - - LGDT EAX ; register not allowed - LGDT #$1234 ; immed not allowed - LGDT WORD PTR [BX] ; illegal size - - LGDT [BX] - LGDT PWORD PTR [BX] - LGDT FWORD PTR [BX] - LGDT [EAX] - - INVLPG [EDI] - SGDT [BP] - SIDT [EBX] - - LMSW AL ; illeg size - LMSW EAX ; illeg size - LMSW #$1234 ; immed not allowed - LMSW DS ; segreg not allowed - - LMSW AX - LMSW [BX] - LMSW [EAX] - - SMSW BX diff --git a/bin86-0.3/as/asm/imul.asm b/bin86-0.3/as/asm/imul.asm deleted file mode 100644 index e2772c2..0000000 --- a/bin86-0.3/as/asm/imul.asm +++ /dev/null @@ -1,33 +0,0 @@ - use32 - - imul bl - imul byte ptr [esi] - imul bx - imul word ptr [esi] - imul ebx - imul dword ptr [esi] - - imul ax,bx - imul ax,[esi] - imul eax,ebx - imul eax,[esi] - - imul ax,bx,22 - imul ax,[esi],22 - imul eax,ebx,22 - imul eax,[esi],22 - - imul ax,[22] - imul eax,[22] - imul ax,#22 - imul eax,#22 - - imul ax,bx,300 - imul ax,[esi],300 - imul eax,ebx,300000 - imul eax,[esi],300000 - - imul ax,[300] - imul eax,[300000] - imul ax,#300 - imul eax,#300000 diff --git a/bin86-0.3/as/asm/incdec.asm b/bin86-0.3/as/asm/incdec.asm deleted file mode 100644 index 573861c..0000000 --- a/bin86-0.3/as/asm/incdec.asm +++ /dev/null @@ -1,83 +0,0 @@ - INC AL - INC AH - INC BL - INC BH - INC CL - INC CH - INC DL - INC DH - INC #1 ; illeg - INC BYTE #1 ; illeg - INC [BX] ; illeg - INC BYTE [BX] - - INC AX - INC BX - INC CX - INC DX - INC SP - INC BP - INC SI - INC DI - INC CS ; illeg - INC DS ; illeg - INC ES ; illeg - INC FS ; illeg - INC GS ; illeg - INC #$1234 ; illeg - INC WORD #$1234 ; illeg - INC WORD [BX] - - INC EAX - INC EBX - INC ECX - INC EDX - INC ESP - INC EBP - INC ESI - INC EDI - INC #$12345678 ; illeg - INC DWORD #$12345678 ; illeg - INC DWORD [BX] - - DEC AL - DEC AH - DEC BL - DEC BH - DEC CL - DEC CH - DEC DL - DEC DH - DEC #1 ; illeg - DEC BYTE #1 ; illeg - DEC [BX] ; illeg - DEC BYTE [BX] - - DEC AX - DEC BX - DEC CX - DEC DX - DEC SP - DEC BP - DEC SI - DEC DI - DEC CS ; illeg - DEC DS ; illeg - DEC ES ; illeg - DEC FS ; illeg - DEC GS ; illeg - DEC #$1234 ; illeg - DEC WORD #$1234 ; illeg - DEC WORD [BX] - - DEC EAX - DEC EBX - DEC ECX - DEC EDX - DEC ESP - DEC EBP - DEC ESI - DEC EDI - DEC #$12345678 ; illeg - DEC DWORD #$12345678 ; illeg - DEC DWORD [BX] diff --git a/bin86-0.3/as/asm/inher.asm b/bin86-0.3/as/asm/inher.asm deleted file mode 100644 index f1343fa..0000000 --- a/bin86-0.3/as/asm/inher.asm +++ /dev/null @@ -1,127 +0,0 @@ -; INHER.ASM - -; INHER opcodes - - AAA - AAS - - CLC - CLD - CLI - CLTS - CMC - CMPSB - - DAA - DAS - - HLT - - INTO - INSB - - LAHF - LEAVE - LOCK - LODSB - - MOVSB - - NOP - - OUTSB - - REP - REPE - REPNE - - SAHF - SCASB - STC - STD - STI - STOSB - - WAIT - -; INHER16 and INHER32 opcodes - - USE16 - - CBW - CWD - CWDE - CDQ - CMPSW - CMPSD - - INSW - INSD - IRET - IRETD - - LODSW - LODSD - - MOVSW - MOVSD - - OUTSW - OUTSD - - POPA - POPAD - POPF - POPFD - PUSHA - PUSHAD - PUSHF - PUSHFD - - SCASW - SCASD - STOSW - STOSW - - XLAT - XLATB - - USE32 - - CBW - CWD - CWDE - CDQ - CMPSW - CMPSD - - INSW - INSD - IRET - IRETD - - LODSW - LODSD - - MOVSW - MOVSD - - OUTSW - OUTSD - - POPA - POPAD - POPF - POPFD - PUSHA - PUSHAD - PUSHF - PUSHFD - - SCASW - SCASD - STOSW - STOSW - - XLAT - XLATB diff --git a/bin86-0.3/as/asm/inout.asm b/bin86-0.3/as/asm/inout.asm deleted file mode 100644 index 3f0a3f2..0000000 --- a/bin86-0.3/as/asm/inout.asm +++ /dev/null @@ -1,25 +0,0 @@ - IN EAX,DX ; plain IN is no longer allowed - INB - IN AL,DX - INW - IN AX,DX - IN EAX,DX - IN AL,$20 - IN AL,$101 - IN AX,$20 - IN AX,$101 - IN EAX,$20 - IN EAX,$101 - - OUTB DX,EAX ; plain OUT is no longer allowed - OUTB - OUT DX,AL - OUTW - OUT DX,AX - OUT DX,EAX - OUT $20,AL - OUT $101,AL - OUT $20,AX - OUT #101,AX - OUT $20,EAX - OUT $101,EAX diff --git a/bin86-0.3/as/asm/movspec.asm b/bin86-0.3/as/asm/movspec.asm deleted file mode 100644 index a4f9c15..0000000 --- a/bin86-0.3/as/asm/movspec.asm +++ /dev/null @@ -1,246 +0,0 @@ -mov eax,cr0 -mov eax,cr2 -mov eax,cr3 -mov eax,dr0 -mov eax,dr1 -mov eax,dr2 -mov eax,dr3 -mov eax,dr6 -mov eax,dr7 -mov eax,tr3 -mov eax,tr4 -mov eax,tr5 -mov eax,tr6 -mov eax,tr7 - -mov cr0,eax -mov cr2,eax -mov cr3,eax -mov dr0,eax -mov dr1,eax -mov dr2,eax -mov dr3,eax -mov dr6,eax -mov dr7,eax -mov tr3,eax -mov tr4,eax -mov tr5,eax -mov tr6,eax -mov tr7,eax - - -mov ebx,cr0 -mov ebx,cr2 -mov ebx,cr3 -mov ebx,dr0 -mov ebx,dr1 -mov ebx,dr2 -mov ebx,dr3 -mov ebx,dr6 -mov ebx,dr7 -mov ebx,tr3 -mov ebx,tr4 -mov ebx,tr5 -mov ebx,tr6 -mov ebx,tr7 - -mov cr0,ebx -mov cr2,ebx -mov cr3,ebx -mov dr0,ebx -mov dr1,ebx -mov dr2,ebx -mov dr3,ebx -mov dr6,ebx -mov dr7,ebx -mov tr3,ebx -mov tr4,ebx -mov tr5,ebx -mov tr6,ebx -mov tr7,ebx - - -mov ecx,cr0 -mov ecx,cr2 -mov ecx,cr3 -mov ecx,dr0 -mov ecx,dr1 -mov ecx,dr2 -mov ecx,dr3 -mov ecx,dr6 -mov ecx,dr7 -mov ecx,tr3 -mov ecx,tr4 -mov ecx,tr5 -mov ecx,tr6 -mov ecx,tr7 - -mov cr0,ecx -mov cr2,ecx -mov cr3,ecx -mov dr0,ecx -mov dr1,ecx -mov dr2,ecx -mov dr3,ecx -mov dr6,ecx -mov dr7,ecx -mov tr3,ecx -mov tr4,ecx -mov tr5,ecx -mov tr6,ecx -mov tr7,ecx - - -mov edx,cr0 -mov edx,cr2 -mov edx,cr3 -mov edx,dr0 -mov edx,dr1 -mov edx,dr2 -mov edx,dr3 -mov edx,dr6 -mov edx,dr7 -mov edx,tr3 -mov edx,tr4 -mov edx,tr5 -mov edx,tr6 -mov edx,tr7 - -mov cr0,edx -mov cr2,edx -mov cr3,edx -mov dr0,edx -mov dr1,edx -mov dr2,edx -mov dr3,edx -mov dr6,edx -mov dr7,edx -mov tr3,edx -mov tr4,edx -mov tr5,edx -mov tr6,edx -mov tr7,edx - - -mov esi,cr0 -mov esi,cr2 -mov esi,cr3 -mov esi,dr0 -mov esi,dr1 -mov esi,dr2 -mov esi,dr3 -mov esi,dr6 -mov esi,dr7 -mov esi,tr3 -mov esi,tr4 -mov esi,tr5 -mov esi,tr6 -mov esi,tr7 - -mov cr0,esi -mov cr2,esi -mov cr3,esi -mov dr0,esi -mov dr1,esi -mov dr2,esi -mov dr3,esi -mov dr6,esi -mov dr7,esi -mov tr3,esi -mov tr4,esi -mov tr5,esi -mov tr6,esi -mov tr7,esi - - -mov edi,cr0 -mov edi,cr2 -mov edi,cr3 -mov edi,dr0 -mov edi,dr1 -mov edi,dr2 -mov edi,dr3 -mov edi,dr6 -mov edi,dr7 -mov edi,tr3 -mov edi,tr4 -mov edi,tr5 -mov edi,tr6 -mov edi,tr7 - -mov cr0,edi -mov cr2,edi -mov cr3,edi -mov dr0,edi -mov dr1,edi -mov dr2,edi -mov dr3,edi -mov dr6,edi -mov dr7,edi -mov tr3,edi -mov tr4,edi -mov tr5,edi -mov tr6,edi -mov tr7,edi - - -mov esp,cr0 -mov esp,cr2 -mov esp,cr3 -mov esp,dr0 -mov esp,dr1 -mov esp,dr2 -mov esp,dr3 -mov esp,dr6 -mov esp,dr7 -mov esp,tr3 -mov esp,tr4 -mov esp,tr5 -mov esp,tr6 -mov esp,tr7 - -mov cr0,esp -mov cr2,esp -mov cr3,esp -mov dr0,esp -mov dr1,esp -mov dr2,esp -mov dr3,esp -mov dr6,esp -mov dr7,esp -mov tr3,esp -mov tr4,esp -mov tr5,esp -mov tr6,esp -mov tr7,esp - - -mov ebp,cr0 -mov ebp,cr2 -mov ebp,cr3 -mov ebp,dr0 -mov ebp,dr1 -mov ebp,dr2 -mov ebp,dr3 -mov ebp,dr6 -mov ebp,dr7 -mov ebp,tr3 -mov ebp,tr4 -mov ebp,tr5 -mov ebp,tr6 -mov ebp,tr7 - -mov cr0,ebp -mov cr2,ebp -mov cr3,ebp -mov dr0,ebp -mov dr1,ebp -mov dr2,ebp -mov dr3,ebp -mov dr6,ebp -mov dr7,ebp -mov tr3,ebp -mov tr4,ebp -mov tr5,ebp -mov tr6,ebp -mov tr7,ebp diff --git a/bin86-0.3/as/asm/pushpop.asm b/bin86-0.3/as/asm/pushpop.asm deleted file mode 100644 index b45117a..0000000 --- a/bin86-0.3/as/asm/pushpop.asm +++ /dev/null @@ -1,86 +0,0 @@ - PUSH AL ; illeg - PUSH AH ; illeg - PUSH BL ; illeg - PUSH BH ; illeg - PUSH CL ; illeg - PUSH CH ; illeg - PUSH DL ; illeg - PUSH DH ; illeg - PUSH #1 ; illeg - PUSH BYTE #1 ; illeg - PUSH [BX] ; illeg - PUSH BYTE [BX] ; illeg - PUSH WORD #-1 ; right way to push a signed byte value - - PUSH AX - PUSH BX - PUSH CX - PUSH DX - PUSH SP - PUSH BP - PUSH SI - PUSH DI - PUSH CS - PUSH DS - PUSH ES - PUSH FS - PUSH GS - PUSH SS - PUSH #$1234 ; illeg - PUSH WORD #$1234 - PUSH WORD [BX] - - PUSH EAX - PUSH EBX - PUSH ECX - PUSH EDX - PUSH ESP - PUSH EBP - PUSH ESI - PUSH EDI - PUSH #$12345678 ; illeg - PUSH DWORD #$12345678 - PUSH DWORD [BX] - - POP AL ; illeg - POP AH ; illeg - POP BL ; illeg - POP BH ; illeg - POP CL ; illeg - POP CH ; illeg - POP DL ; illeg - POP DH ; illeg - POP #1 ; illeg - POP BYTE #1 ; illeg - POP [BX] ; illeg - POP BYTE [BX] ; illeg - - POP AX - POP BX - POP CX - POP DX - POP SP - POP BP - POP SI - POP DI - POP CS ; illeg - POP DS - POP ES - POP FS - POP GS - POP SS - POP #$1234 ; illeg - POP WORD #$1234 ; illeg - POP WORD [BX] - - POP EAX - POP EBX - POP ECX - POP EDX - POP ESP - POP EBP - POP ESI - POP EDI - POP #$12345678 ; illeg - POP DWORD #$12345678 ; illeg - POP DWORD [BX] diff --git a/bin86-0.3/as/asm/seg.asm b/bin86-0.3/as/asm/seg.asm deleted file mode 100644 index 0394615..0000000 --- a/bin86-0.3/as/asm/seg.asm +++ /dev/null @@ -1,6 +0,0 @@ - SEG CS - SEG DS - SEG ES - SEG FS - SEG GS - SEG SS diff --git a/bin86-0.3/as/asm/shdouble.asm b/bin86-0.3/as/asm/shdouble.asm deleted file mode 100644 index 1080ece..0000000 --- a/bin86-0.3/as/asm/shdouble.asm +++ /dev/null @@ -1,34 +0,0 @@ -; SHDOUBLE.ASM - -ILLEGALS EQU 1 - -; 0F A4 SHLD r/m16,r16,imm8 3/7 -; 0F A4 SHLD r/m32,r32,imm8 3/7 -; 0F A5 SHLD r/m16,r16,CL 3/7 -; 0F A5 SHLD r/m32,r32,CL 3/7 - -; 0F AC SHRD r/m16,r16,imm8 3/7 -; 0F AC SHRD r/m32,r32,imm8 3/7 -; 0F AD SHRD r/m16,r16,CL 3/7 -; 0F AD SHRD r/m32,r32,CL 3/7 - -IF ILLEGALS - SHLD AL,BL,8 ; byte size - SHLD AX,8,8 ; immediate source - SHLD AX,DS,8 ; segment register - SHLD AX,[BX],8 ; non-register source - SHLD AX,BX,256 ; shift count too big - SHLD AL,BL,8 ; byte size -ENDIF - - SHLD BX,CX,3 - SHLD EDX,ESI,1 - SHLD CX,BX,CL - SHLD ESI,EDX,1 - SHLD [BX],CX,3 - SHLD [BX],ECX,1 - SHLD [SI],BX,CL - SHLD [SI],EBX,CL - - SHRD BX,CX,3 - SHRD CX,BX,CL diff --git a/bin86-0.3/as/asm/shift.asm b/bin86-0.3/as/asm/shift.asm deleted file mode 100644 index 35cc23f..0000000 --- a/bin86-0.3/as/asm/shift.asm +++ /dev/null @@ -1,119 +0,0 @@ - RCL AL,CL - RCL AH,CL - RCL BL,CL - RCL BH,CL - RCL CL,CL - RCL CH,CL - RCL DL,CL - RCL DH,CL - RCL #1,CL ; illeg - RCL [BX],CL ; illeg - RCL BYTE [BX],CL - - RCL AX,CL - RCL BX,CL - RCL CX,CL - RCL DX,CL - RCL SP,CL - RCL BP,CL - RCL SI,CL - RCL DI,CL - RCL CS,CL ; illeg - RCL DS,CL ; illeg - RCL ES,CL ; illeg - RCL FS,CL ; illeg - RCL GS,CL ; illeg - RCL WORD [BX],CL - - RCL EAX,CL - RCL EBX,CL - RCL ECX,CL - RCL EDX,CL - RCL ESP,CL - RCL EBP,CL - RCL ESI,CL - RCL EDI,CL - RCL DWORD [BX],CL - - RCL AL,1 - RCL AH,1 - RCL BL,1 - RCL BH,1 - RCL CL,1 - RCL CH,1 - RCL DL,1 - RCL DH,1 - RCL #1,1 ; illeg - RCL [BX],1 ; illeg - RCL BYTE [BX],1 - - RCL AX,1 - RCL BX,1 - RCL CX,1 - RCL DX,1 - RCL SP,1 - RCL BP,1 - RCL SI,1 - RCL DI,1 - RCL CS,1 ; illeg - RCL DS,1 ; illeg - RCL ES,1 ; illeg - RCL FS,1 ; illeg - RCL GS,1 ; illeg - RCL WORD [BX],1 - - RCL EAX,1 - RCL EBX,1 - RCL ECX,1 - RCL EDX,1 - RCL ESP,1 - RCL EBP,1 - RCL ESI,1 - RCL EDI,1 - RCL DWORD [BX],1 - - RCL AL,15 - RCL AH,15 - RCL BL,15 - RCL BH,15 - RCL CL,15 - RCL CH,15 - RCL DL,15 - RCL DH,15 - RCL #1,15 ; illeg - RCL [BX],15 ; illeg - RCL BYTE [BX],15 - RCL AL,$1000 - - RCL AX,15 - RCL BX,15 - RCL CX,15 - RCL DX,15 - RCL SP,15 - RCL BP,15 - RCL SI,15 - RCL DI,15 - RCL CS,15 ; illeg - RCL DS,15 ; illeg - RCL ES,15 ; illeg - RCL FS,15 ; illeg - RCL GS,15 ; illeg - RCL WORD [BX],15 - - RCL EAX,15 - RCL EBX,15 - RCL ECX,15 - RCL EDX,15 - RCL ESP,15 - RCL EBP,15 - RCL ESI,15 - RCL EDI,15 - RCL DWORD [BX],15 - - RCR AX,7 - ROL AX,7 - ROR AX,7 - SAL AX,7 - SAR AX,7 - SHL AX,7 - SHR AX,7 diff --git a/bin86-0.3/as/asm/summary.as b/bin86-0.3/as/asm/summary.as deleted file mode 100644 index cd62e37..0000000 --- a/bin86-0.3/as/asm/summary.as +++ /dev/null @@ -1,385 +0,0 @@ -general: - ; AL,imm8 - ; AX,imm16 - ; EAX,imm32 - ; r/m8,imm8 - ; r/m16,imm16 - ; r/m32.imm32 - ; r/m16,signed imm8 - ; r/m32,signed imm8 - ; r/m8,r8 - ; r/m16,r16 - ; r/m32,r32 - ; r8,r/m8 - ; r16,r/m16 - ; r32,r/m32 - -shiftcount: - ; 1 - ; CL - ; imm8 -unary alterable: - ; r/m8 - ; r/m16 - ; r/m32 - - AAA - AAD ; [unsupported base] - AAM ; [unsupported base] - AAS - ADC ; general - ADD ; general - AND ; general - ARPL ; r/m16,r16 - BOUND ; r16,m16&16 - BOUND ; r32,m32&32 - BSF ; r16,r/m16 - BSF ; r32,r/m32 - BSR ; r16,r/m16 - BSR ; r32,r/m32 - BSWAP ; r32 - BT ; r/m16,r16 - BT ; r/m32,r32 - BT ; r/m16,imm8 - BT ; r/m32,imm8 - BTC ; r/m16,r16 - BTC ; r/m32,r32 - BTC ; r/m16,imm8 - BTC ; r/m32,imm8 - BTR ; r/m16,r16 - BTR ; r/m32,r32 - BTR ; r/m16,imm8 - BTR ; r/m32,imm8 - BTS ; r/m16,r16 - BTS ; r/m32,r32 - BTS ; r/m16,imm8 - BTS ; r/m32,imm8 - CALL ; rel16 - CALL ; r/m16 - CALL ; ptr16:16 - CALL ; m16:16 - CALL ; rel32 - CALL ; r/m32 - CALL ; ptr16:32 - CALL ; m16:32 - CBW - CDQ - CLC - CLD - CLI - CLTS - CMC - CMP ; general - CMPS ; [segreg:]m8,m8 - CMPS ; [segreg:]m16,m16 - CMPS ; [segreg:]m32,m32 - CMPSB - CMPSW - CMPSD - CMPXCHG ; r/m8,r8 - CMPXCHG ; r/m16,r16 - CMPXCHG ; r/m32,r32 - CWD - CWDE - DAA - DAS - DEC ; unary alterable - DEC ; r16 - DEC ; r32 - DIV ; AL,r/m8 - DIV ; AX,r/m16 - DIV ; EAX,r/m32 - ENTER ; imm16,imm8 - HLT - IDIV ; AL,r/m8 - IDIV ; AX,r/m16 - IDIV ; EAX,r/m32 - IMUL ; r/m8 - IMUL ; r/m16 - IMUL ; r/m32 - IMUL ; r16,r/m16 - IMUL ; r32,r/m32 - IMUL ; r16,r/m16,imm8 - IMUL ; r32,r/m32,imm8 - IMUL ; r16,imm8 - IMUL ; r32,imm8 - IMUL ; r16,r/m16,imm16 - IMUL ; r32,r/m32,imm32 - IMUL ; r16,imm16 - IMUL ; r32,imm32 - IN ; AL,imm8 - IN ; AX,imm8 - IN ; EAX,imm8 - IN ; AL,DX - IN ; AX,DX - IN ; EAX,DX - INC ; unary alterable - INC ; r16 - INC ; r32 - INSB - INSW - INSD - INT ; imm8 - INTO - INVD - INVLPG ; m - IRET - IRETD - JCC ; rel8 - JCC ; rel16/32 - JA - JAE - JB - JBE - JC - JCXZ - JECXZ - JE - JG - JGE - JL - JLE - JNA - JNAE - JNB - JNBE - JNC - JNE - JNG - JNGE - JNL - JNLE - JNO - JNP - JNS - JNZ - JO - JP - JPE - JPO - JS - JZ - JMP ; rel8 - JMP ; rel16 - JMP ; r/m16 - JMP ; ptr16:16 - JMP ; m16:16 - JMP ; rel32 - JMP ; r/m32 - JMP ; ptr16:32 - JMP ; m16:32 - LAHF - LAR ; r16,r/m16 - LAR ; r32,r/m32 - LEA ; r16,m - LEA ; r32,m - LEAVE - LGDT ; m16&32 - LIDT ; m16&32 - LDS ; r16,m16:16 - LDS ; r32,m16:32 - LES ; r16,m16:16 - LES ; r32,m16:32 - LFS ; r16,m16:16 - LFS ; r32,m16:32 - LGS ; r16,m16:16 - LGS ; r32,m16:32 - LSS ; r16,m16:16 - LSS ; r32,m16:32 - LLDT ; r/m16 - LMSW ; r/m16 - LOCK - LODS ; [segreg:]m8 - LODS ; [segreg:]m16 - LODS ; [segreg:]m32 - LODSB - LODSW - LODSD - LOOP ; rel8 - LOOPE ; rel8 - LOOPZ ; rel8 - LOOPNE ; rel8 - LOOPNZ ; rel8 - LSL ; r16,r/m16 - LSL ; r32,r/m32 - LTR ; r/m16 - MOV ; r/m8,r8 - MOV ; r/m16,r16 - MOV ; r/m32,r32 - MOV ; r8,r/m8 - MOV ; r16,r/m16 - MOV ; r32,r/m32 - MOV ; r/m16,Sreg - MOV ; Sreg,r/m16 - MOV ; AL,moffs8 - MOV ; AX,moffs16 - MOV ; EAX,moffs32 - MOV ; moffs8,AL - MOV ; moffs16,AX - MOV ; moffs32,EAX - MOV ; r8,imm8 - MOV ; r16,imm16 - MOV ; r32,imm32 - MOV ; r32,CR0/CR2/CR3 - MOV ; r/m8,imm8 - MOV ; r/m16,imm16 - MOV ; r/m32,imm32 - MOV ; r32,CR0/CR2/CR3 - MOV ; CR0/CR2/CR3,r32 - MOV ; r32,DR0/DR1/DR2/DR3/DR6/DR7 - MOV ; DR0/DR1/DR2/DR3/DR6/DR7,r32 - MOV ; r32,TR6/TR7 - MOV ; TR6/TR7,r32 - MOVS ; [segreg:]m8,m8 - MOVS ; [segreg:]m16,m16 - MOVS ; [segreg:]m32,m32 - MOVSB - MOVSW - MOVSD - MOVSX ; r16,r/m8 - MOVSX ; r32,r/m8 - MOVSX ; r32,r/m16 - MOVZX ; r16,r/m8 - MOVZX ; r32,r/m8 - MOVZX ; r32,r/m16 - MUL ; AL,r/m8 - MUL ; AX,r/m16 - MUL ; EAX,r/m32 - NEG ; unary alterable - NOP - NOT ; unary alterable - OR ; general - OUT ; imm8,AL - OUT ; imm8,AX - OUT ; imm8,EAX - OUT ; DX,AL - OUT ; DX,AX - OUT ; DX,EAX - OUTS ; [segreg:]m8 - OUTS ; [segreg:]m16 - OUTS ; [segreg:]m32 - OUTSB - OUTSW - OUTSD - POP ; m16 - POP ; m32 - POP ; r16 - POP ; r32 - POP ; DS - POP ; ES - POP ; FS - POP ; GS - POP ; SS - POPA - POPAD - POPF - POPFD - PUSH ; m16 - PUSH ; m32 - PUSH ; r16 - PUSH ; r32 - PUSH ; imm8 - PUSH ; imm16 - PUSH ; imm32 - PUSH ; CS - PUSH ; DS - PUSH ; ES - PUSH ; FS - PUSH ; GS - PUSH ; SS - PUSHA - PUSHAD - PUSHF - PUSHFD - RCL ; shiftcount - RCR ; shiftcount - ROL ; shiftcount - ROR ; shiftcount - REP ; INS/MOVS/OUTS/STOS - REPE ; CMPS/SCAS - REPNE ; CMPS/SCAS - RET - RET ; imm16 - SAHF - SAL ; shiftcount - SAR ; shiftcount - SHL ; shiftcount - SHR ; shiftcount - SBB ; general - SCASB - SCASW - SCASD - SETA ; r/m8 - SETAE ; r/m8 - SETB ; r/m8 - SETBE ; r/m8 - SETC ; r/m8 - SETE ; r/m8 - SETG ; r/m8 - SETGE ; r/m8 - SETL ; r/m8 - SETLE ; r/m8 - SETNA ; r/m8 - SETNAE ; r/m8 - SETNB ; r/m8 - SETNBE ; r/m8 - SETNC ; r/m8 - SETNE ; r/m8 - SETNG ; r/m8 - SETNGE ; r/m8 - SETNL ; r/m8 - SETNLE ; r/m8 - SETNO ; r/m8 - SETNP ; r/m8 - SETNS ; r/m8 - SETNZ ; r/m8 - SETO ; r/m8 - SETP ; r/m8 - SETPE ; r/m8 - SETPO ; r/m8 - SETS ; r/m8 - SETZ ; r/m8 - SGDT ; m - SHLD ; r/m16,r16,imm8 - SHLD ; r/m32,r32,imm8 - SHLD ; r/m16,r16,CL - SHLD ; r/m32,r32,CL - SHRD ; r/m16,r16,imm8 - SHRD ; r/m32,r32,imm8 - SHRD ; r/m16,r16,CL - SHRD ; r/m32,r32,CL - SIDT ; m - SLDT ; r/m16 - SMSW ; r/m16 - STC - STD - STI - STOSB - STOSW - STOSD - STR ; r/m16 - SUB ; general - TEST ; AL,imm8 - TEST ; AX,imm16 - TEST ; EAX,imm32 - TEST ; r/m8,imm8 - TEST ; r/m16,imm16 - TEST ; r/m32,imm32 - TEST ; r/m8,r8 - TEST ; r/m16,r16 - TEST ; r/m32/r32 - VERR ; r/m16 - VERW ; r/m16 - WAIT - WBINVD - XADD ; r/m8,r8 - XADD ; r/m16,r16 - XADD ; r/m32,r32 - XCHG ; AX,r16 - XCHG ; EAX,r32 - XCHG ; r/m8,r8 - XCHG ; r/m16,r16 - XCHG ; r/m32,r32 - XLAT ; [segreg:]m8 - XLATB - XOR ; general diff --git a/bin86-0.3/as/asm/xchg.asm b/bin86-0.3/as/asm/xchg.asm deleted file mode 100644 index f05157f..0000000 --- a/bin86-0.3/as/asm/xchg.asm +++ /dev/null @@ -1,103 +0,0 @@ - XCHG AX,BL ; illeg - XCHG AX,BYTE [BX] ; illeg - XCHG AX,DS ; illeg - XCHG AX,#1 ; illeg - - XCHG AX,AX - XCHG AX,BX - XCHG AX,CX - XCHG AX,DX - XCHG AX,SP - XCHG AX,BP - XCHG AX,SI - XCHG AX,DI - - XCHG AX,AX - XCHG BX,AX - XCHG CX,AX - XCHG DX,AX - XCHG SP,AX - XCHG BP,AX - XCHG SI,AX - XCHG DI,AX - - XCHG EAX,EAX - XCHG EAX,EBX - XCHG EAX,ECX - XCHG EAX,EDX - XCHG EAX,ESP - XCHG EAX,EBP - XCHG EAX,ESI - XCHG EAX,EDI - - XCHG EAX,EAX - XCHG EBX,EAX - XCHG ECX,EAX - XCHG EDX,EAX - XCHG ESP,EAX - XCHG EBP,EAX - XCHG ESI,EAX - XCHG EDI,EAX - - XCHG AL,AL - XCHG AL,AH - XCHG AL,BL - XCHG AL,BH - XCHG BL,CL - XCHG BL,CH - XCHG BL,DL - XCHG BL,DH - - XCHG [BX],AL - XCHG [BX],AH - XCHG [BX],BL - XCHG [BX],BH - XCHG [BX],CL - XCHG [BX],CH - XCHG [BX],DL - XCHG [BX],DH - - XCHG AL,[BX] - XCHG AH,[BX] - XCHG BL,[BX] - XCHG BH,[BX] - XCHG CL,[BX] - XCHG CH,[BX] - XCHG DL,[BX] - XCHG DH,[BX] - - XCHG [BX],AX - XCHG [BX],BX - XCHG [BX],CX - XCHG [BX],DX - XCHG [BX],SP - XCHG [BX],BP - XCHG [BX],SI - XCHG [BX],DI - - XCHG AX,[BX] - XCHG BX,[BX] - XCHG CX,[BX] - XCHG DX,[BX] - XCHG SP,[BX] - XCHG BP,[BX] - XCHG SI,[BX] - XCHG DI,[BX] - - XCHG [BX],EAX - XCHG [BX],EBX - XCHG [BX],ECX - XCHG [BX],EDX - XCHG [BX],ESP - XCHG [BX],EBP - XCHG [BX],ESI - XCHG [BX],EDI - - XCHG AX,[EBX] - XCHG BX,[EBX] - XCHG CX,[EBX] - XCHG DX,[EBX] - XCHG SP,[EBX] - XCHG BP,[EBX] - XCHG SI,[EBX] - XCHG DI,[EBX] diff --git a/bin86-0.3/as/assemble.c b/bin86-0.3/as/assemble.c deleted file mode 100644 index 4e96178..0000000 --- a/bin86-0.3/as/assemble.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * bin86/as/assemble.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* assemble.c - main loop for assembler */ - -#include "const.h" -#include "type.h" -#include "address.h" -#include "globvar.h" -#include "opcode.h" -#include "scan.h" - -PRIVATE bool_t nocolonlabel; /* set for labels not followed by ':' */ -PRIVATE void (*routine) P((void)); -PRIVATE pfv rout_table[] = -{ - pelse, - pelseif, - pelsifc, - pendif, - pif, - pifc, - - /* start of non-conditionals */ - palign, - pblkw, - pblock, - pbss, - pcomm, - pcomm1, - pdata, - pendb, - penter, - pentry, - pequ, - peven, - pexport, - pfail, - pfcb, - pfcc, - pfdb, - pfqb, - pget, - pglobl, - pident, - pimport, - plcomm, - plcomm1, - plist, - ploc, - pmaclist, - pmacro, - pmap, - porg, - pproceof, - prmb, - psect, - pset, - psetdp, - ptext, -#ifdef I80386 - puse16, - puse32, -#endif - pwarn, - /* end of pseudo-ops */ - -#ifdef I80386 - mbcc, - mbswap, - mcall, - mcalli, - mdivmul, - menter, - mEwGw, - mExGx, - mf_inher, - mf_m, - mf_m2, - mf_m2_ax, - mf_m2_m4, - mf_m2_m4_m8, - mf_m4_m8_optst, - mf_m4_m8_st, - mf_m4_m8_stst, - mf_m4_m8_m10_st, - mf_m10, - mf_optst, - mf_st, - mf_stst, - mf_w_inher, - mf_w_m, - mf_w_m2, - mf_w_m2_ax, - mgroup1, - mgroup2, - mgroup6, - mgroup7, - mgroup8, - mGvEv, - mGvMa, - mGvMp, - mimul, - min, - mincdec, - minher, - minher16, - minher32, - minhera, - mint, - mjcc, - mjcxz, - mlea, - mmov, - mmovx, - mnegnot, - mout, - mpushpop, - mret, - mseg, - msetcc, - mshdouble, - mtest, - mxchg, -#endif /* I80386 */ - -#ifdef MC6809 - mall, /* all address modes allowed, like LDA */ - malter, /* all but immediate, like STA */ - mimmed, /* immediate only (ANDCC, ORCC) */ - mindex, /* indexed (LEA's) */ - minher, /* inherent, like CLC or CLRA */ - mlong, /* long branches */ - mshort, /* short branches */ - msstak, /* S-stack (PSHS, PULS) */ - mswap, /* TFR, EXG */ - mustak, /* U-stack (PSHU,PULU) */ -#endif /* MC6809 */ -}; - -FORWARD void asline P((void)); - -/* - This uses registers as follows: A is for work and is not preserved by - the subroutines.B holds the last symbol code, X usually points to data - about the last symbol, U usually holds the value of last expression - or symbol, and Y points to the current char. The value in Y is needed - by READCH and GETSYM. EXPRES needs B and Y, and returns a value in U. - If the expression starts with an identifier, X must point to its string. - LOOKUP needs a string pointer in X and length in A. It returns a table - pointer in X (unless not assembling and not found), symbol type in A - and overflow in CC. -*/ - -PUBLIC void assemble() -{ - while (TRUE) - { - asline(); - if (label != NULL) /* must be confirmed if still set */ - { /* it is nulled by EQU, COMM and SET */ -#ifndef MC6809 -#define NEEDENDLABEL ILLAB - if (nocolonlabel) - error(NEEDENDLABEL); -#endif - label->type |= LABIT; /* confirm, perhaps redundant */ - if (label->type & REDBIT) - { - /* REDBIT meant 'GLOBLBIT' while LABIT was not set. */ - label->type |= EXPBIT; - label->type &= ~REDBIT; - } - if ((mcount | popflags) == 0) - /* unaccompanied label, display adr like EQU and SET */ - showlabel(); - label = NULL; /* reset for next line */ - } - skipline(); - listline(); - genbin(); - genobj(); - binmbuf = lc += lcjump -#ifdef I80386 - + immcount -#endif - ; - } -} - -PRIVATE void asline() -{ - register struct sym_s *symptr; - - postb = popflags = pcrflag = -#ifdef I80386 - sprefix = oprefix = aprefix = -#endif - immcount = lastexp.data = lcjump = 0; -#ifdef I80386 - sib = NO_SIB; -#endif -#if SIZEOF_OFFSET_T > 2 - fqflag = -#endif - fdflag = fcflag = FALSE; - readline(); - getsym(); - if (sym != IDENT) /* expect label, mnemonic or macro */ - return; /* anything else is a comment */ - symptr = gsymptr; - if (!ifflag) - /* not assembling, just test for IF/ELSE/ELSEIF/ENDIF */ - { - if (symptr == NULL || !(symptr->type & MNREGBIT) || - symptr->data & REGBIT || - symptr->value_reg_or_op.op.routine >= MIN_NONCOND) - return; - } - else if (!(symptr->type & (MACBIT | MNREGBIT))) - /* not macro, op, pseudo-op or register, expect label */ - { - if ((nocolonlabel = (*lineptr - ':')) == 0) /* exported label? */ - { - sym = COLON; - ++lineptr; - } - if (symptr->type & (LABIT | VARBIT)) - { - if (symptr->type & REDBIT) - labelerror(RELAB); - label = symptr; - } - else if (checksegrel(symptr)) - { - symptr->type &= ~COMMBIT; /* ignore COMM, PCOMM gives warning */ -#ifdef MC6809 -#if 0 - if (sym == COLON) - symptr->type |= EXPBIT; -#endif -#endif - symptr->data = (symptr->data & FORBIT) | lcdata; - /* remember if forward referenced */ - symptr->value_reg_or_op.value = lc; - /* unless changed by EQU,COMM or SET */ - label = symptr; - } - getsym(); - if (sym != IDENT) - { - if (sym == EQOP) - { - getsym(); - pequ(); - } - return; /* anything but ident is comment */ - } - symptr = gsymptr; - } - if (symptr->type & MACBIT) - { - entermac(symptr); - return; - } - if (!(symptr->type & MNREGBIT)) - { - error(OPEXP); - return; - } - if (symptr->data & REGBIT) - { - error(REGUID); - return; - } - mnsize = 0; - if ((page = (symptr->data & (PAGE1 | PAGE2))) != 0) - { -#ifdef MNSIZE - if (page == (PAGE1 | PAGE2)) - { - mnsize = 1; - page = 0; - } - else -#endif - { -#ifdef PAGE2_OPCODE - if (page == PAGE2) - page = PAGE2_OPCODE; - else -#endif - page = PAGE1_OPCODE; - mcount = 1; - } - } - opcode = symptr->value_reg_or_op.op.opcode; - routine = rout_table[symptr->value_reg_or_op.op.routine]; - getsym(); - (*routine)(); - if (sym != EOLSYM) - error(JUNK_AFTER_OPERANDS); -#ifdef I80386 - if (aprefix != 0) - ++mcount; - if (oprefix != 0) - ++mcount; - if (sprefix != 0) - ++mcount; -#endif -} diff --git a/bin86-0.3/as/byteord.h b/bin86-0.3/as/byteord.h deleted file mode 100644 index 01d2d85..0000000 --- a/bin86-0.3/as/byteord.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * bin86/as/byteord.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* byteord.h - byte order dependencies for C compiler, assembler, linker */ - -/* These are for the targets of everything and for linker source too. */ - -#ifdef I8086 -# define BIG_ENDIAN 0 -# define LONG_BIG_ENDIAN 0 /* except longs are back to front for Xenix */ -#endif - -#ifdef I80386 -# define BIG_ENDIAN 0 -# define LONG_BIG_ENDIAN 0 -#endif - -#ifdef MC6809 -# define BIG_ENDIAN 1 /* byte order in words is high-low */ -# define LONG_BIG_ENDIAN 1 /* byte order in longs is high-low */ -#endif diff --git a/bin86-0.3/as/chk b/bin86-0.3/as/chk deleted file mode 100755 index ce55954..0000000 --- a/bin86-0.3/as/chk +++ /dev/null @@ -1,9 +0,0 @@ -for i in `ls asm/*.asm` -do - j=`basename $i .asm` - ./as asm/$j.asm -b $j.bin -o $j.obj > /dev/null - cmp $j.bin bin/$j.bin - cmp $j.obj obj/$j.obj - rm $j.bin $j.obj -done - diff --git a/bin86-0.3/as/const.h b/bin86-0.3/as/const.h deleted file mode 100644 index 7961cf5..0000000 --- a/bin86-0.3/as/const.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * bin86/as/const.h - * - * Copyright (C) 1992 Bruce Evans - */ - -#undef __BYTE_ORDER -#undef __LITTLE_ENDIAN -#undef __BIG_ENDIAN -#include "endian.h" -#define __LITTLE_ENDIAN 1234 -#define __BIG_ENDIAN 4321 - -#if __BYTE_ORDER == __BIG_ENDIAN -#define LOW_BYTE 3 -#else -#define LOW_BYTE 0 -#endif - -#define align(x) ((x) = (void *)(((int) (x) + (4-1)) & ~(4-1))) -/* const.h - constants for assembler */ - -/* major switches */ - -#define I80386 /* generate 80386 code */ -#undef MC6809 /* generate 6809 code */ -#define MNSIZE /* allow byte size in mnemonic, e.g. "movb" */ -#undef SOS_EDOS /* source OS is EDOS */ - -/* defaults */ - -#define DIRCHAR '/' /* character separating filename from dir */ -#define INBUFSIZE 8192 -#define SOS_EOLSTR "\012" - -/* defaults modified by switches */ - -#ifdef SOS_EDOS -# undef INBUFSIZE -# define INBUFSIZE 512 -# undef SOS_EOLSTR -# define SOS_EOLSTR "\015\012" -# define STAKSIZ 256 /* table grows up to stack less this */ -#endif - -/* booleans */ - -#define FALSE 0 -#define TRUE 1 - -/* ASCII constants */ - -#define ETB 23 - -/* C tricks */ - -#define EXTERN extern -#define FORWARD static -#define PRIVATE static -#define PUBLIC - -#ifndef NULL -#define NULL ((void *)0) -#endif - -/* O/S constants */ - -#define CREAT_PERMS 0666 -#define EOF (-1) -#define STDIN 0 -#define STDOUT 1 - -enum -{ -/* Register codes (internal to assembler). */ -#ifdef I80386 - -/* Index regs must be first. */ - BPREG, - BXREG, - DIREG, - SIREG, -#define MAX16BITINDREG SIREG - - EAXREG, - EBPREG, - EBXREG, - ECXREG, - EDIREG, - EDXREG, - ESIREG, - ESPREG, -#define MAXINDREG ESPREG - - AXREG, - CXREG, - DXREG, - SPREG, - - AHREG, - ALREG, - BHREG, - BLREG, - CHREG, - CLREG, - DHREG, - DLREG, - - CSREG, - DSREG, - ESREG, - FSREG, - GSREG, - SSREG, - - CR0REG, - CR2REG, - CR3REG, - DR0REG, - DR1REG, - DR2REG, - DR3REG, - DR6REG, - DR7REG, - TR3REG, - TR4REG, - TR5REG, - TR6REG, - TR7REG, - - ST0REG, - ST1REG, - ST2REG, - ST3REG, - ST4REG, - ST5REG, - ST6REG, - ST7REG, - - NOREG, -#endif /* I80386 */ - -#ifdef MC6809 - -/* Index regs must be first, then PC. */ - SREG, - UREG, - XREG, - YREG, -#define MAXINDREG YREG - - PCREG, - AREG, - BREG, - CCREG, - DPREG, - DREG, - - NOREG, -#endif /* MC6809 */ -}; - -#ifdef I80386 -enum -{ -/* Type and size keywords. */ - BYTEOP, - DWORDOP, - FWORDOP, - FAROP, - PTROP, - PWORDOP, - QWORDOP, - TBYTEOP, - WORDOP, -}; -#endif /* I80386 */ - -/* special chars */ - -#define EOL 0 -#define MACROCHAR '?' - -enum -{ -/* Symbol codes. */ - -/* The first 2 must be from chars in identifiers. */ - IDENT, - INTCONST, - -/* The next few are best for other possibly-multi-char tokens. */ - ADDOP, /* also ++ */ - BINCONST, - CHARCONST, - GREATERTHAN, /* also >> and context-sensitive */ - HEXCONST, - LESSTHAN, /* also << and context-sensitive */ - SUBOP, /* also -- */ - WHITESPACE, - - ANDOP, - COMMA, - EOLSYM, - EQOP, - IMMEDIATE, - INDIRECT, - LBRACKET, - LPAREN, - MACROARG, - NOTOP, - OROP, - OTHERSYM, - POSTINCOP, - PREDECOP, - RBRACKET, - RPAREN, - SLASH, /* context-sensitive */ - SLOP, - SROP, - STAR, /* context-sensitive */ - STRINGCONST, - COLON, -}; - -enum -{ -/* Error codes. */ - -/* Syntax errors. */ - COMEXP, - DELEXP, - FACEXP, - IREGEXP, - LABEXP, - LPEXP, - OPEXP, - RBEXP, - REGEXP, - RPEXP, - SPEXP, - -/* Expression errors. */ - ABSREQ, - NONIMPREQ, - RELBAD, - -/* Label errors. */ - ILLAB, - MACUID, - MISLAB, - MNUID, - REGUID, - RELAB, - UNBLAB, - UNLAB, - VARLAB, - -/* Addressing errors. */ - ABOUNDS, - DBOUNDS, - ILLMOD, - ILLREG, - -/* Control structure errors. */ - ELSEBAD, -#define ELSEIFBAD ELSEBAD - ENDBBAD, -#define ENDIFBAD ELSEBAD - EOFBLOCK, - EOFIF, - EOFLC, - EOFMAC, - FAILERR, - -/* Overflow errors. */ - BLOCKOV, - BWRAP, - COUNTOV, - COUNTUN, - GETOV, - IFOV, - - LINLONG, - MACOV, - OBJSYMOV, - OWRITE, - PAROV, - SYMOV, - SYMOUTOV, - -/* I/O errors. */ - OBJOUT, - -/* Miscellaneous errors. */ - AL_AX_EAX_EXP, - CTLINS, - FURTHER, - ILL_IMM_MODE, - ILL_IND_TO_IND, - ILL_IND, - ILL_IND_PTR, - ILL_SCALE, - ILL_SECTION, - ILL_SEG_REG, - ILL_SOURCE_EA, - ILL_SIZE, - IMM_REQ, - INDEX_REG_EXP, - IND_REQ, - MISMATCHED_SIZE, - NOIMPORT, - REENTER, - REL_REQ, - REPEATED_DISPL, - SEGREL, - SEG_REG_REQ, - SIZE_UNK, - - FP_REG_REQ, - FP_REG_NOT_ALLOWED, - ILL_FP_REG, - ILL_FP_REG_PAIR, - JUNK_AFTER_OPERANDS, - - ALREADY, - -/* Warnings. */ -#define MINWARN SHORTB - SHORTB, -}; - -/* symbol table entry */ - - /* type entry contains following flags */ -#define ENTBIT (1<<0) /* entry point (= OBJ_N_MASK) */ -#define COMMBIT (1<<1) /* common */ -#define LABIT (1<<2) /* label (a PC location or defined by EQU) */ -#define MNREGBIT (1<<3) /* mnemonic for op or pseudo-op, or register */ -#define MACBIT (1<<4) /* macro */ -#define REDBIT (1<<5) /* redefined (if with LABIT or VARBIT), to do - * with SA_MASK (if with COMMBIT), otherwise - * means globl */ -#define VARBIT (1<<6) /* variable (i.e. something defined by SET) */ -#define EXPBIT (1<<7) /* exported (= OBJ_E_MASK) */ - - /* data entry contains following flags, valid */ - /* for expressions as well as syms */ -#define PAGE1 (1<<0) /* page 1 machine op = MNREGBIT | PAGE1 */ -#define PAGE2 (1<<1) /* page 2 machine op = MNREGBIT | PAGE2 */ -#define REGBIT (1<<2) /* register = MNREGBIT | REGBIT */ -#define SIZEBIT (1<<3) /* sizing mnemonic = MNREGBIT | SIZEBIT */ -#define SEGM 0x0F /* 1st 4 bits reused for segment if !MNREGBIT */ -#define RELBIT (1<<4) /* relative (= OBJ_A_MASK) */ -#define FORBIT (1<<5) /* forward referenced */ -#define IMPBIT (1<<6) /* imported (= OBJ_I_MASK) */ -#define UNDBIT (1<<7) /* undefined */ - -/* object code format (Introl) */ - -#define OBJ_SEGSZ_TWO 0x02 /* size 2 code for segment size descriptor */ - -#define OBJ_MAX_ABS_LEN 64 /* max length of chunk of absolute code */ - -#define OBJ_ABS 0x40 /* absolute code command */ -#define OBJ_OFFSET_REL 0x80 /* offset relocation command */ -#define OBJ_SET_SEG 0x20 /* set segment command */ -#define OBJ_SKIP_1 0x11 /* skip with 1 byte count */ -#define OBJ_SKIP_2 0x12 /* skip with 2 byte count */ -#define OBJ_SKIP_4 0x13 /* skip with 4 byte count */ -#define OBJ_SYMBOL_REL 0xC0 /* symbol relocation command */ - -#define OBJ_A_MASK 0x10 /* absolute bit(symbols) */ -#if OBJ_A_MASK - RELBIT /* must match internal format (~byte 1 -> 0) */ -oops - RELBIT misplaced -#endif -#define OBJ_E_MASK 0x80 /* exported bit (symbols) */ -#if OBJ_E_MASK - EXPBIT /* must match internal format (byte 0 -> 0) */ -oops - EXPBIT misplaced -#endif -#define OBJ_I_MASK 0x40 /* imported bit (symbols) */ -#if OBJ_I_MASK - IMPBIT /* must match internal format (byte 1 -> 0) */ -oops - IMPBIT misplaced -#endif -#define OBJ_N_MASK 0x01 /* entry bit (symbols) */ -#if OBJ_N_MASK - ENTBIT /* must match internal format (byte 0 -> 1) */ -oops - ENTBIT misplaced -#endif -#define OBJ_SA_MASK 0x20 /* size allocation bit (symbols) */ -#define OBJ_SZ_ONE 0x40 /* size one code for symbol value */ -#define OBJ_SZ_TWO 0x80 /* size two code for symbol value */ -#define OBJ_SZ_FOUR 0xC0 /* size four code for symbol value */ - -#define OBJ_R_MASK 0x20 /* PC-rel bit (off & sym reloc commands) */ -#define OBJ_SEGM_MASK 0x0F /* segment mask (symbols, off reloc command) */ - -#define OBJ_OF_MASK 0x03 /* offset size code for symbol reloc */ -#define OBJ_S_MASK 0x04 /* symbol number size code for symbol reloc */ - -#define SYMLIS_NAMELEN 26 -#define SYMLIS_LEN (sizeof (struct sym_listing_s)) - -#define FILNAMLEN 64 /* max length of a file name */ -#define LINLEN 256 /* max length of input line */ -#define LINUM_LEN 5 /* length of formatted line number */ - -#define SPTSIZ 1024 /* number of symbol ptrs */ - /* pseudo-op flags */ -#define POPHI 1 /* set to print hi byte of adr */ -#define POPLO 2 /* to print lo byte of ADR */ -#define POPLC 4 /* to print LC */ -#define POPLONG 8 /* to print high word of ADR */ -#define MAXBLOCK 8 /* max nesting level of BLOCK stack */ -#define MAXGET 8 /* max nesting level of GET stack */ -#define MAXIF 8 /* max nesting level of IF stack */ -#define MACPSIZ (128 / sizeof (struct schain_s)) - /* size of macro param buffer */ -#define MAXMAC 8 /* max nesting level of macro stack */ -#define NLOC 16 /* number of location counters */ -#ifdef I80386 -#define NO_SIB 0340 /* illegal sib (3 with 4) to mean no sib */ -#endif - -/* special segments */ - -#define BSSLOC 3 -#define DATALOC 3 -#define DPLOC 2 -#define STRLOC 1 -#define TEXTLOC 0 diff --git a/bin86-0.3/as/error.c b/bin86-0.3/as/error.c deleted file mode 100644 index 343ec8c..0000000 --- a/bin86-0.3/as/error.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * bin86/as/error.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* error.c - error routines for assembler */ - -#include <string.h> -#include "const.h" -#include "type.h" - -PRIVATE char *errormessage[] = -{ - "comma expected", - "delimiter expected", - "factor expected", - "index register expected", - "label expected", - "left parentheses expected", - "opcode expected", - "right bracket expected", - "register expected", - "right parentheses expected", - "space expected", - "absolute expression required", - "non-imported expression required", - "relocation impossible", - "illegal label", - "MACRO used as identifier", - "missing label", - "opcode used as identifier", - "register used as identifier", - "redefined label", - "unbound label", - "undefined label", - "variable used as label", - "address out of bounds", - "data out of bounds", - "illegal address mode", - "illegal register", - "no matching IF", - "no matching BLOCK", - "end of file in BLOCK", - "end of file in IF", - "location counter was undefined at end", - "end of file in MACRO", - "user-generated error", - "BLOCK stack overflow", - "binary file wrap-around", - "counter overflow", - "counter underflow", - "GET stack overflow", - "IF stack overflow", - "line too long", - "MACRO stack overflow", - "object symbol table overflow", - "program overwrite", - "parameter table overflow", - "symbol table overflow", - "output symbol table overflow", - "error writing object file", - "al, ax or eax expected", - "control character in string", - "futher errors suppressed", - "illegal immediate mode", - "illegal indirect to indirect", - "illegal indirection", - "illegal indirection from previous 'ptr'", - "illegal scale", - "illegal section", - "illegal segment register", - "illegal source effective address", - "illegal size", - "immediate expression expected", - "index register expected", - "indirect expression required", - "mismatched size", - "no imports with binary file output", - "multiple ENTER pseudo-ops", - "relative expression required", - "repeated displacement", - "segment or relocatability redefined", - "segment register required", - "size unknown", - "FP register required", - "FP register not allowed", - "illegal FP register", - "illegal FP register pair", - "junk after operands", - "already defined", - "short branch would do", - "unknown error", -}; - -/* build null-terminated error message for given error at given spot */ - -PUBLIC char *build_error_message(errnum, buf) -unsigned errnum; -char *buf; -{ - if (errnum >= sizeof errormessage / sizeof errormessage[0]) - errnum = sizeof errormessage / sizeof errormessage[0] - 1; - return strcpy(buf, errormessage[errnum]); -} diff --git a/bin86-0.3/as/express.c b/bin86-0.3/as/express.c deleted file mode 100644 index 7cd0b55..0000000 --- a/bin86-0.3/as/express.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * bin86/as/express.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* express.c - expression handler for assembler */ - -#include "const.h" -#include "type.h" -#include "address.h" -#include "globvar.h" -#include "scan.h" -#include "source.h" - -FORWARD void experror P((error_pt errnum)); -FORWARD void expundefined P((void)); -FORWARD void simple2 P((void)); -FORWARD void simple P((void)); -FORWARD void term P((void)); -FORWARD void factor2 P((void)); - -PUBLIC void absexpres() -{ - expres(); - chkabs(); -} - -/* check lastexp.data is abs */ - -PUBLIC void chkabs() -{ - if (lastexp.data & RELBIT) - { - if (pass != 0) - error(ABSREQ); - expundefined(); - } -} - -PRIVATE void experror(errnum) -error_pt errnum; -{ - error(errnum); - expundefined(); -} - -PRIVATE void expundefined() -{ - lastexp.data = FORBIT | UNDBIT; -} - -PUBLIC void nonimpexpres() -{ - expres(); - if (lastexp.data & IMPBIT) - experror(NONIMPREQ); -} - -/* generate relocation error if pass 2, make lastexp.data forward&undefined */ - -PUBLIC void showrelbad() -{ - if (pass != 0) - error(RELBAD); - expundefined(); -} - -PUBLIC void symabsexpres() -{ - getsym(); - absexpres(); -} - -PUBLIC void symexpres() -{ - getsym(); - expres(); -} - -/* - expres() parses expression = simple expression [op simple expression], - where op is =, < or >. - Parameters: sym, number in number, identifier from symname to lineptr - 1. - Returns value in lastexp. -*/ - -PUBLIC void expres() -{ - offset_t leftoffset; - - simple(); - leftoffset = lastexp.offset; - if (sym == EQOP) - { - simple2(); - if (leftoffset == lastexp.offset) - lastexp.offset = -1; - else - lastexp.offset = 0; - } - else if (sym == LESSTHAN) - { - /* context-sensitive, LESSTHAN really means less than here */ - simple2(); - if (leftoffset < lastexp.offset) - lastexp.offset = -1; - else - lastexp.offset = 0; - } - else if (sym == GREATERTHAN) - { - /* context-sensitive, GREATERTHAN really means greater than here */ - simple2(); - if (leftoffset > lastexp.offset) - lastexp.offset = -1; - else - lastexp.offset = 0; - } -} - -/* get symbol and 2nd simple expression, check both rel or both abs */ - -PRIVATE void simple2() -{ - unsigned char leftdata; - - leftdata = lastexp.data; - getsym(); - simple(); - if ((leftdata | lastexp.data) & IMPBIT || - (leftdata ^ lastexp.data) & (RELBIT | SEGM)) - showrelbad(); - else - lastexp.data = (leftdata & lastexp.data) & ~(RELBIT | SEGM); -} - -/* - simple() parses simple expression = [+-] term {op term}, - where op is +, -, or \ (OR). -*/ - -PRIVATE void simple() -{ - offset_t leftoffset; - unsigned char leftdata; - - if (sym == ADDOP || sym == SUBOP) - lastexp.data = lastexp.offset = 0; - else - term(); - while (TRUE) - { - leftoffset = lastexp.offset; - leftdata = lastexp.data; - if (sym == ADDOP) - { - getsym(); - term(); - if (leftdata & lastexp.data & RELBIT) - showrelbad(); /* rel + rel no good */ - else - lastexp.data |= leftdata; - lastexp.offset += leftoffset; - } - else if (sym == SUBOP) - { - getsym(); - term(); - /* check not abs - rel or rel - rel with mismatch */ - if (lastexp.data & RELBIT && - (!(leftdata & RELBIT) || - (leftdata | lastexp.data) & IMPBIT || - (leftdata ^ lastexp.data) & (RELBIT | SEGM))) - showrelbad(); - else - lastexp.data = ((leftdata | lastexp.data) & ~(RELBIT | SEGM)) - | ((leftdata ^ lastexp.data) & (RELBIT | SEGM)); - lastexp.offset = leftoffset - lastexp.offset; - } - else if (sym == OROP) - { - getsym(); - term(); - lastexp.data |= leftdata; - chkabs(); /* both must be absolute */ - lastexp.offset |= leftoffset; - } - else - return; - } -} - -/* term() parses term = factor {op factor}, where op is *, /, &, <<, or >>. */ - -PRIVATE void term() -{ - offset_t leftoffset; - - factor(); - while (TRUE) - { - leftoffset = lastexp.offset; - if (sym == STAR) - { - /* context-sensitive, STAR means multiplication here */ - factor2(); - lastexp.offset *= leftoffset; - } - else if (sym == SLASH) - { - /* context-sensitive, SLASH means division here */ - factor2(); - lastexp.offset = leftoffset / lastexp.offset; - } - else if (sym == ANDOP) - { - factor2(); - lastexp.offset &= leftoffset; - } - else if (sym == SLOP) - { - factor2(); - lastexp.offset = leftoffset << lastexp.offset; - } - else if (sym == SROP) - { - factor2(); - lastexp.offset = leftoffset >> lastexp.offset; - } - else - return; - } -} - -/* get symbol and 2nd or later factor, check both abs */ - -PRIVATE void factor2() -{ - unsigned char leftdata; - - leftdata = lastexp.data; - getsym(); - factor(); - lastexp.data |= leftdata; - chkabs(); -} - -/* - factor() parses factor = number | identifier | * | (expression) | ! factor, - ! is complementation. Returns value in lastexp.offset, possible flags - IMPBIT, FORBIT, RELBIT and UNDBIT in lastexp.data, and segment in SEGM - part of lastexp.data, and lastexp.sym at imported symbol if IMPBIT. - If the factor is an identifier, LOOKUP is used to get its value - (so the ident is installed in the symbol table if necessary, with - default flags inidata). If the identifier is not a label, - (could be imported, or later in the program), its FORBIT is set. - The expression FORBIT, IMPBIT, RELBIT, UNDBIT and SEGM are then - taken from the identifier. -*/ - -PUBLIC void factor() -{ - switch (sym) - { - case SLASH: - /* context-sensitive, SLASH means a hex number here */ - context_hexconst(); - case INTCONST: - lastexp.data = 0; /* absolute & not forward or undefined */ - lastexp.offset = number; - getsym(); - return; - case IDENT: - { - register struct sym_s *symptr; - - symptr = gsymptr; - if (symptr->type & (MNREGBIT | MACBIT)) - experror(symptr->type & MACBIT ? MACUID : - symptr->data & REGBIT ? REGUID : MNUID); - else - { - if (!(symptr->type & (LABIT | VARBIT))) - { - symptr->data |= FORBIT; - lastexp.sym = symptr; - } - if (pass == 0) - { - lastexp.data = symptr->data & - (FORBIT | RELBIT | UNDBIT | SEGM); - /* possible flags for pass 1 */ - lastexp.offset = symptr->value_reg_or_op.value; - } - else - { - if ((lastexp.data = symptr->data) & IMPBIT) - lastexp.offset = 0; /* value != 0 for commons */ - /* OK even if UNDBIT */ - else - { - lastexp.offset = symptr->value_reg_or_op.value; - if (lastexp.data & UNDBIT) - experror(UNBLAB); - } - } - } - getsym(); - return; - } - case LBRACKET: - if (!asld_compatible) - break; /* error, LPAREN is the grouping symbol */ - getsym(); - expres(); - if (sym != RBRACKET) - error(RBEXP); - else - getsym(); - return; - case LPAREN: - if (asld_compatible) - break; /* error, LBRACKET is the grouping symbol */ - getsym(); - expres(); - if (sym != RPAREN) - error(RPEXP); - else - getsym(); - return; - case NOTOP: - getsym(); - factor(); - chkabs(); - lastexp.offset = ~lastexp.offset; - return; - case STAR: - /* context-sensitive, STAR means location counter here */ - lastexp.offset = lc; - if ((lastexp.data = lcdata) & UNDBIT && pass != 0) - experror(UNBLAB); - getsym(); - return; - } - experror(FACEXP); -} - -/* - string compare for IFC/ELSEIFC - expects (<string1>,<string2>) - returns logical value in lastexp -*/ - -PUBLIC void scompare() -{ - /* prepare flags for OK, lastexp.offset for error */ - lastexp.data = lastexp.offset = 0; - if (sym != LPAREN) - experror(LPEXP); - else - { - register char *string1; - register char *string2; - - for (string2 = string1 = lineptr; *string2 != ')'; ++string2) - if (*string2 == 0 || *string2 == ')') - { - symname = string2; - experror(COMEXP); - return; - } - while (*string1++ == *string2++) - ; - if (string2[-1] == ')') - { - if (string1[-1] == ',') - lastexp.offset = TRUE; /* else leave FALSE */ - } - else /* FALSE, keep reading to verify syntax */ - for (; *string2 != ')'; ++string2) - if (*string2 == 0 || *string2 == ',') - { - symname = string2; - experror(RPEXP); - } - } -} diff --git a/bin86-0.3/as/file.h b/bin86-0.3/as/file.h deleted file mode 100644 index 180b19b..0000000 --- a/bin86-0.3/as/file.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bin86/as/file.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* file.h - global variables involving files for assembler */ - -EXTERN fd_t binfil; /* binary output file (0 = memory) */ -EXTERN char *filnamptr; /* file name pointer */ -EXTERN fd_t infil0; /* initial input file */ -EXTERN fd_t infil; /* current input file (stacked, 0 = memory) */ -EXTERN unsigned char infiln; /* innum when file was opened */ -EXTERN unsigned char innum; /* counter for calls to opem */ -EXTERN fd_t lstfil; /* list output file (0 = standard) */ -EXTERN fd_t objfil; /* object output file */ -EXTERN fd_t symfil; /* symbol table output file */ -EXTERN char *truefilename; /* in case actual source name is a tmpname */ diff --git a/bin86-0.3/as/flag.h b/bin86-0.3/as/flag.h deleted file mode 100644 index 21859cf..0000000 --- a/bin86-0.3/as/flag.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * bin86/as/flag.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* flag.h - global structured-flag variables for assembler */ - -EXTERN struct flags_s list; /* listing on/off */ -EXTERN struct flags_s maclist; /* list macros on/off */ -EXTERN struct flags_s warn; /* warnings on/off */ diff --git a/bin86-0.3/as/genbin.c b/bin86-0.3/as/genbin.c deleted file mode 100644 index c215249..0000000 --- a/bin86-0.3/as/genbin.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * bin86/as/genbin.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* genbin.c - binary code generation routines for assembler */ - -#include "const.h" -#include "type.h" -#include "address.h" -#include "file.h" -#include "globvar.h" - -PRIVATE char *asmbeg; /* beginning of assembler code */ - /* for overwrite check */ - /* bss-init to zero = NULL and not changed */ -PRIVATE offset_t binfbuf; /* binary code buffer for file (counter) */ -PRIVATE offset_t binmax; /* maximum value of binmbuf for pass 1 */ -PRIVATE offset_t binmin; /* minimum value of binmbuf for pass 1 */ - -FORWARD void putbinoffset P((offset_t offset, count_t size)); - -/* write header to binary file */ - -PUBLIC void binheader() -{ - if ((innum = binfil) != 0x0) - { - writec(0x0); /* binary header byte */ -#ifdef LONG_BINHEADER - writeoff(binmax - binmin); /* program length */ - writeoff(binfbuf = binmin); /* program start */ -#else - writew((unsigned) (binmax - binmin)); /* program length */ - writew((unsigned) (binfbuf = binmin)); /* program start */ -#endif - } -} - -/* write trailer to binary file */ - -PUBLIC void bintrailer() -{ - if ((innum = binfil) != 0x0) - { - writec(0xFF); /* binary trailer byte */ - writew(0x0); /* further trailer bytes */ -#ifdef LONG_BINHEADER - writeoff(pedata & UNDBIT ? binmin : progent); /* entry point */ -#else - writew(pedata & UNDBIT ? (unsigned) binmin : (unsigned) progent); -#endif - } -} - -/* generate binary code for current line */ - -PUBLIC void genbin() -{ - struct address_s *adrptr; - char *bufptr; - unsigned char remaining; - - if (binaryg && mcount != 0x0) - { - if (popflags) - { - if (fcflag) - { - bufptr = databuf.fcbuf; - remaining = mcount; - do - putbin(*bufptr++); - while (--remaining != 0x0); - } - if (fdflag) - { - adrptr = databuf.fdbuf; - remaining = mcount; - do - { - putbinoffset(adrptr->offset, 0x2); - ++adrptr; - } - while ((remaining -= 0x2) != 0x0); - } -#if SIZEOF_OFFSET_T > 0x2 - if (fqflag) - { - adrptr = databuf.fqbuf; - remaining = mcount; - do - { - putbinoffset(adrptr->offset, 0x4); - ++adrptr; - } - while ((remaining -= 0x4) != 0x0); - } -#endif - } - else - { - remaining = mcount - 0x1; /* count opcode immediately */ -#ifdef I80386 - if (aprefix != 0x0) - { - putbin(aprefix); - --remaining; - } - if (oprefix != 0x0) - { - putbin(oprefix); - --remaining; - } - if (sprefix != 0x0) - { - putbin(sprefix); - --remaining; - } -#endif - if (page != 0x0) - { - putbin(page); - --remaining; - } - putbin(opcode); - if (remaining != 0x0) - { - if (postb != 0x0) - { - putbin(postb); - --remaining; - } -#ifdef I80386 - if (sib != NO_SIB) - { - putbin(sib); - --remaining; - } -#endif - if (remaining != 0x0) - putbinoffset(lastexp.offset, remaining); - } -#ifdef I80386 - if (immcount != 0x0) - putbinoffset(immadr.offset, immcount); -#endif - } - /* else no code for this instruction, or already generated */ - } -} - -/* initialise private variables */ - -PUBLIC void initbin() -{ - binmin = -1; /* greater than anything */ -} - -/* write char to binary file or directly to memory */ - -PUBLIC void putbin(c) -opcode_pt c; -{ - if (binfil != 0x0) - { - if (!binaryc) /* pass 1, just record limits */ - { - if (binmbuf < binmin) - binmin = binmbuf; - if (++binmbuf > binmax) - binmax = binmbuf; - } - else - { - if (binfbuf > binmbuf) - error(BWRAP); /* file buffer ahead of memory buffer */ - else - { - innum = binfil; - while (binfbuf < binmbuf) - { - writec(0x0);/* pad with nulls if file buffer behind */ - ++binfbuf; - } - writec(c); - binmbuf = ++binfbuf; - } - } - } - else if (binaryc && !(lcdata & UNDBIT)) - /* memory output, and enabled */ - { - register char *bufptr; - - if ((bufptr = (char *) binmbuf) >= asmbeg && bufptr < heapptr) - error(OWRITE); - else - *bufptr = c; - ++binmbuf; - } -} - -/* write sized offset to binary file or directly to memory */ - -PRIVATE void putbinoffset(offset, size) -offset_t offset; -count_t size; -{ - char buf[sizeof offset]; - -#if SIZEOF_OFFSET_T > 0x2 - u4cn(buf, offset, size); -#else - u2cn(buf, offset, size); -#endif - putbin(buf[0]); - if (size > 0x1) - putbin(buf[1]); - if (size > 0x2) - { - putbin(buf[2]); - putbin(buf[3]); - } -} diff --git a/bin86-0.3/as/genlist.c b/bin86-0.3/as/genlist.c deleted file mode 100644 index 6286d4b..0000000 --- a/bin86-0.3/as/genlist.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * bin86/as/genlist.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* genlist.c - generate listing and error reports for assembler */ - -#include "const.h" -#include "type.h" -#include "address.h" -#include "flag.h" -#include "file.h" -#include "globvar.h" -#include "macro.h" -#include "scan.h" -#include "source.h" - -#define CODE_LIST_LENGTH (sizeof (struct code_listing_s) - 1) - /* length of formatted code listing */ -#define MAXERR 6 /* maximum errors listed per line */ - -struct error_s /* to record error info */ -{ - unsigned char errnum; - unsigned char position; -}; - -/* code listing format */ - -struct code_listing_s -{ - union linum_macro_u - { - char linum[LINUM_LEN]; - struct - { - char pad[1]; - char mark[1]; - char level[1]; - } - macro; - } - linum_or_macro; - char padlinum[1]; - char lc[4]; - char padlc[1]; -#ifdef I80386 - char lprefix[2]; - char aprefix[2]; - char oprefix[2]; - char sprefix[2]; -#endif - char page[2]; - char opcode[2]; - char postb[2]; -#ifdef I80386 - char sib[2]; -#endif - char padopcode[1]; -#if SIZEOF_OFFSET_T > 2 - char displ4[2]; - char displ3[2]; -#endif - char displ2[2]; - char displ1[2]; - char reldispl[1]; - char paddispl[1]; -#ifdef I80386 - char imm4[2]; - char imm3[2]; - char imm2[2]; - char imm1[2]; - char relimm[1]; - char padimm[1]; -#endif - char nullterm; -}; - -PRIVATE struct error_s errbuf[MAXERR]; /* error buffer */ -PRIVATE unsigned char errcount; /* # errors in line */ -PRIVATE bool_t erroverflow; /* set if too many errors on line */ - -FORWARD char *build_1hex_number P((unsigned num, char *where)); -FORWARD void list1 P((fd_t fd)); -FORWARD void listcode P((void)); -FORWARD void listerrors P((void)); -FORWARD void paderrorline P((unsigned nspaces)); - -/* format 1 byte number as 2 hex digits, return ptr to end */ - -PRIVATE char *build_1hex_number(num, where) -unsigned num; -register char *where; -{ - static char hexdigits[] = "0123456789ABCDEF"; - - where[0] = hexdigits[(num % 256) / 16]; - where[1] = hexdigits[num % 16]; - return where + 2; -} - -/* format 2 byte number as 4 hex digits, return ptr to end */ - -PUBLIC char *build_2hex_number(num, where) -unsigned num; -char *where; -{ - return build_1hex_number(num, build_1hex_number(num / 256, where)); -} - -/* format 2 byte number as decimal with given width (pad with leading '0's) */ -/* return ptr to end */ - -PUBLIC char *build_number(num, width, where) -unsigned num; -unsigned width; -register char *where; -{ - static unsigned powers_of_10[] = {1, 10, 100, 1000, 10000,}; - unsigned char digit; - unsigned char power; - register unsigned power_of_10; - - power = 5; /* actually 1 more than power */ - do - { - for (digit = '0', power_of_10 = (powers_of_10 - 1)[power]; - num >= power_of_10; num -= power_of_10) - ++digit; - if (power <= width) - *where++ = digit; - } - while (--power != 0); - return where; -} - -/* record number and position of error (or error buffer overflow) */ - -PUBLIC void error(errnum) -error_pt errnum; -{ - register struct error_s *errptr; - register struct error_s *errptrlow; - unsigned char position; - - if (errnum < MINWARN || warn.current) - { - if (errcount >= MAXERR) - erroverflow = TRUE; - else - { - position = symname - linebuf; - for (errptr = errbuf + errcount; - errptr > errbuf && errptr->position > position; - errptr = errptrlow) - { - errptrlow = errptr - 1; - errptr->errnum = errptrlow->errnum; - errptr->position = errptrlow->position; - } - errptr->errnum = errnum; - errptr->position = position; - ++errcount; - if (errnum >= MINWARN) - ++totwarn; - else - ++toterr; - } - } -} - -/* list 1 line to list file if any errors or flags permit */ -/* list line to console as well if any errors and list file is not console */ - -PUBLIC void listline() -{ - if (!listpre) - { - if (errcount || list.current && (!macflag || mcount != 0) || - macflag && maclist.current) - list1(lstfil); - if (errcount) - { - if (lstfil != STDOUT) - list1(STDOUT); - errcount = 0; - erroverflow = FALSE; - } - } -} - -/* list 1 line unconditionally */ - -PRIVATE void list1(fd) -fd_t fd; -{ - innum = fd; - listcode(); - write(innum, linebuf, lineptr - linebuf); - writenl(); - if (errcount != 0) - listerrors(); - listpre = TRUE; -} - -/* list object code for 1 line */ - -PRIVATE void listcode() -{ - unsigned char count; - struct code_listing_s *listptr; - int numlength; - char *numptr; - - listptr = (struct code_listing_s *) heapptr; - memset((char *) listptr, ' ', sizeof *listptr); - listptr->nullterm = 0; - if (macflag) - { - listptr->linum_or_macro.macro.mark[0] = '+'; - listptr->linum_or_macro.macro.level[0] = maclevel + ('a' - 1); - } - else - { - numlength = LINUM_LEN; - numptr = listptr->linum_or_macro.linum; - if (infiln != infil0) - { - *numptr++ = infiln - infil0 + ('a' - 1); - numlength = LINUM_LEN - 1; - } - build_number(linum, numlength, numptr); - } - if ((count = mcount) != 0 || popflags & POPLC) - build_2hex_number((u16_t) lc, listptr->lc); - if (popflags & POPLO) - { -#if SIZEOF_OFFSET_T > 2 - if (popflags & POPLONG) - build_2hex_number((u16_t) (lastexp.offset / (offset_t) 0x10000L), - listptr->displ4); -#endif - if (popflags & POPHI) - build_2hex_number((u16_t) lastexp.offset, listptr->displ2); - else - build_1hex_number((u16_t) lastexp.offset, listptr->displ1); - if (lastexp.data & RELBIT) - listptr->reldispl[0] = '>'; - } - else if (count != 0) - { -#ifdef I80386 - if (aprefix != 0) - { - --count; - build_1hex_number(aprefix, listptr->aprefix); - } - if (oprefix != 0) - { - --count; - build_1hex_number(oprefix, listptr->oprefix); - } - if (sprefix != 0) - { - --count; - build_1hex_number(sprefix, listptr->sprefix); - } -#endif - if (page != 0) - { - build_1hex_number(page, listptr->page); - --count; - } - build_1hex_number(opcode, listptr->opcode); - --count; - if (postb != 0) - { - --count; - build_1hex_number(postb, -#ifdef MC6809 - count == 0 ? listptr->displ1 : -#endif - listptr->postb); - } -#ifdef I80386 - if (sib != NO_SIB) - { - --count; - build_1hex_number(sib, listptr->sib); - } -#endif - if (count > 0) - { - build_1hex_number((opcode_pt) lastexp.offset, listptr->displ1); - if (lastexp.data & RELBIT) - listptr->reldispl[0] = '>'; - } - if (count > 1) - build_1hex_number((opcode_pt) lastexp.offset >> 0x8, - listptr->displ2); -#if SIZEOF_OFFSET_T > 2 - if (count > 2) - { - build_1hex_number((opcode_pt) (lastexp.offset >> 0x10), - listptr->displ3); - build_1hex_number((opcode_pt) (lastexp.offset >> 0x18), - listptr->displ4); - } -#endif -#ifdef I80386 - if (immcount > 0) - { - build_1hex_number((opcode_pt) immadr.offset, listptr->imm1); - if (immadr.data & RELBIT) - listptr->relimm[0] = '>'; - } - if (immcount > 1) - build_1hex_number((opcode_pt) immadr.offset >> 0x8, - listptr->imm2); - if (immcount > 2) - { - build_1hex_number((opcode_pt) (immadr.offset >> 0x10), - listptr->imm3); - build_1hex_number((opcode_pt) (immadr.offset >> 0x18), - listptr->imm4); - } -#endif - } - writes((char *) listptr); -} - -/* list errors, assuming some */ - -PRIVATE void listerrors() -{ - unsigned char column; - unsigned char errcol; /* column # in error line */ - unsigned char errcolw; /* working column in error line */ - char *errmsg; - struct error_s *errptr; - char *linep; - unsigned char remaining; - - paderrorline(CODE_LIST_LENGTH - LINUM_LEN); - remaining = errcount; - column = 0; /* column to match with error column */ - errcolw = errcol = CODE_LIST_LENGTH; /* working & col number on err line */ - errptr = errbuf; - linep = linebuf; - do - { - while (column < errptr->position) - { - ++column; - if (*linep++ == '\t') /* next tab (standard tabs only) */ - errcolw = (errcolw + 8) & 0xf8; - else - ++errcolw; - while (errcolw > errcol) - { - writec(' '); - ++errcol; - } - } - if (errcolw < errcol) /* position under error on new line */ - { - writenl(); - paderrorline(errcolw - LINUM_LEN); - } - writec('^'); - writes(errmsg = build_error_message(errptr->errnum, heapptr)); - errcol += strlen(errmsg); - ++errptr; - } - while (--remaining != 0); - writenl(); - if (erroverflow) - { - paderrorline(CODE_LIST_LENGTH - LINUM_LEN); - writesn(build_error_message(FURTHER, heapptr)); - } -} - -/* pad out error line to begin under 1st char of source listing */ - -PRIVATE void paderrorline(nspaces) -unsigned nspaces; -{ - int nstars = LINUM_LEN; - - while (nstars-- != 0) - writec('*'); /* stars under line number */ - while (nspaces-- != 0) - writec(' '); /* spaces out to error position */ -} - -/* write 1 character */ - -PUBLIC void writec(c) -char c; -{ - write(innum, &c, 1); -} - -/* write newline */ - -PUBLIC void writenl() -{ - writes(SOS_EOLSTR); -} - -/* write 1 offset_t, order to suit target */ - -PUBLIC void writeoff(offset) -offset_t offset; -{ - char buf[sizeof offset]; - -#if SIZEOF_OFFSET_T > 2 - u4c4(buf, offset); -#else - u2c2(buf, offset); -#endif - write(innum, buf, sizeof buf); -} - -/* write string */ - -PUBLIC void writes(s) -char *s; -{ - write(innum, s, strlen(s)); -} - -/* write string followed by newline */ - -PUBLIC void writesn(s) -char *s; -{ - writes(s); - writenl(); -} - -/* write 1 word, order to suit target */ - -PUBLIC void writew(word) -unsigned word; -{ - char buf[2]; - - u2c2(buf, (u16_t) word); - write(innum, buf, sizeof buf); -} diff --git a/bin86-0.3/as/genobj.c b/bin86-0.3/as/genobj.c deleted file mode 100644 index fc42394..0000000 --- a/bin86-0.3/as/genobj.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * bin86/as/genobj.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* genobj.c - object code generation routines for assembler */ - -#include "const.h" -#include "type.h" -#include "address.h" -#include "file.h" -#include "globvar.h" - -#define OBJBUFSIZE 512 /* size of object code output buffer */ -#define isge2byteoffset(offset) ((offset) >= 0x100) -#define isge4byteoffset(offset) ((offset) >= 0x10000L) - -PRIVATE char hid_absbuf[OBJ_MAX_ABS_LEN]; /* absolute object code buf */ -PRIVATE char *absbuf; /* start */ -PRIVATE char *absbufend; /* last location + 1 */ -PRIVATE char *absbufptr; /* current location */ -PRIVATE struct sym_s **arrext; /* array of external symbol ptrs */ -PRIVATE char hid_objbuf[OBJBUFSIZE]; /* object code buffer */ -PRIVATE unsigned numext; /* number of external symbols */ -PRIVATE char *objbuf; /* start */ -PRIVATE char *objbufend; /* last location + 1 */ -PRIVATE char *objbufptr; /* current location */ -PRIVATE unsigned char relsize; /* current relocation size, 0 init */ - /* local to genobjadr, but here */ - /* because of static re-init bug */ -PRIVATE offset_t rmbcount; /* accumulator for repeated RMB's */ - -FORWARD void flushabs P((void)); -FORWARD void flushrmb P((void)); -FORWARD void genobjadr P((struct address_s *adrptr, int size)); -FORWARD void putobj1 P((opcode_pt c)); -FORWARD void putobj4 P((u32_t offset)); -FORWARD void putobjoffset P((offset_t offset, count_t size)); -FORWARD void putobjword P((unsigned word)); -FORWARD void writeobj P((char *buf, unsigned count)); - -/* accumulate RMB requests into 1 (so + and - requests cancel) */ - -PUBLIC void accumulate_rmb(offset) -offset_t offset; -{ - if (objectc) - { - flushabs(); - rmbcount += offset; - } -} - -/* flush absolute object code buffer to object code buffer if necessary */ - -PRIVATE void flushabs() -{ - if (absbufptr > absbuf) - { - putobj1((absbufptr - absbuf) | OBJ_ABS); - { - register char *bufptr; - - bufptr = absbuf; - do - putobj1(*bufptr); - while (++bufptr < absbufptr); - absbufptr = absbuf; - } - } -} - -/* flush object code buffer if necessary */ - -PUBLIC void flushobj() -{ - int ntowrite; - - if ((ntowrite = objbufptr - objbuf) > 0) - { - if (write(objfil, objbuf, ntowrite) != ntowrite) - { - error(OBJOUT); - listline(); - finishup(); - } - objbufptr = objbuf; - } -} - -/* flush RMB count if necessary */ - -PRIVATE void flushrmb() -{ - count_t size; - - if (rmbcount != 0) - { -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(rmbcount)) - { - putobj1(OBJ_SKIP_4); - size = 4; - } - else -#endif - if (isge2byteoffset(rmbcount)) - { - putobj1(OBJ_SKIP_2); - size = 2; - } - else - { - putobj1(OBJ_SKIP_1); - size = 1; - } - putobjoffset(rmbcount, size); - rmbcount = 0; - } -} - -/* generate object code for current line */ - -/* - any address parameter is (regrettably) in lastexp - any immediate parameter is (corectly) in immadr -*/ - -PUBLIC void genobj() -{ - struct address_s *adrptr; - char *bufptr; - unsigned char remaining; - - if (objectc && mcount != 0) - { - if (popflags) - { - if (fcflag) - { - bufptr = databuf.fcbuf; - remaining = mcount; - do - putabs(*bufptr++); - while (--remaining != 0); - } - if (fdflag) - { - adrptr = databuf.fdbuf; - remaining = mcount; - do - genobjadr(adrptr++, 2); - while ((remaining -= 2) != 0); - } -#if SIZEOF_OFFSET_T > 2 - if (fqflag) - { - adrptr = databuf.fqbuf; - remaining = mcount; - do - genobjadr(adrptr++, 4); - while ((remaining -= 4) != 0); - } -#endif - } - else - { - remaining = mcount - 1; /* count opcode immediately */ -#ifdef I80386 - if (aprefix != 0) - { - putabs(aprefix); - --remaining; - } - if (oprefix != 0) - { - putabs(oprefix); - --remaining; - } - if (sprefix != 0) - { - putabs(sprefix); - --remaining; - } -#endif - if (page != 0) - { - putabs(page); - --remaining; - } - putabs(opcode); - if (remaining != 0) - { - if (postb != 0) - { - putabs(postb); - --remaining; - } -#ifdef I80386 - if (sib != NO_SIB) - { - putabs(sib); - --remaining; - } -#endif - if (remaining != 0) - genobjadr(&lastexp, remaining); - } - } -#ifdef I80386 - if (immcount != 0) - genobjadr(&immadr, immcount); -#endif - } -} - -/* generate object code for current address */ - -PRIVATE void genobjadr(adrptr, size) -struct address_s *adrptr; -smallcount_t size; -{ - unsigned char byte; - unsigned symnum; - - if (!(adrptr->data & RELBIT)) - { - /* absolute address */ - - char buf[sizeof(offset_t)]; - -#if SIZEOF_OFFSET_T > 2 - u4cn(buf, adrptr->offset, size); -#else - u2cn(buf, adrptr->offset, size); -#endif - putabs(buf[0]); - if (size > 1) - putabs(buf[1]); - if (size > 2) - { - putabs(buf[2]); - putabs(buf[3]); - } - } - else - { - /* relocatable address */ - if (size != relsize) - /* set reloc size index |00|0000xx| */ - putobj((relsize = size) == 4 ? 0x03 : relsize); - if (!(adrptr->data & IMPBIT)) - { - /* offset relocation (known offset) */ - putobj((adrptr->data & SEGM) | OBJ_OFFSET_REL | pcrflag); - putobjoffset(adrptr->offset, size); - } - else - { - /* symbol relocation (imported symbol + offset) */ - { - register struct sym_s **copyptr; - - for (copyptr = arrext, symnum = 0; - symnum < numext && *copyptr++ != adrptr->sym; ++symnum) - ; - } - byte = OBJ_SYMBOL_REL; - if (isge2byteoffset(symnum)) - byte = OBJ_SYMBOL_REL | OBJ_S_MASK; -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(adrptr->offset)) - { - byte |= 0x03; /* 4 byte offset */ - size = 4; - } - else -#endif - if (isge2byteoffset(adrptr->offset)) - { - byte |= 0x02; /* 2 byte offset */ - size = 2; - } - else if (adrptr->offset != 0) - { - byte |= 0x01; /* 1 byte offset */ - size = 1; - } - else - size = 0; - putobj(byte | pcrflag); - if (isge2byteoffset(symnum)) - putobjword(symnum); - else - putobj1(symnum); - if (adrptr->offset != 0) - putobjoffset(adrptr->offset, size); - } - } -} - -/* initialise private variables */ - -PUBLIC void initobj() -{ - absbufend = (absbufptr = absbuf = hid_absbuf) + sizeof hid_absbuf; - objbufend = (objbufptr = objbuf = hid_objbuf) + sizeof hid_objbuf; -} - -/* - write header to object file - also build array of imported/exported symbols -*/ - -PUBLIC void objheader() -{ - static char module_header[] = - { -#ifdef I80386 - 0xA3, 0x86, - 1, 0, - (char) (0xA3 + 0x86 + 1 + 0), -#endif -#ifdef MC6809 - 'S', '1', /* 2 byte magic number */ - 0, 1, /* 2 byte number of modules in file */ - 'S' + '1' + 0 + 1, /* 1 byte checksum */ -#endif - }; - static char seg_max_sizes[] = - { - 0x55, /* all segments have maximum size 2^16 */ - 0x55, /* this is encoded by 0b01 4 times per byte */ - 0x55, /* other codes are 0b00 = max size 2^8 */ - 0x55, /* 0b10 = max size 2^24, 0b11 = max 2^32 */ - }; - unsigned char byte; - register struct sym_s **copyptr; - struct sym_s **copytop; - struct sym_s **hashptr; - struct lc_s *lcp; - char module_name[FILNAMLEN + 1]; - char *nameptr; - unsigned offset; - unsigned segsizebytes; - unsigned size; - unsigned char sizebits; - unsigned strsiz; /* size of object string table */ - unsigned symosiz; /* size of object symbol table */ - register struct sym_s *symptr; - u32_t textlength; - - if ((objectc = objectg) == 0) - return; - writeobj(module_header, sizeof module_header); - - /* calculate number of imported/exported symbols */ - /* and lengths of symbol and string tables */ - /* build array of imported/exported symbols */ - - symosiz = 0; - if (truefilename == NULL) - truefilename = filnamptr; - nameptr = strrchr(truefilename, DIRCHAR); - strcpy(module_name, nameptr != NULL ? nameptr + 1 : truefilename); - if ((nameptr = strrchr(module_name, '.')) != NULL) - *nameptr = 0; - strsiz = strlen(module_name) + 1; - align(heapptr); - for (hashptr = spt, arrext = copyptr = (struct sym_s **) heapptr; - hashptr < spt_top;) - if ((symptr = *hashptr++) != NULL) - do - { - if ((symptr->type & EXPBIT || symptr->data & IMPBIT) || - !globals_only_in_obj && symptr->name[0] != '.' && - !(symptr->type & (MNREGBIT | MACBIT | VARBIT))) - { - if (copyptr >= (struct sym_s **) heapend) - { - heapptr = (char *) copyptr; - fatalerror(OBJSYMOV); - } - *copyptr++ = symptr; - strsiz += symptr->length + 1; -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(symptr->value_reg_or_op.value)) - size = 4 + 4; - /* 4 is size of offset into string table and flags */ - /* 2nd 4 is for 4 byte offset */ - else -#endif - if (isge2byteoffset(symptr->value_reg_or_op.value)) - size = 4 + 2; - else if (symptr->value_reg_or_op.value != 0) - size = 4 + 1; - else - size = 4; - symosiz += size; - ++numext; - } - } - while ((symptr = symptr->next) != NULL); - heapptr = (char *) (copytop = copyptr); - - /* calculate length of text, and number of seg size bytes in header */ - - textlength = segsizebytes = 0; - lcp = lctab; - do - if (lcp->lc != 0) - { - textlength += lcp->lc; /* assuming text starts at 0 */ -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(lcp->lc)) - segsizebytes += 4; - else -#endif - segsizebytes += 2; /* use 2 byte size if possible */ - } - while (++lcp < lctabtop); - -/* - offset to text = length of header since only 1 module - header consists of: - module header sizeof module_header - offset to start of text 4 - length of text 4 - length of string area 2 - class 1 - revision 1 - seg max sizes sizeof seg_max_sizes - seg size descriptors 4 - seg sizes segsizebytes - symbol count 2 - symbol offsets and types symosiz - strings strsiz -*/ - - /* offset to start of text */ - - putobj4((u32_t) (sizeof module_header + 4 + 4 + 2 + 1 + 1 + - sizeof seg_max_sizes + 4 + segsizebytes + 2 + - symosiz) + strsiz); - - /* length of text */ - - putobj4((u32_t) textlength); - - /* length of string area */ - - putobjword(strsiz); - - /* class and revision */ - - putobj1(0); - putobj1(0); - - /* segment max sizes (constant) */ - - writeobj(seg_max_sizes, sizeof seg_max_sizes); - - /* segment size descriptors */ - /* produce only 0 and 2 byte sizes */ - - lcp = lctabtop; - byte = 0; - sizebits = OBJ_SEGSZ_TWO << 6; - do - { - --lcp; - if (lcp->lc != 0) - { - byte |= sizebits; -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(lcp->lc)) - byte |= sizebits >> 1; /* XXX - convert size 2 to size 4 */ -#endif - } - if ((sizebits >>= 2) == 0) - { - putobj1(byte); - sizebits = OBJ_SEGSZ_TWO << 6; - } - } - while (lcp > lctab); - - /* segment sizes */ - - do /* lcp starts at lctab */ - if (lcp->lc != 0) - { -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(lcp->lc)) - putobj4(lcp->lc); - else -#endif - putobjword((unsigned) lcp->lc); - } - while (++lcp < lctabtop); - - /* symbol count */ - - putobjword(numext); - - /* symbol offsets and types */ - - offset = strlen(module_name) + 1; /* 1st symbol begins after name */ - for (copyptr = arrext; copyptr < copytop;) - { - putobjword(offset); - symptr = *copyptr++; - byte = symptr->type & OBJ_N_MASK; -#if SIZEOF_OFFSET_T > 2 - if (isge4byteoffset(symptr->value_reg_or_op.value)) - { - byte |= OBJ_SZ_FOUR; - size = 4; - } - else -#endif - if (isge2byteoffset(symptr->value_reg_or_op.value)) - { - byte |= OBJ_SZ_TWO; - size = 2; - } - else if (symptr->value_reg_or_op.value != 0) - { - byte |= OBJ_SZ_ONE; - size = 1; - } - else - size = 0; - if ((symptr->type & (COMMBIT | REDBIT)) == (COMMBIT | REDBIT)) - { - byte |= OBJ_SA_MASK; - symptr->data &= ~OBJ_I_MASK; - } - putobjword((byte << 0x8) | - (symptr->type & OBJ_E_MASK) | /* |E|0000000| */ - ((symptr->data & (OBJ_I_MASK | OBJ_A_MASK | OBJ_SEGM_MASK)) ^ - /* |0|I|0|A|SEGM| */ - RELBIT)); /* RELBIT by negative logic */ - if ((symptr->type & (COMMBIT | REDBIT)) == (COMMBIT | REDBIT)) - symptr->data |= OBJ_I_MASK; - if (size != 0) - putobjoffset(symptr->value_reg_or_op.value, size); - offset += symptr->length + 1; - } - - /* strings */ - - writeobj(module_name, strlen(module_name)); - putobj1(0); - for (copyptr = arrext; copyptr < copytop;) - { - symptr = *copyptr++; - writeobj(symptr->name, symptr->length); - putobj1(0); - } - putobj1(OBJ_SET_SEG | 0); /* default segment 0, |0010|SEGM| */ -} - -/* write trailer to object file */ - -PUBLIC void objtrailer() -{ - if (objectc) - { - putobj(0); /* end of object file */ - flushobj(); - } -} - -/* write char to absolute object code buffer, flush if necessary */ - -PUBLIC void putabs(c) -opcode_pt c; -{ - if (objectc) - { - if (rmbcount != 0) - flushrmb(); - if (absbufptr >= absbufend) - flushabs(); - *absbufptr++ = c; - } -} - -/* write char to object code buffer, flush if necessary */ - -PUBLIC void putobj(c) -opcode_pt c; -{ - if (objectc) - { - flushabs(); - flushrmb(); - putobj1(c); - } -} - -/* write char to object code buffer assuming nothing in absolute & rmb bufs */ - -PRIVATE void putobj1(c) -opcode_pt c; -{ - if (objbufptr >= objbufend) - flushobj(); - *objbufptr++ = c; -} - -/* write 32 bit offset to object code buffer assuming ... */ - -PRIVATE void putobj4(offset) -u32_t offset; -{ - char buf[sizeof offset]; - - u4c4(buf, offset); - writeobj(buf, sizeof buf); -} - -/* write sized offset to object code buffer assuming ... */ - -PRIVATE void putobjoffset(offset, size) -offset_t offset; -count_t size; -{ - char buf[sizeof offset]; - -#if SIZEOF_OFFSET_T > 2 - u4cn(buf, offset, size); -#else - u2cn(buf, offset, size); -#endif - putobj1(buf[0]); - if (size > 1) - putobj1(buf[1]); - if (size > 2) - { - putobj1(buf[2]); - putobj1(buf[3]); - } -} - -/* write word to object code buffer assuming ... */ - -PRIVATE void putobjword(word) -unsigned word; -{ - char buf[sizeof word]; - - u2c2(buf, word); - putobj1(buf[0]); - putobj1(buf[1]); -} - -/* write several bytes to object code buffer assuming ... */ - -PRIVATE void writeobj(buf, count) -char *buf; -unsigned count; -{ - do - putobj1(*buf++); - while (--count); -} diff --git a/bin86-0.3/as/gensym.c b/bin86-0.3/as/gensym.c deleted file mode 100644 index e06d3ce..0000000 --- a/bin86-0.3/as/gensym.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * bin86/as/gensym.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* gensym.c - generate symbol table for assembler */ - -#include "const.h" -#include "type.h" -#include "flag.h" -#include "file.h" -#include "globvar.h" - -FORWARD int printsym P((register struct sym_s *symptr, unsigned column)); -FORWARD void sort P((struct sym_s **array, struct sym_s **top, - bool_pt nameflag)); - -/* sort labels in symbol table on name and value */ -/* if listing, write human-readable table to list file */ -/* if symbol file, write machine-readable tables to it */ -/* pointers become relative to start of file */ - -PUBLIC void gensym() -{ - unsigned column; - struct sym_s **copyptr; - struct sym_s **copytop; - register struct sym_s **hashptr; - unsigned label_count; /* number of labels */ - unsigned labels_length; /* length of all label strings */ - unsigned label_stringptr; /* offset of label str from start of file */ - register struct sym_s *symptr; - struct sym_s **symlptr; /* start of symbol output list */ - - labels_length = label_count = 0; - - /* make copy of all relavant symbol ptrs on heap */ - /* original ptrs can now be modified, but need to be an array for sort */ - - align(heapptr); - for (hashptr = spt, symlptr = copyptr = (struct sym_s **) heapptr; - hashptr < spt_top;) - if ((symptr = *hashptr++) != NULL) - do - if (!(symptr->type & (MACBIT | MNREGBIT | VARBIT))) - { - if (copyptr >= (struct sym_s **) heapend) - { - heapptr = (char *) copyptr; - error(SYMOUTOV); /* avoid recursive fatalerror */ - listline(); /* the main job is OK if here */ - goto sort_symbols; - } - *copyptr++ = symptr; - ++label_count; - labels_length += symptr->length + 3; /* 3 for type, value */ - } - while ((symptr = symptr->next) != NULL); - -sort_symbols: - sort(symlptr, copyptr, TRUE); /* sort on name */ - heapptr = (char *) (copytop = copyptr); - if (list.global) - { - innum = lstfil; - writenl(); - writesn("Symbols:"); - for (copyptr = symlptr, column = 0; copyptr < copytop;) - column = printsym(*copyptr++, column); - if (column != 0) - writenl(); - } - if ((innum = symfil) != 0) - { - writew(mapnum); - label_count *= 2; /* now length of ptr table (2 bytes per ptr) */ - label_stringptr = label_count + 6; - /* offset to current string in symbol file */ - /* 6 is length of header */ - labels_length += label_stringptr; - /* offset to ptr table sorted on value */ - writew(labels_length + label_count); - /* total length of symbol file */ - writew(label_count); - for (copyptr = symlptr; copyptr < copytop;) - { - symptr = *copyptr++; - writew((unsigned) - (symptr->next = (struct sym_s *) label_stringptr)); - /* reuse "next" to record string position */ - label_stringptr += symptr->length + 3; - } - for (copyptr = symlptr; copyptr < copytop;) - { - symptr = *copyptr++; - writew((unsigned) symptr->value_reg_or_op.value); - writec(symptr->type); - write(innum, symptr->name, symptr->length - 1); - writec(symptr->name[symptr->length - 1] | 0x80); - } - sort(symlptr, copyptr, FALSE); - /* sort on value */ - for (copyptr = symlptr; copyptr < copytop;) - { - symptr = *copyptr++; - writew((unsigned) symptr->next); /* now has string position */ - } - } -} - -/* print symbol nicely formatted for given column */ - -PRIVATE int printsym(symptr, column) -register struct sym_s *symptr; -unsigned column; -{ - unsigned char length; - register struct sym_listing_s *listptr; - char *outname; - char *symname; - - listptr = (struct sym_listing_s *) heapptr; - memset((char *) listptr, ' ', SYMLIS_LEN); - listptr->nullterm = 0; - if ((length = symptr->length) > SYMLIS_NAMELEN) - { - outname = listptr->name; - outname[length = SYMLIS_NAMELEN] = '+'; - } - else - outname = (listptr->name + SYMLIS_NAMELEN) - length; - symname = symptr->name; - do - *outname++ = *symname++; - while (--length != 0); - listptr->ar[0] = symptr->data & RELBIT ? 'R' : 'A'; - listptr->segm[0] = (symptr->data & SEGM) + '0'; - if (symptr->type & COMMBIT) - listptr->cein[0] = 'C'; - else if (symptr->type & ENTBIT) - listptr->cein[0] = 'N'; - else if (symptr->type & EXPBIT) - listptr->cein[0] = 'E'; - else if (symptr->data & IMPBIT) - listptr->cein[0] = 'I'; -#if SIZEOF_OFFSET_T > 2 - build_2hex_number((unsigned) (symptr->value_reg_or_op.value >> 16), - listptr->value); -#endif - build_2hex_number((unsigned) symptr->value_reg_or_op.value, - listptr->value); - writes((char *) listptr); - if ((column += SYMLIS_LEN) > (80 - SYMLIS_LEN)) - { - writenl(); - column = 0; - } - return column; -} - -/* shell sort symbols */ - -PRIVATE void sort(array, top, nameflag) -struct sym_s **array; -struct sym_s **top; -bool_pt nameflag; -{ - int gap; - int i; - int j; - register struct sym_s **left; - register struct sym_s **right; - int size; - struct sym_s *swap; - - size = top - array; - /* choose gaps according to Knuth V3 p95 */ - for (gap = 1, i = 4; (j = 3 * i + 1) < size; gap = i, i = j) - ; - do - { - for (j = gap; j < size; ++j) - for (i = j - gap; i >= 0; i -= gap) - { - left = &array[i]; - right = &array[i + gap]; - if ((bool_t) nameflag) - { - if (strcmp((*left)->name, (*right)->name) <= 0) - break; - } - else if ((unsigned) (*left)->value_reg_or_op.value <= - (*right)->value_reg_or_op.value) - break; - swap = *left; - *left = *right; - *right = swap; - } - } - while ((gap /= 3) != 0); -} diff --git a/bin86-0.3/as/globvar.h b/bin86-0.3/as/globvar.h deleted file mode 100644 index e560abc..0000000 --- a/bin86-0.3/as/globvar.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * bin86/as/globvar.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* globvar.h - global variables for assembler */ - -/* global control and bookkeeping */ - -EXTERN bool_t binaryc; /* current binary code flag */ -EXTERN bool_t binaryg; /* global binary code flag */ -EXTERN offset_t binmbuf; /* offset in binary code buffer for memory */ - -EXTERN unsigned char dirpag; /* direct page */ - -EXTERN bool_t globals_only_in_obj; /* global symbols only in object file */ - -EXTERN bool_t jumps_long; /* make all jumps long */ - -EXTERN unsigned char mapnum; /* global map number */ - -EXTERN bool_t objectc; /* current object code flag */ -EXTERN bool_t objectg; /* global object code flag */ - -EXTERN bool_t pass; /* pass, FALSE means 0, TRUE means 1 */ - -EXTERN offset_t progent; /* program entry point */ - -EXTERN bool_t symgen; /* generate symbol table flag */ - -EXTERN unsigned toterr; /* total errors */ -EXTERN unsigned totwarn; /* total warnings */ - -/* bookeeping for current line */ - -EXTERN char *linebuf; /* buffer */ - -/* for symbol table routines */ - -EXTERN char *heapend; /* end of free space for symbol list */ -EXTERN char *heapptr; /* next free space in symbol list */ -EXTERN unsigned char inidata; /* init sym entry data governed by "u" flag */ -EXTERN struct sym_s **spt; /* symbol pointer table */ -EXTERN struct sym_s **spt_top; /* top of symbol ptr table */ - -/* for translator */ - -EXTERN struct sym_s *label; /* non-null if valid label starts line */ -EXTERN unsigned char pedata; /* shows how PROGENT bound, flags like LCDATA*/ -EXTERN unsigned char popflags; /* pseudo-op flags */ - -/* for BLOCK stack */ - -EXTERN struct block_s *blockstak; /* stack ptr */ -EXTERN unsigned char blocklevel; /* nesting level */ - -/* for IF stack */ - -EXTERN struct if_s *ifstak; /* stack ptr */ -EXTERN unsigned char iflevel; /* nesting level */ -EXTERN bool_t ifflag; /* set if assembling */ - -/* location counters for various segments */ - -EXTERN offset_t lc; /* location counter */ -EXTERN unsigned char lcdata; /* shows how lc is bound */ - /* FORBIT is set if lc is forward referenced */ - /* RELBIT is is if lc is relocat. (not ASEG) */ -EXTERN offset_t lcjump; /* lc jump between lines */ -#define mcount (((unsigned char *) &lcjump)[LOW_BYTE]) - /* low byte of lcjump */ -EXTERN struct lc_s *lcptr; /* top of current spot in lctab */ -EXTERN struct lc_s *lctab; /* start of lctab */ -EXTERN struct lc_s *lctabtop; /* top of lctab */ - -/* for code generator */ - -EXTERN opsize_t mnsize; /* 1 if forced byte operand size, else 0 */ -EXTERN opcode_t page; -EXTERN opcode_t opcode; -EXTERN opcode_t postb; /* postbyte, 0 if none */ -EXTERN unsigned char pcrflag; /* OBJ_RMASK set if addressing is PC-relative */ - -#ifdef I80386 - -EXTERN opcode_t aprefix; /* address size prefix or 0 */ -EXTERN bool_t asld_compatible; /* asld compatibility flag */ -EXTERN opsize_t defsize; /* current default size */ -EXTERN opsize_t idefsize; /* initial default size */ -EXTERN opcode_t oprefix; /* operand size prefix or 0 */ -EXTERN opcode_t sprefix; /* segment prefix or 0 */ -EXTERN opcode_t sib; /* scale-index-base byte */ - -#endif diff --git a/bin86-0.3/as/keywords.c b/bin86-0.3/as/keywords.c deleted file mode 100644 index 5d0bf84..0000000 --- a/bin86-0.3/as/keywords.c +++ /dev/null @@ -1,733 +0,0 @@ -/* - * bin86/as/keywords.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* keywords.c - keywords for assembler */ - -#include "const.h" -#include "type.h" -#include "opcode.h" - -/* registers */ -/* the register code (internal to assembler) is given in 1 byte */ -/* the "opcode" field is not used */ - -PUBLIC char regs[] = -{ -#ifdef I80386 - 2, 'B', 'P', BPREG, 0, - 2, 'B', 'X', BXREG, 0, - 2, 'D', 'I', DIREG, 0, - 2, 'S', 'I', SIREG, 0, - - 3, 'E', 'A', 'X', EAXREG, 0, - 3, 'E', 'B', 'P', EBPREG, 0, - 3, 'E', 'B', 'X', EBXREG, 0, - 3, 'E', 'C', 'X', ECXREG, 0, - 3, 'E', 'D', 'I', EDIREG, 0, - 3, 'E', 'D', 'X', EDXREG, 0, - 3, 'E', 'S', 'I', ESIREG, 0, - 3, 'E', 'S', 'P', ESPREG, 0, - - 2, 'A', 'X', AXREG, 0, - 2, 'C', 'X', CXREG, 0, - 2, 'D', 'X', DXREG, 0, - 2, 'S', 'P', SPREG, 0, - - 2, 'A', 'H', AHREG, 0, - 2, 'A', 'L', ALREG, 0, - 2, 'B', 'H', BHREG, 0, - 2, 'B', 'L', BLREG, 0, - 2, 'C', 'H', CHREG, 0, - 2, 'C', 'L', CLREG, 0, - 2, 'D', 'H', DHREG, 0, - 2, 'D', 'L', DLREG, 0, - - 2, 'C', 'S', CSREG, 0, - 2, 'D', 'S', DSREG, 0, - 2, 'E', 'S', ESREG, 0, - 2, 'F', 'S', FSREG, 0, - 2, 'G', 'S', GSREG, 0, - 2, 'S', 'S', SSREG, 0, - - 3, 'C', 'R', '0', CR0REG, 0, - 3, 'C', 'R', '2', CR2REG, 0, - 3, 'C', 'R', '3', CR3REG, 0, - 3, 'D', 'R', '0', DR0REG, 0, - 3, 'D', 'R', '1', DR1REG, 0, - 3, 'D', 'R', '2', DR2REG, 0, - 3, 'D', 'R', '3', DR3REG, 0, - 3, 'D', 'R', '6', DR6REG, 0, - 3, 'D', 'R', '7', DR7REG, 0, - 3, 'T', 'R', '3', TR3REG, 0, - 3, 'T', 'R', '4', TR4REG, 0, - 3, 'T', 'R', '5', TR5REG, 0, - 3, 'T', 'R', '6', TR6REG, 0, - 3, 'T', 'R', '7', TR7REG, 0, - - 2, 'S', 'T', ST0REG, 0, -#endif /* I80386 */ - -#ifdef MC6809 - 1, 'A', AREG, 0, - 1, 'B', BREG, 0, - 2, 'C', 'C', CCREG, 0, - 1, 'D', DREG, 0, - 2, 'D', 'P', DPREG, 0, - 2, 'P', 'C', PCREG, 0, - 3, 'P', 'C', 'R', PCREG, 0, - 1, 'S', SREG, 0, - 1, 'U', UREG, 0, - 1, 'X', XREG, 0, - 1, 'Y', YREG, 0, -#endif - 0 /* end of register list */ -}; - -#ifdef I80386 - -/* type sizes */ -/* the "opcode" field gives the type size */ - -PUBLIC char typesizes[] = -{ - 4, 'B', 'Y', 'T', 'E', BYTEOP, 1, - 5, 'D', 'W', 'O', 'R', 'D', DWORDOP, 4, - 5, 'F', 'W', 'O', 'R', 'D', FWORDOP, 6, - 3, 'F', 'A', 'R', FAROP, 0, - 3, 'P', 'T', 'R', PTROP, 0, - 5, 'P', 'W', 'O', 'R', 'D', PWORDOP, 6, - 5, 'Q', 'W', 'O', 'R', 'D', QWORDOP, 8, - 5, 'T', 'B', 'Y', 'T', 'E', TBYTEOP, 10, - 4, 'W', 'O', 'R', 'D', WORDOP, 2, - 0 /* end of typesize list */ -}; - -#endif - -/* ops */ -/* the routine number is given in 1 byte */ -/* the opcode is given in 1 byte (it is not used for pseudo-ops) */ - -PUBLIC char ops[] = -{ - /* pseudo-ops. The "opcode" field is unused and padded with a null byte */ - /* conditionals - must be first */ - 4, 'E', 'L', 'S', 'E', ELSEOP, 0, - 6, 'E', 'L', 'S', 'E', 'I', 'F', ELSEIFOP, 0, - 7, 'E', 'L', 'S', 'E', 'I', 'F', 'C', ELSEIFCOP, 0, - 5, 'E', 'N', 'D', 'I', 'F', ENDIFOP, 0, - 2, 'I', 'F', IFOP, 0, - 3, 'I', 'F', 'C', IFCOP, 0, - - /* unconditionals */ - 6, '.', 'A', 'L', 'I', 'G', 'N', ALIGNOP, 0, - 6, '.', 'A', 'S', 'C', 'I', 'I', FCCOP, 0, - 5, '.', 'B', 'L', 'K', 'B', RMBOP, 0, - 5, '.', 'B', 'L', 'K', 'W', BLKWOP, 0, - 5, 'B', 'L', 'O', 'C', 'K', BLOCKOP, 0, - 4, '.', 'B', 'S', 'S', BSSOP, 0, - 5, '.', 'B', 'Y', 'T', 'E', FCBOP, 0, - 4, 'C', 'O', 'M', 'M', COMMOP, 0, - 5, '.', 'C', 'O', 'M', 'M', COMMOP1, 0, - 5, '.', 'D', 'A', 'T', 'A', DATAOP, 0, - 6, '.', 'D', 'A', 'T', 'A', '1', FCBOP, 0, - 6, '.', 'D', 'A', 'T', 'A', '2', FDBOP, 0, - 6, '.', 'D', 'A', 'T', 'A', '4', FQBOP, 0, - 2, 'D', 'B', FCBOP, 0, - 2, 'D', 'D', FQBOP, 0, - 7, '.', 'D', 'E', 'F', 'I', 'N', 'E', EXPORTOP, 0, - 2, 'D', 'W', FDBOP, 0, - 3, 'E', 'N', 'D', PROCEOFOP, 0, - 4, 'E', 'N', 'D', 'B', ENDBOP, 0, - 5, 'E', 'N', 'T', 'E', 'R', ENTEROP, 0, - 5, 'E', 'N', 'T', 'R', 'Y', ENTRYOP, 0, - 3, 'E', 'Q', 'U', EQUOP, 0, - 5, '.', 'E', 'V', 'E', 'N', EVENOP, 0, - 6, 'E', 'X', 'P', 'O', 'R', 'T', EXPORTOP, 0, - 6, 'E', 'X', 'T', 'E', 'R', 'N', IMPORTOP, 0, - 7, '.', 'E', 'X', 'T', 'E', 'R', 'N', IMPORTOP, 0, - 5, 'E', 'X', 'T', 'R', 'N', IMPORTOP, 0, - 4, 'F', 'A', 'I', 'L', FAILOP, 0, - 5, '.', 'F', 'A', 'I', 'L', FAILOP, 0, - 3, 'F', 'C', 'B', FCBOP, 0, - 3, 'F', 'C', 'C', FCCOP, 0, - 3, 'F', 'D', 'B', FDBOP, 0, - 3, 'G', 'E', 'T', GETOP, 0, - 6, '.', 'G', 'L', 'O', 'B', 'L', GLOBLOP, 0, - 5, 'I', 'D', 'E', 'N', 'T', IDENTOP, 0, - 6, 'I', 'M', 'P', 'O', 'R', 'T', IMPORTOP, 0, - 7, 'I', 'N', 'C', 'L', 'U', 'D', 'E', GETOP, 0, - 5, 'L', 'C', 'O', 'M', 'M', LCOMMOP, 0, - 6, '.', 'L', 'C', 'O', 'M', 'M', LCOMMOP1, 0, - 5, '.', 'L', 'I', 'S', 'T', LISTOP, 0, - 3, 'L', 'O', 'C', LOCOP, 0, - 5, '.', 'L', 'O', 'N', 'G', FQBOP, 0, - 8, '.', 'M', 'A', 'C', 'L', 'I', 'S', 'T', MACLISTOP, 0, - 5, 'M', 'A', 'C', 'R', 'O', MACROOP, 0, - 4, '.', 'M', 'A', 'P', MAPOP, 0, - 3, 'O', 'R', 'G', ORGOP, 0, - 4, '.', 'O', 'R', 'G', ORGOP, 0, - 6, 'P', 'U', 'B', 'L', 'I', 'C', EXPORTOP, 0, - 3, 'R', 'M', 'B', RMBOP, 0, - 4, '.', 'R', 'O', 'M', DATAOP, 0, - 5, '.', 'S', 'E', 'C', 'T', SECTOP, 0, - 3, 'S', 'E', 'T', SETOP, 0, - 5, 'S', 'E', 'T', 'D', 'P', SETDPOP, 0, - 6, '.', 'S', 'H', 'O', 'R', 'T', FDBOP, 0, - 6, '.', 'S', 'P', 'A', 'C', 'E', RMBOP, 0, - 5, '.', 'T', 'E', 'X', 'T', TEXTOP, 0, - 5, 'U', 'S', 'E', '1', '6', USE16OP, 0, - 5, 'U', 'S', 'E', '3', '2', USE32OP, 0, - 5, '.', 'W', 'A', 'R', 'N', WARNOP, 0, - 5, '.', 'W', 'O', 'R', 'D', FDBOP, 0, - 6, '.', 'Z', 'E', 'R', 'O', 'W', BLKWOP, 0, - - /* hardware ops. The opcode field is now used */ -#ifdef I80386 - 3, 'A', 'A', 'A', INHER, 0x37, - 3, 'A', 'A', 'D', INHER_A, 0xD5, - 3, 'A', 'A', 'M', INHER_A, 0xD4, - 3, 'A', 'A', 'S', INHER, 0x3F, - 3, 'A', 'D', 'C', GROUP1, 0x10, - 3, 'A', 'D', 'D', GROUP1, 0x00, - 3, 'A', 'N', 'D', GROUP1, 0x20, - 4, 'A', 'R', 'P', 'L', EwGw, 0x63, - 3, 'B', 'C', 'C', BCC, 0x73, - 3, 'B', 'C', 'S', BCC, 0x72, - 3, 'B', 'E', 'Q', BCC, 0x74, - 3, 'B', 'G', 'E', BCC, 0x7D, - 3, 'B', 'G', 'T', BCC, 0x7F, - 3, 'B', 'H', 'I', BCC, 0x77, - 4, 'B', 'H', 'I', 'S', BCC, 0x73, - 3, 'B', 'L', 'E', BCC, 0x7E, - 3, 'B', 'L', 'O', BCC, 0x72, - 4, 'B', 'L', 'O', 'S', BCC, 0x76, - 3, 'B', 'L', 'T', BCC, 0x7C, - 3, 'B', 'M', 'I', BCC, 0x78, - 3, 'B', 'N', 'E', BCC, 0x75, - 5, 'B', 'O', 'U', 'N', 'D', GvMa, 0x62, - 3, 'B', 'P', 'C', BCC, 0x7B, - 3, 'B', 'P', 'L', BCC, 0x79, - 3, 'B', 'P', 'S', BCC, 0x7A, - 2, 'B', 'R', CALL, JMP_OPCODE, - 3, 'B', 'V', 'C', BCC, 0x71, - 3, 'B', 'V', 'S', BCC, 0x70, - 4, 'C', 'A', 'L', 'L', CALL, JSR_OPCODE, - 5, 'C', 'A', 'L', 'L', 'F', CALLI, 0x9A, - 5, 'C', 'A', 'L', 'L', 'I', CALLI, 0x9A, - 3, 'C', 'B', 'W', INHER16, 0x98, - 3, 'C', 'L', 'C', INHER, 0xF8, - 3, 'C', 'L', 'D', INHER, 0xFC, - 3, 'C', 'L', 'I', INHER, 0xFA, - 3, 'C', 'M', 'C', INHER, 0xF5, - 3, 'C', 'M', 'P', GROUP1, CMP_OPCODE_BASE, - 4, 'C', 'M', 'P', 'S', INHER, CMPSW_OPCODE, - 5, 'C', 'M', 'P', 'S', 'B', INHER, CMPSB_OPCODE, - 5, 'C', 'M', 'P', 'S', 'D', INHER32, CMPSW_OPCODE, - 5, 'C', 'M', 'P', 'S', 'W', INHER16, CMPSW_OPCODE, - 4, 'C', 'M', 'P', 'W', INHER16, CMPSW_OPCODE, - 4, 'C', 'S', 'E', 'G', INHER, 0x2E, - 3, 'C', 'W', 'D', INHER16, 0x99, - 4, 'C', 'W', 'D', 'E', INHER32, 0x98, - 3, 'C', 'D', 'Q', INHER32, 0x99, - 3, 'D', 'A', 'A', INHER, 0x27, - 3, 'D', 'A', 'S', INHER, 0x2F, - 4, 'D', 'S', 'E', 'G', INHER, 0x3E, - 3, 'D', 'E', 'C', INCDEC, 0x08, - 3, 'D', 'I', 'V', DIVMUL, 0x30, - 5, 'E', 'N', 'T', 'E', 'R', ENTER, 0xC8, - 4, 'E', 'S', 'E', 'G', INHER, 0x26, - 4, 'F', 'S', 'E', 'G', INHER, 0x64, - 4, 'G', 'S', 'E', 'G', INHER, 0x65, - 3, 'H', 'L', 'T', INHER, 0xF4, - 4, 'I', 'D', 'I', 'V', DIVMUL, 0x38, - 4, 'I', 'M', 'U', 'L', IMUL, 0x28, - 2, 'I', 'N', IN, 0xEC, - 3, 'I', 'N', 'C', INCDEC, 0x00, - 3, 'I', 'N', 'S', INHER, 0x6D, - 4, 'I', 'N', 'S', 'B', INHER, 0x6C, - 4, 'I', 'N', 'S', 'D', INHER32, 0x6D, - 4, 'I', 'N', 'S', 'W', INHER16, 0x6D, - 3, 'I', 'N', 'T', INT, 0xCD, - 4, 'I', 'N', 'T', 'O', INHER, 0xCE, - 3, 'I', 'N', 'W', IN, 0xED, - 4, 'I', 'R', 'E', 'T', INHER16, 0xCF, - 5, 'I', 'R', 'E', 'T', 'D', INHER32, 0xCF, - 1, 'J', CALL, JMP_SHORT_OPCODE, - 2, 'J', 'A', JCC, 0x77, - 3, 'J', 'A', 'E', JCC, 0x73, - 2, 'J', 'B', JCC, 0x72, - 3, 'J', 'B', 'E', JCC, 0x76, - 2, 'J', 'C', JCC, 0x72, - 4, 'J', 'C', 'X', 'E', JCXZ, 0x2, - 4, 'J', 'C', 'X', 'Z', JCXZ, 0x2, - 5, 'J', 'E', 'C', 'X', 'E', JCXZ, 0x4, - 5, 'J', 'E', 'C', 'X', 'Z', JCXZ, 0x4, - 2, 'J', 'E', JCC, 0x74, - 2, 'J', 'G', JCC, 0x7F, - 3, 'J', 'G', 'E', JCC, 0x7D, - 2, 'J', 'L', JCC, 0x7C, - 3, 'J', 'L', 'E', JCC, 0x7E, - 3, 'J', 'M', 'P', CALL, JMP_SHORT_OPCODE, - 4, 'J', 'M', 'P', 'F', CALLI, 0xEA, - 4, 'J', 'M', 'P', 'I', CALLI, 0xEA, - 3, 'J', 'N', 'A', JCC, 0x76, - 4, 'J', 'N', 'A', 'E', JCC, 0x72, - 3, 'J', 'N', 'B', JCC, 0x73, - 4, 'J', 'N', 'B', 'E', JCC, 0x77, - 3, 'J', 'N', 'C', JCC, 0x73, - 3, 'J', 'N', 'E', JCC, 0x75, - 3, 'J', 'N', 'G', JCC, 0x7E, - 4, 'J', 'N', 'G', 'E', JCC, 0x7C, - 3, 'J', 'N', 'L', JCC, 0x7D, - 4, 'J', 'N', 'L', 'E', JCC, 0x7F, - 3, 'J', 'N', 'O', JCC, 0x71, - 3, 'J', 'N', 'P', JCC, 0x7B, - 3, 'J', 'N', 'S', JCC, 0x79, - 3, 'J', 'N', 'Z', JCC, 0x75, - 2, 'J', 'O', JCC, 0x70, - 2, 'J', 'P', JCC, 0x7A, - 3, 'J', 'P', 'E', JCC, 0x7A, - 3, 'J', 'P', 'O', JCC, 0x7B, - 2, 'J', 'S', JCC, 0x78, - 2, 'J', 'Z', JCC, 0x74, - 4, 'L', 'A', 'H', 'F', INHER, 0x9F, - 3, 'L', 'D', 'S', GvMp, 0xC5, - 3, 'L', 'E', 'A', LEA, 0x8D, - 5, 'L', 'E', 'A', 'V', 'E', INHER, 0xC9, - 3, 'L', 'E', 'S', GvMp, 0xC4, - 4, 'L', 'O', 'C', 'K', INHER, 0xF0, - 4, 'L', 'O', 'D', 'B', INHER, 0xAC, - 4, 'L', 'O', 'D', 'S', INHER, 0xAD, - 5, 'L', 'O', 'D', 'S', 'B', INHER, 0xAC, - 5, 'L', 'O', 'D', 'S', 'D', INHER32, 0xAD, - 5, 'L', 'O', 'D', 'S', 'W', INHER16, 0xAD, - 4, 'L', 'O', 'D', 'W', INHER16, 0xAD, - 4, 'L', 'O', 'O', 'P', JCC, 0xE2, - 5, 'L', 'O', 'O', 'P', 'E', JCC, 0xE1, - 6, 'L', 'O', 'O', 'P', 'N', 'E', JCC, 0xE0, - 6, 'L', 'O', 'O', 'P', 'N', 'Z', JCC, 0xE0, - 5, 'L', 'O', 'O', 'P', 'Z', JCC, 0xE1, - 3, 'M', 'O', 'V', MOV, 0x88, - 4, 'M', 'O', 'V', 'S', INHER, MOVSW_OPCODE, - 5, 'M', 'O', 'V', 'S', 'B', INHER, MOVSB_OPCODE, - 5, 'M', 'O', 'V', 'S', 'D', INHER32, MOVSW_OPCODE, - 5, 'M', 'O', 'V', 'S', 'W', INHER16, MOVSW_OPCODE, - 4, 'M', 'O', 'V', 'W', INHER16, MOVSW_OPCODE, - 3, 'M', 'U', 'L', DIVMUL, 0x20, - 3, 'N', 'E', 'G', NEGNOT, 0x18, - 3, 'N', 'O', 'P', INHER, 0x90, - 3, 'N', 'O', 'T', NEGNOT, 0x10, - 2, 'O', 'R', GROUP1, 0x08, - 3, 'O', 'U', 'T', OUT, 0xEE, - 4, 'O', 'U', 'T', 'S', INHER, 0x6F, - 5, 'O', 'U', 'T', 'S', 'B', INHER, 0x6E, - 5, 'O', 'U', 'T', 'S', 'D', INHER32, 0x6F, - 5, 'O', 'U', 'T', 'S', 'W', INHER16, 0x6F, - 4, 'O', 'U', 'T', 'W', OUT, 0xEF, - 3, 'P', 'O', 'P', PUSHPOP, POP_OPCODE, - 4, 'P', 'O', 'P', 'A', INHER16, 0x61, - 5, 'P', 'O', 'P', 'A', 'D', INHER32, 0x61, - 4, 'P', 'O', 'P', 'F', INHER16, 0x9D, - 5, 'P', 'O', 'P', 'F', 'D', INHER32, 0x9D, - 4, 'P', 'U', 'S', 'H', PUSHPOP, PUSH_OPCODE, - 5, 'P', 'U', 'S', 'H', 'A', INHER16, 0x60, - 6, 'P', 'U', 'S', 'H', 'A', 'D', INHER32, 0x60, - 5, 'P', 'U', 'S', 'H', 'F', INHER16, 0x9C, - 6, 'P', 'U', 'S', 'H', 'F', 'D', INHER32, 0x9C, - 3, 'R', 'C', 'L', GROUP2, 0x10, - 3, 'R', 'C', 'R', GROUP2, 0x18, - 3, 'R', 'O', 'L', GROUP2, 0x00, - 3, 'R', 'O', 'R', GROUP2, 0x08, - 3, 'R', 'E', 'P', INHER, 0xF3, - 4, 'R', 'E', 'P', 'E', INHER, 0xF3, - 5, 'R', 'E', 'P', 'N', 'E', INHER, 0xF2, - 5, 'R', 'E', 'P', 'N', 'Z', INHER, 0xF2, - 4, 'R', 'E', 'P', 'Z', INHER, 0xF3, - 3, 'R', 'E', 'T', RET, 0xC3, - 4, 'R', 'E', 'T', 'F', RET, 0xCB, - 4, 'R', 'E', 'T', 'I', RET, 0xCB, - 4, 'S', 'A', 'H', 'F', INHER, 0x9E, - 3, 'S', 'A', 'L', GROUP2, 0x20, - 3, 'S', 'A', 'R', GROUP2, 0x38, - 3, 'S', 'B', 'B', GROUP1, 0x18, - 4, 'S', 'C', 'A', 'B', INHER, 0xAE, - 4, 'S', 'C', 'A', 'S', INHER, 0xAF, - 5, 'S', 'C', 'A', 'S', 'B', INHER, 0xAE, - 5, 'S', 'C', 'A', 'S', 'D', INHER32, 0xAF, - 5, 'S', 'C', 'A', 'S', 'W', INHER16, 0xAF, - 4, 'S', 'C', 'A', 'W', INHER16, 0xAF, - 3, 'S', 'E', 'G', SEG, 0x06, - 3, 'S', 'H', 'L', GROUP2, 0x20, - 3, 'S', 'H', 'R', GROUP2, 0x28, - 4, 'S', 'S', 'E', 'G', INHER, 0x36, - 3, 'S', 'T', 'C', INHER, 0xF9, - 3, 'S', 'T', 'D', INHER, 0xFD, - 3, 'S', 'T', 'I', INHER, 0xFB, - 4, 'S', 'T', 'O', 'B', INHER, 0xAA, - 4, 'S', 'T', 'O', 'S', INHER, 0xAB, - 5, 'S', 'T', 'O', 'S', 'B', INHER, 0xAA, - 5, 'S', 'T', 'O', 'S', 'D', INHER32, 0xAB, - 5, 'S', 'T', 'O', 'S', 'W', INHER16, 0xAB, - 4, 'S', 'T', 'O', 'W', INHER16, 0xAB, - 3, 'S', 'U', 'B', GROUP1, 0x28, - 4, 'T', 'E', 'S', 'T', TEST, 0x84, - 4, 'W', 'A', 'I', 'T', INHER, WAIT_OPCODE, - 4, 'X', 'C', 'H', 'G', XCHG, 0x86, - 4, 'X', 'L', 'A', 'T', INHER, 0xD7, - 5, 'X', 'L', 'A', 'T', 'B', INHER, 0xD7, - 3, 'X', 'O', 'R', GROUP1, 0x30, - - /* floating point */ - 5, 'F', '2', 'X', 'M', '1', F_INHER, 0x70, - 4, 'F', 'A', 'B', 'S', F_INHER, 0x61, - 4, 'F', 'A', 'D', 'D', F_M4_M8_STST, 0x00, - 5, 'F', 'A', 'D', 'D', 'P', F_STST, 0x60, - 4, 'F', 'B', 'L', 'D', F_M10, 0x74, - 5, 'F', 'B', 'S', 'T', 'P', F_M10, 0x76, - 4, 'F', 'C', 'H', 'S', F_INHER, 0x60, - 5, 'F', 'C', 'L', 'E', 'X', F_W_INHER, 0xE2, - 4, 'F', 'C', 'O', 'M', F_M4_M8_OPTST, 0x02, - 5, 'F', 'C', 'O', 'M', 'P', F_M4_M8_OPTST, 0x03, - 6, 'F', 'C', 'O', 'M', 'P', 'P', F_INHER, 0x19, - 4, 'F', 'C', 'O', 'S', F_INHER, 0x7F, - 7, 'F', 'D', 'E', 'C', 'S', 'T', 'P', F_INHER, 0x76, - 5, 'F', 'D', 'I', 'S', 'I', F_W_INHER, 0xE1, - 4, 'F', 'D', 'I', 'V', F_M4_M8_STST, 0x06, - 5, 'F', 'D', 'I', 'V', 'P', F_STST, 0x67, - 5, 'F', 'D', 'I', 'V', 'R', F_M4_M8_STST, 0x07, - 6, 'F', 'D', 'I', 'V', 'R', 'P', F_STST, 0x66, - 4, 'F', 'E', 'N', 'I', F_W_INHER, 0xE0, - 5, 'F', 'F', 'R', 'E', 'E', F_ST, 0x50, - 5, 'F', 'I', 'A', 'D', 'D', F_M2_M4, 0x20, - 5, 'F', 'I', 'C', 'O', 'M', F_M2_M4, 0x22, - 6, 'F', 'I', 'C', 'O', 'M', 'P', F_M2_M4, 0x23, - 5, 'F', 'I', 'D', 'I', 'V', F_M2_M4, 0x26, - 6, 'F', 'I', 'D', 'I', 'V', 'R', F_M2_M4, 0x27, - 4, 'F', 'I', 'L', 'D', F_M2_M4_M8, 0x30, - 5, 'F', 'I', 'M', 'U', 'L', F_M2_M4, 0x21, - 7, 'F', 'I', 'N', 'C', 'S', 'T', 'P', F_INHER, 0x77, - 5, 'F', 'I', 'N', 'I', 'T', F_W_INHER, 0xE3, - 4, 'F', 'I', 'S', 'T', F_M2_M4, 0x32, - 5, 'F', 'I', 'S', 'T', 'P', F_M2_M4_M8, 0x33, - 5, 'F', 'I', 'S', 'U', 'B', F_M2_M4, 0x24, - 6, 'F', 'I', 'S', 'U', 'B', 'R', F_M2_M4, 0x25, - 3, 'F', 'L', 'D', F_M4_M8_M10_ST, 0x10, - 4, 'F', 'L', 'D', '1', F_INHER, 0x68, - 6, 'F', 'L', 'D', 'L', '2', 'E', F_INHER, 0x6A, - 6, 'F', 'L', 'D', 'L', '2', 'T', F_INHER, 0x69, - 5, 'F', 'L', 'D', 'C', 'W', F_M2, 0x15, - 6, 'F', 'L', 'D', 'E', 'N', 'V', F_M, 0x14, - 6, 'F', 'L', 'D', 'L', 'G', '2', F_INHER, 0x6C, - 6, 'F', 'L', 'D', 'L', 'N', '2', F_INHER, 0x6D, - 5, 'F', 'L', 'D', 'P', 'I', F_INHER, 0x6B, - 4, 'F', 'L', 'D', 'Z', F_INHER, 0x6E, - 4, 'F', 'M', 'U', 'L', F_M4_M8_STST, 0x01, - 5, 'F', 'M', 'U', 'L', 'P', F_STST, 0x61, - 6, 'F', 'N', 'C', 'L', 'E', 'X', F_INHER, 0xE2, - 6, 'F', 'N', 'D', 'I', 'S', 'I', F_INHER, 0xE1, - 5, 'F', 'N', 'E', 'N', 'I', F_INHER, 0xE0, - 6, 'F', 'N', 'I', 'N', 'I', 'T', F_INHER, 0xE3, - 4, 'F', 'N', 'O', 'P', F_INHER, 0x50, - 6, 'F', 'N', 'S', 'A', 'V', 'E', F_M, 0x56, - 6, 'F', 'N', 'S', 'T', 'C', 'W', F_M2, 0x17, - 7, 'F', 'N', 'S', 'T', 'E', 'N', 'V', F_M, 0x16, - 6, 'F', 'N', 'S', 'T', 'S', 'W', F_M2_AX, 0x57, - 6, 'F', 'P', 'A', 'T', 'A', 'N', F_INHER, 0x73, - 5, 'F', 'P', 'R', 'E', 'M', F_INHER, 0x78, - 6, 'F', 'P', 'R', 'E', 'M', '1', F_INHER, 0x75, - 5, 'F', 'P', 'T', 'A', 'N', F_INHER, 0x72, - 7, 'F', 'R', 'N', 'D', 'I', 'N', 'T', F_INHER, 0x7C, - 6, 'F', 'R', 'S', 'T', 'O', 'R', F_M, 0x54, - 5, 'F', 'S', 'A', 'V', 'E', F_W_M, 0x56, - 6, 'F', 'S', 'C', 'A', 'L', 'E', F_INHER, 0x7D, - 6, 'F', 'S', 'E', 'T', 'P', 'M', F_INHER, 0xE4, - 4, 'F', 'S', 'I', 'N', F_INHER, 0x7E, - 7, 'F', 'S', 'I', 'N', 'C', 'O', 'S', F_INHER, 0x7B, - 5, 'F', 'S', 'Q', 'R', 'T', F_INHER, 0x7A, - 3, 'F', 'S', 'T', F_M4_M8_ST, FST_ENCODED, - 5, 'F', 'S', 'T', 'C', 'W', F_W_M2, 0x17, - 6, 'F', 'S', 'T', 'E', 'N', 'V', F_W_M, 0x16, - 4, 'F', 'S', 'T', 'P', F_M4_M8_M10_ST, FSTP_ENCODED, - 5, 'F', 'S', 'T', 'S', 'W', F_W_M2_AX, 0x57, - 4, 'F', 'S', 'U', 'B', F_M4_M8_STST, 0x04, - 5, 'F', 'S', 'U', 'B', 'P', F_STST, 0x65, - 5, 'F', 'S', 'U', 'B', 'R', F_M4_M8_STST, 0x05, - 6, 'F', 'S', 'U', 'B', 'R', 'P', F_STST, 0x64, - 4, 'F', 'T', 'S', 'T', F_INHER, 0x64, - 5, 'F', 'U', 'C', 'O', 'M', F_OPTST, 0x54, - 6, 'F', 'U', 'C', 'O', 'M', 'P', F_OPTST, 0x55, - 7, 'F', 'U', 'C', 'O', 'M', 'P', 'P', F_INHER, 0xA9, - 5, 'F', 'W', 'A', 'I', 'T', INHER, WAIT_OPCODE, - 4, 'F', 'X', 'A', 'M', F_INHER, 0x65, - 4, 'F', 'X', 'C', 'H', F_OPTST, 0x11, - 7, 'F', 'X', 'T', 'R', 'A', 'C', 'T', F_INHER, 0x74, - 5, 'F', 'Y', 'L', '2', 'X', F_INHER, 0x71, - 7, 'F', 'Y', 'L', '2', 'X', 'P', '1', F_INHER, 0x79, -#endif /* I80386 */ - -#ifdef MC6809 - 3, 'A', 'B', 'X', INHER, 0x3A, - 4, 'A', 'D', 'C', 'A', ALL, 0x89, - 4, 'A', 'D', 'C', 'B', ALL, 0xC9, - 4, 'A', 'D', 'D', 'A', ALL, 0x8B, - 4, 'A', 'D', 'D', 'B', ALL, 0xCB, - 4, 'A', 'D', 'D', 'D', ALL, 0xC3, - 4, 'A', 'N', 'D', 'A', ALL, 0x84, - 4, 'A', 'N', 'D', 'B', ALL, 0xC4, - 5, 'A', 'N', 'D', 'C', 'C', IMMED, 0x1C, - 3, 'A', 'S', 'L', ALTER, 0x08, - 4, 'A', 'S', 'L', 'A', INHER, 0x48, - 4, 'A', 'S', 'L', 'B', INHER, 0x58, - 3, 'A', 'S', 'R', ALTER, 0x07, - 4, 'A', 'S', 'R', 'A', INHER, 0x47, - 4, 'A', 'S', 'R', 'B', INHER, 0x57, - 3, 'B', 'C', 'C', SHORT, 0x24, - 3, 'B', 'C', 'S', SHORT, 0x25, - 3, 'B', 'E', 'Q', SHORT, 0x27, - 3, 'B', 'G', 'E', SHORT, 0x2C, - 3, 'B', 'G', 'T', SHORT, 0x2E, - 3, 'B', 'H', 'I', SHORT, 0x22, - 3, 'B', 'H', 'S', SHORT, 0x24, - 4, 'B', 'I', 'T', 'A', ALL, 0X85, - 4, 'B', 'I', 'T', 'B', ALL, 0XC5, - 3, 'B', 'L', 'E', SHORT, 0x2F, - 3, 'B', 'L', 'O', SHORT, 0x25, - 3, 'B', 'L', 'S', SHORT, 0x23, - 3, 'B', 'L', 'T', SHORT, 0x2D, - 3, 'B', 'M', 'I', SHORT, 0x2B, - 3, 'B', 'N', 'E', SHORT, 0x26, - 3, 'B', 'P', 'L', SHORT, 0x2A, - 3, 'B', 'R', 'A', SHORT, 0x20, - 4, 'L', 'B', 'R', 'A', LONG, 0x16, - 3, 'B', 'R', 'N', SHORT, 0x21, - 3, 'B', 'S', 'R', SHORT, 0x8D, - 4, 'L', 'B', 'S', 'R', LONG, 0x17, - 3, 'B', 'V', 'C', SHORT, 0x28, - 3, 'B', 'V', 'S', SHORT, 0x29, - 3, 'C', 'L', 'R', ALTER, 0x0F, - 4, 'C', 'L', 'R', 'A', INHER, 0x4F, - 4, 'C', 'L', 'R', 'B', INHER, 0x5F, - 4, 'C', 'M', 'P', 'A', ALL, 0x81, - 4, 'C', 'M', 'P', 'B', ALL, 0xC1, - 4, 'C', 'M', 'P', 'X', ALL, 0x8C, - 3, 'C', 'O', 'M', ALTER, 0x03, - 4, 'C', 'O', 'M', 'A', INHER, 0x43, - 4, 'C', 'O', 'M', 'B', INHER, 0x53, - 4, 'C', 'W', 'A', 'I', IMMED, 0x3C, - 3, 'D', 'A', 'A', INHER, 0x19, - 3, 'D', 'E', 'C', ALTER, 0x0A, - 4, 'D', 'E', 'C', 'A', INHER, 0x4A, - 4, 'D', 'E', 'C', 'B', INHER, 0x5A, - 4, 'E', 'O', 'R', 'A', ALL, 0x88, - 4, 'E', 'O', 'R', 'B', ALL, 0xC8, - 3, 'E', 'X', 'G', SWAP, 0x1E, - 3, 'I', 'N', 'C', ALTER, 0x0C, - 4, 'I', 'N', 'C', 'A', INHER, 0x4C, - 4, 'I', 'N', 'C', 'B', INHER, 0x5C, - 3, 'J', 'M', 'P', ALTER, 0x0E, - 3, 'J', 'S', 'R', ALTER, 0x8D, - 3, 'L', 'D', 'A', ALL, 0x86, - 3, 'L', 'D', 'B', ALL, 0xC6, - 3, 'L', 'D', 'D', ALL, 0xCC, - 3, 'L', 'D', 'U', ALL, 0xCE, - 3, 'L', 'D', 'X', ALL, 0x8E, - 4, 'L', 'E', 'A', 'S', INDEXD, 0x32, - 4, 'L', 'E', 'A', 'U', INDEXD, 0x33, - 4, 'L', 'E', 'A', 'X', INDEXD, 0x30, - 4, 'L', 'E', 'A', 'Y', INDEXD, 0x31, - 3, 'L', 'S', 'L', ALTER, 0x08, - 4, 'L', 'S', 'L', 'A', INHER, 0x48, - 4, 'L', 'S', 'L', 'B', INHER, 0x58, - 3, 'L', 'S', 'R', ALTER, 0x04, - 4, 'L', 'S', 'R', 'A', INHER, 0x44, - 4, 'L', 'S', 'R', 'B', INHER, 0x54, - 3, 'M', 'U', 'L', INHER, 0x3D, - 3, 'N', 'E', 'G', ALTER, 0x00, - 4, 'N', 'E', 'G', 'A', INHER, 0x40, - 4, 'N', 'E', 'G', 'B', INHER, 0x50, - 3, 'N', 'O', 'P', INHER, 0x12, - 3, 'O', 'R', 'A', ALL, 0x8A, - 3, 'O', 'R', 'B', ALL, 0xCA, - 4, 'O', 'R', 'C', 'C', IMMED, 0x1A, - 4, 'P', 'S', 'H', 'S', SSTAK, 0x34, - 4, 'P', 'S', 'H', 'U', USTAK, 0x36, - 4, 'P', 'U', 'L', 'S', SSTAK, 0x35, - 4, 'P', 'U', 'L', 'U', USTAK, 0x37, - 3, 'R', 'O', 'L', ALTER, 0x09, - 4, 'R', 'O', 'L', 'A', INHER, 0x49, - 4, 'R', 'O', 'L', 'B', INHER, 0x59, - 3, 'R', 'O', 'R', ALTER, 0x06, - 4, 'R', 'O', 'R', 'A', INHER, 0x46, - 4, 'R', 'O', 'R', 'B', INHER, 0x56, - 3, 'R', 'T', 'I', INHER, 0x3B, - 3, 'R', 'T', 'S', INHER, 0x39, - 4, 'S', 'B', 'C', 'A', ALL, 0x82, - 4, 'S', 'B', 'C', 'B', ALL, 0xC2, - 3, 'S', 'E', 'X', INHER, 0x1D, - 3, 'S', 'T', 'A', ALTER, 0x87, - 3, 'S', 'T', 'B', ALTER, 0xC7, - 3, 'S', 'T', 'D', ALTER, 0xCD, - 3, 'S', 'T', 'U', ALTER, 0xCF, - 3, 'S', 'T', 'X', ALTER, 0x8F, - 4, 'S', 'U', 'B', 'A', ALL, 0x80, - 4, 'S', 'U', 'B', 'B', ALL, 0xC0, - 4, 'S', 'U', 'B', 'D', ALL, 0x83, - 3, 'S', 'W', 'I', INHER, 0x3F, - 4, 'S', 'Y', 'N', 'C', INHER, 0x13, - 3, 'T', 'F', 'R', SWAP, 0x1F, - 3, 'T', 'S', 'T', ALTER, 0x0D, - 4, 'T', 'S', 'T', 'A', INHER, 0x4D, - 4, 'T', 'S', 'T', 'B', INHER, 0x5D, -#endif /* MC6809 */ - 0 /* end of ops */ -}; - -PUBLIC char page1ops[] = -{ -#ifdef I80386 - 3, 'B', 'S', 'F', GvEv, 0xBC, - 3, 'B', 'S', 'R', GvEv, 0xBD, - 5, 'B', 'S', 'W', 'A', 'P', BSWAP, 0xC8, - 2, 'B', 'T', GROUP8, 0x20, - 3, 'B', 'T', 'C', GROUP8, 0x38, - 3, 'B', 'T', 'R', GROUP8, 0x30, - 3, 'B', 'T', 'S', GROUP8, 0x28, - 4, 'C', 'L', 'T', 'S', INHER, 0x06, - 7, 'C', 'M', 'P', 'X', 'C', 'H', 'G', ExGx, 0xA6, - 4, 'I', 'N', 'V', 'D', INHER, 0x08, - 6, 'I', 'N', 'V', 'L', 'P', 'G', GROUP7, 0x38, - 3, 'L', 'A', 'R', GvEv, 0x02, - 3, 'L', 'F', 'S', GvMp, 0xB4, - 4, 'L', 'G', 'D', 'T', GROUP7, 0x10, - 3, 'L', 'G', 'S', GvMp, 0xB5, - 4, 'L', 'I', 'D', 'T', GROUP7, 0x18, - 4, 'L', 'L', 'D', 'T', GROUP6, 0x10, - 4, 'L', 'M', 'S', 'W', GROUP7, 0x30, - 3, 'L', 'S', 'L', GvEv, 0x03, - 3, 'L', 'S', 'S', GvMp, 0xB2, - 3, 'L', 'T', 'R', GROUP6, 0x18, - 5, 'M', 'O', 'V', 'S', 'X', MOVX, 0xBE, - 5, 'M', 'O', 'V', 'Z', 'X', MOVX, 0xB6, - 4, 'S', 'E', 'T', 'A', SETCC, 0x97, - 5, 'S', 'E', 'T', 'A', 'E', SETCC, 0x93, - 4, 'S', 'E', 'T', 'B', SETCC, 0x92, - 5, 'S', 'E', 'T', 'B', 'E', SETCC, 0x96, - 4, 'S', 'E', 'T', 'C', SETCC, 0x92, - 4, 'S', 'E', 'T', 'E', SETCC, 0x94, - 4, 'S', 'E', 'T', 'G', SETCC, 0x9F, - 5, 'S', 'E', 'T', 'G', 'E', SETCC, 0x9D, - 4, 'S', 'E', 'T', 'L', SETCC, 0x9C, - 5, 'S', 'E', 'T', 'L', 'E', SETCC, 0x9E, - 5, 'S', 'E', 'T', 'N', 'A', SETCC, 0x96, - 6, 'S', 'E', 'T', 'N', 'A', 'E', SETCC, 0x92, - 5, 'S', 'E', 'T', 'N', 'B', SETCC, 0x93, - 6, 'S', 'E', 'T', 'N', 'B', 'E', SETCC, 0x97, - 5, 'S', 'E', 'T', 'N', 'C', SETCC, 0x93, - 5, 'S', 'E', 'T', 'N', 'E', SETCC, 0x95, - 5, 'S', 'E', 'T', 'N', 'G', SETCC, 0x9E, - 6, 'S', 'E', 'T', 'N', 'G', 'E', SETCC, 0x9C, - 5, 'S', 'E', 'T', 'N', 'L', SETCC, 0x9D, - 6, 'S', 'E', 'T', 'N', 'L', 'E', SETCC, 0x9F, - 5, 'S', 'E', 'T', 'N', 'O', SETCC, 0x91, - 5, 'S', 'E', 'T', 'N', 'P', SETCC, 0x9B, - 5, 'S', 'E', 'T', 'N', 'S', SETCC, 0x99, - 5, 'S', 'E', 'T', 'N', 'Z', SETCC, 0x95, - 4, 'S', 'E', 'T', 'O', SETCC, 0x90, - 4, 'S', 'E', 'T', 'P', SETCC, 0x9A, - 5, 'S', 'E', 'T', 'P', 'E', SETCC, 0x9A, - 5, 'S', 'E', 'T', 'P', 'O', SETCC, 0x9B, - 4, 'S', 'E', 'T', 'S', SETCC, 0x98, - 4, 'S', 'E', 'T', 'Z', SETCC, 0x94, - 4, 'S', 'G', 'D', 'T', GROUP7, 0x00, - 4, 'S', 'I', 'D', 'T', GROUP7, 0x08, - 4, 'S', 'H', 'L', 'D', SH_DOUBLE, 0xA4, - 4, 'S', 'H', 'R', 'D', SH_DOUBLE, 0xAC, - 4, 'S', 'L', 'D', 'T', GROUP6, 0x00, - 4, 'S', 'M', 'S', 'W', GROUP7, 0x20, - 3, 'S', 'T', 'R', GROUP6, 0x08, - 4, 'V', 'E', 'R', 'R', GROUP6, 0x20, - 4, 'V', 'E', 'R', 'W', GROUP6, 0x28, - 6, 'W', 'B', 'I', 'N', 'V', 'D', INHER, 0x09, - 4, 'X', 'A', 'D', 'D', ExGx, 0xC0, -#endif /* I80386 */ - -#ifdef MC6809 - 4, 'L', 'B', 'C', 'C', LONG, 0x24, - 4, 'L', 'B', 'C', 'S', LONG, 0x25, - 4, 'L', 'B', 'E', 'Q', LONG, 0x27, - 4, 'L', 'B', 'G', 'E', LONG, 0x2C, - 4, 'L', 'B', 'G', 'T', LONG, 0x2E, - 4, 'L', 'B', 'H', 'I', LONG, 0x22, - 4, 'L', 'B', 'H', 'S', LONG, 0x24, - 4, 'L', 'B', 'L', 'E', LONG, 0x2F, - 4, 'L', 'B', 'L', 'O', LONG, 0x25, - 4, 'L', 'B', 'L', 'S', LONG, 0x23, - 4, 'L', 'B', 'L', 'T', LONG, 0x2D, - 4, 'L', 'B', 'M', 'I', LONG, 0x2B, - 4, 'L', 'B', 'N', 'E', LONG, 0x26, - 4, 'L', 'B', 'P', 'L', LONG, 0x2A, - 4, 'L', 'B', 'R', 'N', LONG, 0x21, - 4, 'L', 'B', 'V', 'C', LONG, 0x28, - 4, 'L', 'B', 'V', 'S', LONG, 0x29, - 4, 'C', 'M', 'P', 'D', ALL, 0x83, - 4, 'C', 'M', 'P', 'Y', ALL, 0x8C, - 3, 'L', 'D', 'S', ALL, 0xCE, - 3, 'L', 'D', 'Y', ALL, 0x8E, - 3, 'S', 'T', 'S', ALTER, 0xCF, - 3, 'S', 'T', 'Y', ALTER, 0x8F, - 4, 'S', 'W', 'I', '2', INHER, 0x3F, -#endif /* MC6809 */ - 0 /* end of page 1 ops */ -}; - -PUBLIC char page2ops[] = -{ -#ifdef MC6809 - 4, 'C', 'M', 'P', 'S', ALL, 0x8C, - 4, 'C', 'M', 'P', 'U', ALL, 0x83, - 4, 'S', 'W', 'I', '3', INHER, 0x3F, -#endif - 0 /* end of page 2 ops */ -}; - -#ifdef I80386 -# ifdef MNSIZE -PUBLIC char bytesizeops[] = -{ - 4, 'A', 'D', 'C', 'B', GROUP1, 0x10, - 4, 'A', 'D', 'D', 'B', GROUP1, 0x00, - 4, 'A', 'N', 'D', 'B', GROUP1, 0x20, - 4, 'C', 'M', 'P', 'B', GROUP1, CMP_OPCODE_BASE, - 4, 'D', 'E', 'C', 'b', INCDEC, 0x08, - 4, 'D', 'I', 'V', 'B', DIVMUL, 0x30, - 5, 'I', 'D', 'I', 'V', 'B', DIVMUL, 0x38, - 5, 'I', 'M', 'U', 'L', 'B', IMUL, 0x28, - 3, 'I', 'N', 'B', IN, 0xEC, - 4, 'I', 'N', 'C', 'B', INCDEC, 0x00, - 4, 'M', 'O', 'V', 'B', MOV, 0x88, - 4, 'M', 'U', 'L', 'B', DIVMUL, 0x20, - 4, 'N', 'E', 'G', 'B', NEGNOT, 0x18, - 4, 'N', 'O', 'T', 'B', NEGNOT, 0x10, - 3, 'O', 'R', 'B', GROUP1, 0x08, - 4, 'O', 'U', 'T', 'B', OUT, 0xEE, - 4, 'R', 'C', 'L', 'B', GROUP2, 0x10, - 4, 'R', 'C', 'R', 'B', GROUP2, 0x18, - 4, 'R', 'O', 'L', 'B', GROUP2, 0x00, - 4, 'R', 'O', 'R', 'B', GROUP2, 0x08, - 4, 'S', 'A', 'L', 'B', GROUP2, 0x20, - 4, 'S', 'A', 'R', 'B', GROUP2, 0x38, - 4, 'S', 'H', 'L', 'B', GROUP2, 0x20, - 4, 'S', 'H', 'R', 'B', GROUP2, 0x28, - 4, 'S', 'B', 'B', 'B', GROUP1, 0x18, - 4, 'S', 'U', 'B', 'B', GROUP1, 0x28, - 5, 'T', 'E', 'S', 'T', 'B', TEST, 0x84, - 5, 'X', 'C', 'H', 'G', 'B', XCHG, 0x86, - 4, 'X', 'O', 'R', 'B', GROUP1, 0x30, - 0 /* end of byte size ops */ -}; -# endif /* MNSIZE */ -#endif /* I80386 */ diff --git a/bin86-0.3/as/macro.c b/bin86-0.3/as/macro.c deleted file mode 100644 index 103ed08..0000000 --- a/bin86-0.3/as/macro.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * bin86/as/macro.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* macro.c - expand macros for assembler */ - -#include "const.h" -#include "type.h" -#include "globvar.h" -#include "scan.h" -#undef EXTERN -#define EXTERN -#include "macro.h" - -/* - Enter macro: stack macro and get its parameters. - Parameters form a linked list of null-terminated strings of form - next:string. The first string is the macro number in 4 bytes. -*/ - -PUBLIC void entermac(symptr) -struct sym_s *symptr; -{ - if (maclevel >= MAXMAC) - error(MACOV); - else if (macpar + 2 > macptop) - error(PAROV); /* no room for 0th param */ - /* (2 structs to fit it!) */ - else - { - char ch; - struct schain_s *param1; - register char *reglineptr; - register char *stringptr; - - ++maclevel; - (--macstak)->text = (char *) symptr->value_reg_or_op.value; - macstak->parameters = param1 = macpar; - param1->next = NULL; - *(stringptr = build_number(++macnum, 3, param1->string)) = 0; - macpar = (struct schain_s *) (stringptr + 1); - /* TODO: alignment */ - getsym(); - if (sym != LPAREN) - return; /* no other params */ - reglineptr = lineptr; - stringptr = macpar->string; - while (TRUE) - { - if (stringptr >= (char *) macptop) - { - symname = reglineptr; - error(PAROV); - return; - } - ch = *reglineptr++; - if (ch == '/') - /* escaped means no special meaning for slash, comma, paren */ - ch = *reglineptr++; - else if (ch == ',' || ch == ')') - { - if (stringptr >= (char *) macptop) - { - symname = reglineptr; - error(PAROV); /* no room for null */ - return; - } - *stringptr = 0; - param1->next = macpar; /* ptr from previous */ - (param1 = macpar)->next = NULL; - /* this goes nowhere */ - macpar = (struct schain_s *) (stringptr + 1); - /* but is finished OK - TODO align */ - stringptr = macpar->string; - if (ch == ')') - return; - continue; - } - if ((*stringptr++ = ch) == 0) - { - symname = reglineptr; - error(RPEXP); - return; - } - } - } -} - -/* MACRO pseudo-op */ - -PUBLIC void pmacro() -{ - bool_t saving; - bool_t savingc; - struct sym_s *symptr; - - saving = /* prepare for bad macro */ - savingc = FALSE; /* normally don't save comments */ - macload = TRUE; /* show loading */ - if (label != NULL) - error(ILLAB); - else if (sym != IDENT) - error(LABEXP); - else - { - symptr = gsymptr; - if (symptr->type & MNREGBIT) - error(LABEXP); - else if (symptr->type & LABIT || symptr->data & FORBIT) - error(RELAB); - else if (pass == 0 || symptr->type & REDBIT) - /* copy on pass 0, also pass 1 if redefined */ - { - saving = TRUE; - if (symptr->type & MACBIT) - symptr->type |= REDBIT; - else - symptr->type |= MACBIT; - symptr->data = UNDBIT; /* undefined till end */ - symptr->value_reg_or_op.value = (unsigned) heapptr; - /* beginning of store for macro */ - /* value s.b. (char *) */ - getsym_nolookup(); /* test for "C" */ - if (sym == IDENT && lineptr == symname + 1 && *symname == 'C') - savingc = TRUE; - } - } - while (TRUE) - { - skipline(); - listline(); - readline(); - if (!macload) - break; /* macload cleared to show eof */ - getsym_nolookup(); - if (sym == IDENT) - { - if (lineptr == symname + 4 && strncmp(symname, "MEND", 4) == 0) - break; - } - else if (sym != MACROARG) - { - if (!savingc) - continue; /* don't save comment */ - } - if (!saving) - continue; - { - register char *reglineptr; - register char *regheapptr; - - reglineptr = linebuf; - regheapptr = heapptr; - do - { - if (regheapptr >= heapend) - { - heapptr = regheapptr; - fatalerror(SYMOV); /* won't fit */ - } - } - while ((*regheapptr++ = *reglineptr++) != EOLCHAR); - heapptr = regheapptr; - } - } - macload = FALSE; - if (saving) - { - *heapptr++ = ETB; - symptr->data = 0; - } -} diff --git a/bin86-0.3/as/macro.h b/bin86-0.3/as/macro.h deleted file mode 100644 index 9fdee58..0000000 --- a/bin86-0.3/as/macro.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * bin86/as/macro.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* macro.h - global variables for macro expansion for assembler */ - -EXTERN bool_t macflag; /* inside macro flag */ -EXTERN bool_t macload; /* loading macro flag */ -EXTERN unsigned macnum; /* macro call counter */ - -EXTERN unsigned char maclevel; /* nesting level */ -EXTERN struct schain_s *macpar; /* parameter save buffer */ -EXTERN struct schain_s *macptop; /* top of param buffer (+1) */ -EXTERN struct macro_s *macstak; /* stack ptr */ diff --git a/bin86-0.3/as/mops.c b/bin86-0.3/as/mops.c deleted file mode 100644 index be4e0f6..0000000 --- a/bin86-0.3/as/mops.c +++ /dev/null @@ -1,2840 +0,0 @@ -/* - * bin86/as/mops.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* mops.c - handle pseudo-ops */ - -#include "const.h" -#include "type.h" -#include "globvar.h" -#include "opcode.h" -#include "scan.h" -#undef EXTERN -#define EXTERN -#include "address.h" - -#define is8bitadr(offset) ((offset_t) offset < 0x100) -#define is8bitsignedoffset(offset) ((offset_t) (offset) + 0x80 < 0x100) -#define pass2 pass - -FORWARD void mshort2 P((void)); -FORWARD reg_pt regchk P((void)); -FORWARD void reldata P((void)); - -#ifdef I80386 - -#define iswordadr(offset) ((offset_t) (offset) < 0x10000L) -#define iswordoffset(offset) ((offset_t) (offset) + 0x8000L < 0x10000L) -#define iswordorswordoffset(offset) ((offset_t) (offset) + 0xFFFFL < 0x1FFFEL) - -#define BYTE_SEGWORD 0x00 -#define isspecreg(r) ((r) >= CR0REG && (r) <= TR7REG) - -#define BASE_MASK 0x07 -#define BASE_SHIFT 0 -#define INDEX_MASK 0x38 -#define INDEX_SHIFT 3 -#define MOD_MASK 0xC0 -# define REG_MOD 0xC0 -# define MEM0_MOD 0x00 -# define MEM1_MOD 0x40 -# define MEM2_MOD 0x80 -#define REG_MASK 0x38 -#define REG_SHIFT 3 -#define RM_MASK 0x07 -#define RM_SHIFT 0 -# define D16_RM 0x06 -# define D32_RM 0x05 -# define SIB_NOBASE 0x05 -# define SIB_RM 0x04 -#define SREG_MASK 0x38 -#define SREG_SHIFT 3 -#define SS_MASK 0xC0 -#define SS_SHIFT 6 - -#define SEGMOV 0x04 -#define SIGNBIT 0x02 -#define TOREGBIT 0x02 -#define WORDBIT 0x01 - -PRIVATE opcode_t baseind16[] = -{ - 0x00, /* BP + BP, illegal */ - 0x00, /* BX + BP, illegal */ - 0x03, /* DI + BP */ - 0x02, /* SI + BP */ - 0x00, /* BP + BX, illegal */ - 0x00, /* BX + BX, illegal */ - 0x01, /* DI + BX */ - 0x00, /* SI + BX */ - 0x03, /* BP + DI */ - 0x01, /* BX + DI */ - 0x00, /* DI + DI, illegal */ - 0x00, /* SI + DI, illegal */ - 0x02, /* BP + SI */ - 0x00, /* BX + SI */ - 0x00, /* DI + SI, illegal */ - 0x00, /* SI + SI, illegal */ -}; - -PRIVATE opcode_t regbits[] = -{ - 0x05 << REG_SHIFT, /* BP */ - 0x03 << REG_SHIFT, /* BX */ - 0x07 << REG_SHIFT, /* DI */ - 0x06 << REG_SHIFT, /* SI */ - - 0x00 << REG_SHIFT, /* EAX */ - 0x05 << REG_SHIFT, /* EBP */ - 0x03 << REG_SHIFT, /* EBX */ - 0x01 << REG_SHIFT, /* ECX */ - 0x07 << REG_SHIFT, /* EDI */ - 0x02 << REG_SHIFT, /* EDX */ - 0x06 << REG_SHIFT, /* ESI */ - 0x04 << REG_SHIFT, /* ESP */ - - 0x00 << REG_SHIFT, /* AX */ - 0x01 << REG_SHIFT, /* CX */ - 0x02 << REG_SHIFT, /* DX */ - 0x04 << REG_SHIFT, /* SP */ - - 0x04 << REG_SHIFT, /* AH */ - 0x00 << REG_SHIFT, /* AL */ - 0x07 << REG_SHIFT, /* BH */ - 0x03 << REG_SHIFT, /* BL */ - 0x05 << REG_SHIFT, /* CH */ - 0x01 << REG_SHIFT, /* CL */ - 0x06 << REG_SHIFT, /* DH */ - 0x02 << REG_SHIFT, /* DL */ - - 0x01 << REG_SHIFT, /* CS */ - 0x03 << REG_SHIFT, /* DS */ - 0x00 << REG_SHIFT, /* ES */ - 0x04 << REG_SHIFT, /* FS */ - 0x05 << REG_SHIFT, /* GS */ - 0x02 << REG_SHIFT, /* SS */ - - 0x00 << REG_SHIFT, /* CR0 */ - 0x02 << REG_SHIFT, /* CR2 */ - 0x03 << REG_SHIFT, /* CR3 */ - - 0x00 << REG_SHIFT, /* DR0 */ - 0x01 << REG_SHIFT, /* DR1 */ - 0x02 << REG_SHIFT, /* DR2 */ - 0x03 << REG_SHIFT, /* DR3 */ - 0x06 << REG_SHIFT, /* DR6 */ - 0x07 << REG_SHIFT, /* DR7 */ - - 0x03 << REG_SHIFT, /* TR3 */ - 0x04 << REG_SHIFT, /* TR4 */ - 0x05 << REG_SHIFT, /* TR5 */ - 0x06 << REG_SHIFT, /* TR6 */ - 0x07 << REG_SHIFT, /* TR7 */ - - 0x00 << REG_SHIFT, /* ST(0) */ - 0x01 << REG_SHIFT, /* ST(1) */ - 0x02 << REG_SHIFT, /* ST(2) */ - 0x03 << REG_SHIFT, /* ST(3) */ - 0x04 << REG_SHIFT, /* ST(4) */ - 0x05 << REG_SHIFT, /* ST(5) */ - 0x06 << REG_SHIFT, /* ST(6) */ - 0x07 << REG_SHIFT, /* ST(7) */ -}; - -PRIVATE opsize_t regsize[] = -{ - 2, /* BP */ - 2, /* BX */ - 2, /* DI */ - 2, /* SI */ - - 4, /* EAX */ - 4, /* EBP */ - 4, /* EBX */ - 4, /* ECX */ - 4, /* EDI */ - 4, /* EDX */ - 4, /* ESI */ - 4, /* ESP */ - - 2, /* AX */ - 2, /* CX */ - 2, /* DX */ - 2, /* SP */ - - 1, /* AH */ - 1, /* AL */ - 1, /* BH */ - 1, /* BL */ - 1, /* CH */ - 1, /* CL */ - 1, /* DH */ - 1, /* DL */ - - 2, /* CS */ - 2, /* DS */ - 2, /* ES */ - 2, /* FS */ - 2, /* GS */ - 2, /* SS */ - - 4, /* CR0 */ - 4, /* CR2 */ - 4, /* CR3 */ - - 4, /* DR0 */ - 4, /* DR1 */ - 4, /* DR2 */ - 4, /* DR3 */ - 4, /* DR6 */ - 4, /* DR7 */ - - 4, /* TR3 */ - 4, /* TR4 */ - 4, /* TR5 */ - 4, /* TR6 */ - 4, /* TR7 */ - - 10, /* ST(0) */ - 10, /* ST(1) */ - 10, /* ST(2) */ - 10, /* ST(3) */ - 10, /* ST(4) */ - 10, /* ST(5) */ - 10, /* ST(6) */ - 10, /* ST(7) */ - - 0, /* NOREG */ -}; - -PRIVATE opcode_t regsegword[] = -{ - WORDBIT, /* BP */ - WORDBIT, /* BX */ - WORDBIT, /* DI */ - WORDBIT, /* SI */ - - WORDBIT, /* EAX */ - WORDBIT, /* EBP */ - WORDBIT, /* EBX */ - WORDBIT, /* ECX */ - WORDBIT, /* EDI */ - WORDBIT, /* EDX */ - WORDBIT, /* ESI */ - WORDBIT, /* ESP */ - - WORDBIT, /* AX */ - WORDBIT, /* CX */ - WORDBIT, /* DX */ - WORDBIT, /* SP */ - - BYTE_SEGWORD, /* AH */ - BYTE_SEGWORD, /* AL */ - BYTE_SEGWORD, /* BH */ - BYTE_SEGWORD, /* BL */ - BYTE_SEGWORD, /* CH */ - BYTE_SEGWORD, /* CL */ - BYTE_SEGWORD, /* DH */ - BYTE_SEGWORD, /* DL */ - - SEGMOV, /* CS */ - SEGMOV, /* DS */ - SEGMOV, /* ES */ - SEGMOV, /* FS */ - SEGMOV, /* GS */ - SEGMOV, /* SS */ - - 0x20, /* CR0 */ - 0x20, /* CR2 */ - 0x20, /* CR3 */ - - 0x21, /* DR0 */ - 0x21, /* DR1 */ - 0x21, /* DR2 */ - 0x21, /* DR3 */ - 0x21, /* DR6 */ - 0x21, /* DR7 */ - - 0x24, /* TR3 */ - 0x24, /* TR4 */ - 0x24, /* TR5 */ - 0x24, /* TR6 */ - 0x24, /* TR7 */ - - 0x00, /* ST(0) */ - 0x00, /* ST(1) */ - 0x00, /* ST(2) */ - 0x00, /* ST(3) */ - 0x00, /* ST(4) */ - 0x00, /* ST(5) */ - 0x00, /* ST(6) */ - 0x00, /* ST(7) */ - - 0x00, /* NOREG */ -}; - -PRIVATE opcode_t rm[] = -{ - 0x05, /* BP */ - 0x03, /* BX */ - 0x07, /* DI */ - 0x06, /* SI */ - - 0x00, /* EAX */ - 0x05, /* EBP */ - 0x03, /* EBX */ - 0x01, /* ECX */ - 0x07, /* EDI */ - 0x02, /* EDX */ - 0x06, /* ESI */ - 0x04, /* ESP */ - - 0x00, /* AX */ - 0x01, /* CX */ - 0x02, /* DX */ - 0x04, /* SP */ - - 0x04, /* AH */ - 0x00, /* AL */ - 0x07, /* BH */ - 0x03, /* BL */ - 0x05, /* CH */ - 0x01, /* CL */ - 0x06, /* DH */ - 0x02, /* DL */ - - 0x01, /* CS */ - 0x03, /* DS */ - 0x00, /* ES */ - 0x04, /* FS */ - 0x05, /* GS */ - 0x02, /* SS */ - - 0x00, /* CR0 */ - 0x00, /* CR2 */ - 0x00, /* CR3 */ - - 0x00, /* DR0 */ - 0x00, /* DR1 */ - 0x00, /* DR2 */ - 0x00, /* DR3 */ - 0x00, /* DR6 */ - 0x00, /* DR7 */ - - 0x00, /* TR3 */ - 0x00, /* TR4 */ - 0x00, /* TR5 */ - 0x00, /* TR6 */ - 0x00, /* TR7 */ - - 0x00, /* ST(0) */ - 0x00, /* ST(1) */ - 0x00, /* ST(2) */ - 0x00, /* ST(3) */ - 0x00, /* ST(4) */ - 0x00, /* ST(5) */ - 0x00, /* ST(6) */ - 0x00, /* ST(7) */ - - 0x04, /* null index reg for sib only */ -}; - -PRIVATE opcode_t rmfunny[] = -{ - 0x06, /* BP */ - 0x07, /* BX */ - 0x05, /* DI */ - 0x04, /* SI */ -}; - -PRIVATE opcode_t segoverride[] = -{ - 0x2E, /* CS */ - 0x3E, /* DS */ - 0x26, /* ES */ - 0x64, /* FS */ - 0x65, /* GS */ - 0x36, /* SS */ -}; - -PRIVATE opcode_t ss[] = /* scale to ss bits */ -{ - 0x00, /* x0, illegal */ - 0x00 << SS_SHIFT, /* x1 */ - 0x01 << SS_SHIFT, /* x2 */ - 0x00, /* x3, illegal */ - 0x02 << SS_SHIFT, /* x4 */ - 0x00, /* x5, illegal */ - 0x00, /* x6, illegal */ - 0x00, /* x7, illegal */ - 0x03 << SS_SHIFT, /* x8 */ -}; - -PRIVATE unsigned char calljmp_kludge; -PRIVATE opcode_t direction; -PRIVATE bool_t fpreg_allowed; -PRIVATE opcode_t segword; -/* - Values of segword: - BYTE_SEGWORD for byte ea's. - SEGMOV for segment registers - opcode for special registers - WORDBIT for other word and dword ea's -*/ - -PRIVATE struct ea_s source; -PRIVATE struct ea_s source2; -PRIVATE struct ea_s target; - -FORWARD void Eb P((struct ea_s *eap)); -FORWARD void Ew P((struct ea_s *eap)); -FORWARD void Ev P((struct ea_s *eap)); -FORWARD void Ex P((struct ea_s *eap)); -FORWARD void Gw P((struct ea_s *eap)); -FORWARD void Gv P((struct ea_s *eap)); -FORWARD void Gx P((struct ea_s *eap)); -FORWARD void buildea P((struct ea_s *eap)); -FORWARD void buildfloat P((void)); -FORWARD void buildfreg P((void)); -FORWARD void buildimm P((struct ea_s *eap, bool_pt signflag)); -FORWARD void buildregular P((void)); -FORWARD void buildsegword P((struct ea_s *eap)); -FORWARD void buildunary P((opcode_pt opc)); -FORWARD opsize_pt displsize P((struct ea_s *eap)); -FORWARD reg_pt fpregchk P((void)); -FORWARD bool_pt getaccumreg P((struct ea_s *eap)); -FORWARD void getbinary P((void)); -FORWARD bool_pt getdxreg P((struct ea_s *eap)); -FORWARD void getea P((struct ea_s *eap)); -FORWARD void getimmed P((struct ea_s *eap, count_t immcount)); -FORWARD void getindirect P((struct ea_s *eap)); -FORWARD void getshift P((struct ea_s *eap)); -FORWARD reg_pt indregchk P((reg_pt matchreg)); -FORWARD void kgerror P((error_pt errnum)); -FORWARD void lbranch P((unsigned backamount)); -FORWARD void notbytesize P((struct ea_s *eap)); -FORWARD void notimmed P((struct ea_s *eap)); -FORWARD void notindirect P((struct ea_s *eap)); -FORWARD void notsegorspecreg P((struct ea_s *eap)); -FORWARD void yesimmed P((struct ea_s *eap)); -FORWARD void yes_samesize P((void)); - -PRIVATE void Eb(eap) -register struct ea_s *eap; -{ - Ex(eap); - if (eap->size != 0x1) - { -#ifndef NODEFAULTSIZE - if (eap->size == 0x0) - eap->size = 0x1; - else -#endif - kgerror(ILL_SIZE); - } -} - -PRIVATE void Ew(eap) -register struct ea_s *eap; -{ - Ex(eap); - if (eap->size != 0x2) - { -#ifndef NODEFAULTSIZE - if (eap->size == 0x0) - eap->size = 0x2; - else -#endif - kgerror(ILL_SIZE); - } -} - -PRIVATE void Ev(eap) -register struct ea_s *eap; -{ - Ex(eap); - notbytesize(eap); -} - -PRIVATE void Ex(eap) -register struct ea_s *eap; -{ - getea(eap); - notimmed(eap); - notsegorspecreg(eap); -} - -PRIVATE void Gd(eap) -register struct ea_s *eap; -{ - Gx(eap); - if (eap->size != 0x4) - kgerror(ILL_SIZE); -} - -PRIVATE void Gw(eap) -register struct ea_s *eap; -{ - Gx(eap); - if (eap->size != 0x2) - kgerror(ILL_SIZE); -} - -PRIVATE void Gv(eap) -register struct ea_s *eap; -{ - Gx(eap); - notbytesize(eap); -} - -PRIVATE void Gx(eap) -register struct ea_s *eap; -{ - Ex(eap); - notindirect(eap); -} - -PRIVATE void buildea(eap) -register struct ea_s *eap; -{ - opsize_t asize; - - ++mcount; - lastexp = eap->displ; - if (eap->indcount == 0x0) - postb = REG_MOD | rm[eap->base]; - else - { - if (eap->base == NOREG) - { - if (eap->index == NOREG) - { - if ((asize = displsize(eap)) > 0x2) - postb = D32_RM; - else - postb = D16_RM; - } - else - { - asize = 0x4; - postb = SIB_NOBASE; /* for sib later */ - } - } - else - { - if (eap->base > MAX16BITINDREG) - { - asize = 0x4; - postb = rm[eap->base]; - } - else - { - asize = 0x2; - if (!(lastexp.data & UNDBIT) && - !iswordorswordoffset(lastexp.offset)) - error(ABOUNDS); - if (eap->index == NOREG) - postb = rmfunny[eap->base]; - else if (eap->base <= MAX16BITINDREG) - postb = baseind16[eap->base + 0x4 * eap->index]; - } - } - if (asize != defsize) - aprefix = 0x67; - if (eap->base == NOREG) - mcount += asize; - else if (lastexp.data & (FORBIT | RELBIT | UNDBIT) || - !is8bitsignedoffset(lastexp.offset)) - { - postb |= MEM2_MOD; - mcount += asize; - } - else if (lastexp.offset != 0x0 || - eap->base == BPREG && eap->index == NOREG || - eap->base == EBPREG) - { - postb |= MEM1_MOD; - ++mcount; - } - if (asize > 0x2 && (eap->base == ESPREG || eap->index != NOREG)) - { - sib = ss[eap->scale] | - (rm[eap->index] << INDEX_SHIFT) | - (postb & RM_MASK); - postb = (postb & MOD_MASK) | SIB_RM; - ++mcount; - } - } -} - -PRIVATE void buildfloat() -{ - if (mcount != 0x0) - { - buildea(&source); - oprefix = 0x0; - postb |= (opcode & 0x07) << REG_SHIFT; - opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4); - } -} - -PRIVATE void buildfreg() -{ - mcount += 0x2; - oprefix = 0x0; - postb = REG_MOD | ((opcode & 0x07) << REG_SHIFT) | (target.base - ST0REG); - opcode = ESCAPE_OPCODE_BASE | ((opcode & 0x70) >> 0x4); -} - -PRIVATE void buildimm(eap, signflag) -register struct ea_s *eap; -bool_pt signflag; -{ - immadr = eap->displ; - immcount = eap->size; - if (!(immadr.data & (FORBIT | RELBIT | UNDBIT))) - { - if (immcount == 0x1) - { - if ((offset_t) (immadr.offset + 0x80) >= 0x180) - datatoobig(); - } - else if (signflag && is8bitsignedoffset(immadr.offset)) - { - opcode |= SIGNBIT; - immcount = 0x1; - } - else if (immcount == 0x2) - { - if ((offset_t) (immadr.offset + 0x8000L) >= 0x18000L) - datatoobig(); - } - } -} - -PRIVATE void buildregular() -{ - if (mcount != 0x0) - { - buildea(&target); - postb |= regbits[source.base]; - } -} - -/* Check size and build segword. */ - -PRIVATE void buildsegword(eap) -register struct ea_s *eap; -{ - if (eap->size == 0x0) -#ifdef NODEFAULTSIZE - kgerror(SIZE_UNK); -#else - eap->size = defsize; -#endif - if (eap->indcount != 0x0 || eap->base == NOREG) - { - segword = WORDBIT; - if (eap->size == 0x1) - segword = BYTE_SEGWORD; - } - else - segword = regsegword[eap->base]; -} - -PRIVATE void buildunary(opc) -opcode_pt opc; -{ - if (mcount != 0x0) - { - buildea(&target); - postb |= opcode; - opcode = opc; - } -} - -PRIVATE opsize_pt displsize(eap) -register struct ea_s *eap; -{ - opsize_t asize; - - asize = defsize; - if (!(eap->displ.data & UNDBIT)) - { - if (asize > 0x2) - { - if (!(eap->displ.data & (FORBIT | RELBIT)) && - iswordadr(eap->displ.offset)) - asize = 0x2; - } - else if (!iswordorswordoffset(eap->displ.offset)) - /* should really use iswordadr() */ - /* but compiler generates signed offsets */ - { - if (!(eap->displ.data & (FORBIT | RELBIT))) - asize = 0x4; - else if (pass2) - error(ABOUNDS); - } - } - return asize; -} - -PRIVATE reg_pt fpregchk() -{ - reg_pt fpreg; - - fpreg_allowed = TRUE; - fpreg = regchk(); - fpreg_allowed = FALSE; - if (fpreg != ST0REG) - return NOREG; - getsym(); - if (sym == LPAREN) - { - getsym(); - if (sym != INTCONST || (unsigned) number >= 0x8) - error(ILL_FP_REG); - else - { - fpreg += number; - getsym(); - if (sym != RPAREN) - error(RPEXP); - else - getsym(); - } - } - return fpreg; -} - -PRIVATE bool_pt getaccumreg(eap) -register struct ea_s *eap; -{ - if ((eap->base = regchk()) != AXREG && eap->base != ALREG - && eap->base != EAXREG) - return FALSE; - getsym(); - if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize) - oprefix = 0x66; - return TRUE; -} - -/* - Get binary ea's in target & source (flipped if direction is set). - Put size in source if not already. - Initialise direction, segword, bump mcount. -*/ - -PRIVATE void getbinary() -{ - ++mcount; - getea(&target); - if (target.indcount == 0x0 && target.base == NOREG) - { - error(ILL_IMM_MODE); - target.base = AXREG; - target.size = defsize; - } - getcomma(); - getea(&source); - if (source.size == 0x0) - source.size = target.size; - else if (target.size != 0x0 && target.size != source.size) - { - kgerror(MISMATCHED_SIZE); - return; - } - if (source.indcount == 0x0 && regsegword[target.base] < SEGMOV) - direction = 0x0; - else if (target.indcount == 0x0 && regsegword[source.base] < SEGMOV) - { - struct ea_s swap; - - direction = TOREGBIT; - swap = source; - source = target; - target = swap; - } - else if (target.indcount != 0x0) - { - kgerror(ILL_IND_TO_IND); - return; - } - else - { - kgerror(ILL_SEG_REG); - return; - } - buildsegword(&source); -} - -PRIVATE bool_pt getdxreg(eap) -register struct ea_s *eap; -{ - if ((eap->base = regchk()) != DXREG) - return FALSE; - getsym(); - return TRUE; -} - -/* parse effective address */ - -/* - Syntax is restrictive in that displacements must be in the right spots - and will not be added up. - - optional size-type prefix, which is - BYTE - BYTE PTR - WORD - WORD PTR - DWORD - DWORD PTR - PTR - reg - segreg - [scaled index] - where scaled index = - indreg - indreg*scale - indreg+indreg - indreg+indreg*scale - [scaled index+displ] - [scaled index-displ] - optional-immediate-prefix displ[scaled index] - [displ] - optional-imediate-prefix displ - (scaled index) -- anachronism - optional-imediate-prefix displ(scaled index) -- anachronism -*/ - -PRIVATE void getea(eap) -register struct ea_s *eap; -{ - bool_t leading_displ; - bool_t leading_immed; - register struct sym_s *symptr; - - leading_immed = leading_displ = lastexp.data = eap->indcount - = lastexp.offset = 0x0; - eap->index = eap->base = NOREG; - eap->scale = 0x1; - eap->size = mnsize; /* 0x1 for byte ops, else 0x0 */ - - if (sym == IDENT) - { - if ((symptr = gsymptr)->type & MNREGBIT) - { - if (symptr->data & SIZEBIT) - { - getsym(); - if (symptr->value_reg_or_op.op.opcode == 0x0) - eap->indcount = 0x2 - calljmp_kludge; - else - { - if (eap->size != 0x0) - { - if (eap->size != symptr->value_reg_or_op.op.opcode) - error(MISMATCHED_SIZE); - } - else - eap->size = symptr->value_reg_or_op.op.opcode; - if (eap->size > 0x1 && eap->size != defsize) - oprefix = 0x66; - if (sym == IDENT && - (symptr = gsymptr)->type & MNREGBIT && - symptr->data & SIZEBIT && - symptr->value_reg_or_op.op.routine == PTROP) - { - getsym(); - eap->indcount = 0x2 - calljmp_kludge; - } - } - } - } - if (!(symptr->type & (LABIT | MACBIT | MNREGBIT | VARBIT))) - symptr->data |= FORBIT; /* show seen in advance */ - } - if ((eap->base = regchk()) != NOREG) - { - getsym(); - if (eap->indcount != 0x0) - { - error(ILL_IND_PTR); - eap->indcount = 0x0; - } - if (eap->size != 0x0 && eap->size != regsize[eap->base]) - error(MISMATCHED_SIZE); - if ((eap->size = regsize[eap->base]) > 0x1 && eap->size != defsize) - oprefix = 0x66; - eap->displ = lastexp; - return; - } - if (sym != lindirect) - { - if (sym == IMMEDIATE || sym == STAR) - { - /* context-sensitive, STAR means signed immediate here */ - leading_immed = TRUE; - getsym(); - } - leading_displ = TRUE; - expres(); - eap->displ = lastexp; - } - if (sym == lindirect) - { - getsym(); - eap->indcount = 0x2 - calljmp_kludge; - if ((eap->base = indregchk(NOREG)) != NOREG) - { - if (eap->indcount == 0x0 && leading_displ) - error(IND_REQ); - getsym(); - if (sym == ADDOP) - { - getsym(); - if ((eap->index = indregchk(eap->base)) != NOREG) - getsym(); - else - { - if (eap->indcount == 0x0) - error(IND_REQ); - if (leading_displ) - error(REPEATED_DISPL); - expres(); /* this eats ADDOP, SUBOP, MULOP */ - } - } - if (sym == STAR) - { - /* context-sensitive, STAR means scaled here*/ - if (eap->index == NOREG && eap->base == ESPREG) - { - error(INDEX_REG_EXP); - eap->base = EAXREG; - } - getsym(); - factor(); - chkabs(); - if (!(lastexp.data & UNDBIT) && lastexp.offset != 0x1) - { - if (eap->base <= MAX16BITINDREG || - lastexp.offset != 0x2 && lastexp.offset != 0x4 && - lastexp.offset != 0x8) - error(ILL_SCALE); - else - { - eap->scale = lastexp.offset; - if (eap->index == NOREG) - { - eap->index = eap->base; - eap->base = NOREG; - } - } - } - lastexp.data = lastexp.offset = 0x0; - } - if ((sym == ADDOP || sym == SUBOP)) - { - if (eap->indcount == 0x0) - error(IND_REQ); - if (leading_displ) - error(REPEATED_DISPL); - expres(); - } - } - else - { - if (leading_displ) - error(REPEATED_DISPL); - expres(); - } - if (sym != rindirect) - error(rindexp); - else - getsym(); - } - else if (!leading_immed && idefsize <= 0x2) - eap->indcount = 0x1; /* compatibility kludge */ - if (!leading_displ) - eap->displ = lastexp; -} - -PRIVATE void getimmed(eap, immcount) -struct ea_s *eap; -count_t immcount; -{ - getea(eap); - yesimmed(eap); - if (mcount != 0x0) - { - eap->size = immcount; - buildimm(eap, FALSE); - } -} - -PRIVATE void getindirect(eap) -register struct ea_s *eap; -{ - getea(eap); - if (eap->indcount == 0x0) - kgerror(IND_REQ); -} - -PRIVATE void getshift(eap) -register struct ea_s *eap; -{ - getcomma(); - getea(eap); - if (eap->base != CLREG) - yesimmed(eap); -} - -/* - Check if current symbol is a compatible index register. - Generate error if it is a reg but not a compatible index. - Return register number (adjusted if necessary to a legal index) or NOREG. -*/ - -PRIVATE reg_pt indregchk(matchreg) -reg_pt matchreg; -{ - reg_pt reg; - - if ((reg = regchk()) != NOREG) - { - switch (matchreg) - { - case BPREG: - case BXREG: - if (reg != DIREG && reg != SIREG) - { - reg = SIREG; - error(INDEX_REG_EXP); - } - break; - case DIREG: - case SIREG: - if (reg != BPREG && reg != BXREG) - { - reg = BXREG; - error(INDEX_REG_EXP); - } - break; - case NOREG: - break; - default: - if (reg <= MAX16BITINDREG || reg == ESPREG) - { - reg = EAXREG; - error(INDEX_REG_EXP); - } - break; - } - if (reg > MAXINDREG && calljmp_kludge == 0x0) - { - if (matchreg != NOREG) - reg = EAXREG; - else - reg = BXREG; - error(INDEX_REG_EXP); - } - } - return reg; -} - -PRIVATE void kgerror(errnum) -error_pt errnum; -{ - error(errnum); - sprefix = oprefix = aprefix = mcount = 0x0; -} - -PRIVATE void lbranch(backamount) -unsigned backamount; -{ - mcount += defsize + 0x1; - if (pass2) - { - reldata(); - if (!(lastexp.data & (RELBIT | UNDBIT))) - { - lastexp.offset = lastexp.offset - lc - lcjump; - if (backamount != 0x0 && !(lastexp.data & IMPBIT) && - lastexp.offset + backamount < 0x80 + backamount) - error(SHORTB); /* -0x8? to 0x7F, warning */ - } - } -} - -/* BCC (long branches emulated by short branch over & long jump) */ - -PUBLIC void mbcc() -{ - getea(&target); - if (target.indcount >= 0x2 || target.base != NOREG) - kgerror(REL_REQ); - else - { - if (defsize != 0x2) - { - page = PAGE1_OPCODE; - ++mcount; - opcode += 0x10; - lbranch(0x84); - } - else - { - aprefix = opcode ^ 0x1; /* kludged storage for short branch - over */ - oprefix = defsize + 0x1; - mcount += 0x2; - opcode = JMP_OPCODE; - lbranch(0x83); - mcount -= 0x2; - } - } -} - -/* bswap r32 */ - -PUBLIC void mbswap() -{ - ++mcount; - Gd(&target); - opcode |= rm[target.base]; -} - -/* BR, CALL, J, JMP */ - -PUBLIC void mcall() -{ - opcode_pt far; - bool_t indirect; - register struct sym_s *symptr; - - far = 0x0; - if (sym == IDENT && (symptr = gsymptr)->type & MNREGBIT && - symptr->data & SIZEBIT && - symptr->value_reg_or_op.op.routine == FAROP) - { - far = 0x8; - getsym(); - } - indirect = FALSE; - if (asld_compatible && idefsize <= 0x2) - { - calljmp_kludge = 0x2; - if (sym == INDIRECT) - { - calljmp_kludge = 0x0; - indirect = TRUE; - getsym(); - } - } - getea(&target); - if (indirect && target.indcount == 0x1) - target.indcount = 0x2; - calljmp_kludge = 0x0; - if (sym == COLON) - { - if (opcode == JMP_SHORT_OPCODE) - opcode = JMP_OPCODE; - ++mcount; - yesimmed(&target); - getsym(); - getea(&source); - yesimmed(&source); - if (mcount != 0x0) - { - if (opcode == JMP_OPCODE) - opcode = 0xEA; - else - opcode = 0x9A; - lastexp = source.displ; - if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) && - defsize == 0x2 && - (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L) - datatoobig(); - mcount += defsize; - target.size = 0x2; - buildimm(&target, FALSE); - } - } - else if (target.indcount >= 0x2 || target.base != NOREG) - { - ++mcount; - notsegorspecreg(&target); - if (target.indcount == 0) - notbytesize(&target); - if (mcount != 0x0) - { - if (opcode == JMP_SHORT_OPCODE) - opcode = JMP_OPCODE; - buildea(&target); - if (opcode == JMP_OPCODE) - opcode = 0x20; - else - opcode = 0x10; - postb |= opcode + far; - opcode = 0xFF; - } - } - else if (opcode == JMP_SHORT_OPCODE) - { - if (jumps_long) - { - opcode = JMP_OPCODE; - lbranch(0x83); - } - else - { - lastexp = target.displ; - if (lastexp.data & IMPBIT) - { - error(NONIMPREQ); - lastexp.data = FORBIT | UNDBIT; - } - mshort2(); - } - } - else - lbranch(opcode == JMP_OPCODE ? 0x83 : 0x0); -} - -/* CALLI, JMPI */ - -PUBLIC void mcalli() -{ - bool_t indirect; - - ++mcount; - indirect = FALSE; - if (sym == INDIRECT) - { - getsym(); - indirect = TRUE; - } - getea(&target); - if (target.indcount >= 0x2 || target.base != NOREG) - indirect = TRUE; - if (indirect) - { - buildea(&target); - if (opcode == 0xEA) - opcode = 0x28; - else - opcode = 0x18; - postb |= opcode; - opcode = 0xFF; - } - else - { - getcomma(); - getea(&source); - yesimmed(&source); - if (mcount != 0x0) - { - lastexp = target.displ; - if (!(lastexp.data & (FORBIT | RELBIT | UNDBIT)) && - defsize == 0x2 && - (offset_t) (lastexp.offset + 0x8000L) >= 0x18000L) - datatoobig(); - mcount += defsize; - source.size = 0x2; - buildimm(&source, FALSE); - } - } -} - -/* DIV, IDIV, MUL */ - -PUBLIC void mdivmul() -{ - if (getaccumreg(&source)) - { - ++mcount; - getcomma(); - Ex(&target); - yes_samesize(); - buildunary(0xF6 | regsegword[source.base]); - } - else - mnegnot(); -} - -/* ENTER */ - -PUBLIC void menter() -{ - ++mcount; - getimmed(&target, 0x2); - getcomma(); - getimmed(&source, 0x1); - if (mcount != 0x0) - { - mcount += 2; - lastexp = target.displ; /* getimmed(&source) wiped it out */ - } -} - -/* arpl r/m16,r16 (Intel manual opcode chart wrongly says EwRw) */ - -PUBLIC void mEwGw() -{ - ++mcount; - Ew(&target); - getcomma(); - Gw(&source); - oprefix = 0x0; - buildregular(); -} - -/* [cmpxchg xadd] [r/m8,r8 r/m16,r16, r/m32,r32] */ - -PUBLIC void mExGx() -{ - ++mcount; - Ex(&target); - getcomma(); - Gx(&source); - yes_samesize(); - opcode |= segword; - buildregular(); -} - -PUBLIC void mf_inher() -{ - mcount += 0x2; - postb = REG_MOD | (opcode & ~REG_MOD); - opcode = ESCAPE_OPCODE_BASE | (opcode >> 0x6); - if (opcode == ESCAPE_OPCODE_BASE) - opcode = ESCAPE_OPCODE_BASE | 0x6; /* fix up encoding of fcompp */ -} - -/* [fldenv fnsave fnstenv frstor] mem */ - -PUBLIC void mf_m() -{ - ++mcount; - getindirect(&source); - if (source.size != 0x0) - kgerror(ILL_SIZE); - buildfloat(); -} - -/* [fldcw fnstcw] mem2i */ - -PUBLIC void mf_m2() -{ - ++mcount; - getindirect(&source); - if (source.size != 0x0 && source.size != 0x2) - kgerror(ILL_SIZE); - buildfloat(); -} - -/* fnstsw [mem2i ax] */ - -PUBLIC void mf_m2_ax() -{ - if (getaccumreg(&target)) - { - if (target.base != AXREG) - kgerror(ILLREG); - else - { - opcode = 0x74; - target.base = ST0REG; /* fake, really ax */ - buildfreg(); - } - } - else - mf_m2(); -} - -/* [fiadd ficom ficomp fidiv fidivr fimul fist fisub fisubr] [mem2i mem4i] */ - -PUBLIC void mf_m2_m4() -{ - ++mcount; - getindirect(&source); - if (source.size == 0x0) - kgerror(SIZE_UNK); - else if (source.size == 0x2) - opcode |= 0x40; - else if (source.size != 0x4) - kgerror(ILL_SIZE); - buildfloat(); -} - -/* [fild fistp] [mem2i mem4i mem8i] */ - -PUBLIC void mf_m2_m4_m8() -{ - ++mcount; - getindirect(&source); - if (source.size == 0x0) - kgerror(SIZE_UNK); - else if (source.size == 0x2) - opcode |= 0x40; - else if (source.size == 0x8) - opcode |= 0x45; /* low bits 0 -> 5 and 3 -> 7 */ - else if (source.size != 0x4) - kgerror(ILL_SIZE); - buildfloat(); -} - -/* [fcom fcomp] [mem4r mem8r optional-st(i)] */ - -PUBLIC void mf_m4_m8_optst() -{ - if (sym == EOLSYM) - { - target.base = ST1REG; - buildfreg(); - } - else - mf_m4_m8_st(); -} - -/* [fadd fdiv fdivr fmul fsub fsubr] [mem4r mem8r st,st(i) st(i),st] */ - -PUBLIC void mf_m4_m8_stst() -{ - target.base = fpregchk(); - if (target.base != NOREG) - { - getcomma(); - source.base = fpregchk(); - if (source.base == NOREG) - { - error(FP_REG_REQ); - source.base = ST0REG; - } - if (target.base == ST0REG) - target.base = source.base; - else - { - if (source.base != ST0REG) - error(ILL_FP_REG_PAIR); - opcode |= 0x40; - if ((opcode & 0x07) >= 0x4) - opcode ^= 0x01; /* weird swap of fdiv/fdivr, fsub/fsubr */ - } - buildfreg(); - } - else - { - ++mcount; - getindirect(&source); - if (source.size == 0x0) - kgerror(SIZE_UNK); - else if (source.size == 0x8) - opcode |= 0x40; - else if (source.size != 0x4) - kgerror(ILL_SIZE); - buildfloat(); - } -} - -/* fst [mem4r mem8r st(i)] */ - -PUBLIC void mf_m4_m8_st() -{ - target.base = fpregchk(); - if (target.base != NOREG) - { - if (opcode == FST_ENCODED) - opcode |= 0x40; - buildfreg(); - } - else - { - ++mcount; - getindirect(&source); - if (source.size == 0x0) - kgerror(SIZE_UNK); - else if (source.size == 0x8) - opcode |= 0x40; - else if (source.size != 0x4) - kgerror(ILL_SIZE); - buildfloat(); - } -} - -/* [fld fstp] [mem4r mem8r mem10r st(i)] */ - -PUBLIC void mf_m4_m8_m10_st() -{ - target.base = fpregchk(); - if (target.base != NOREG) - { - if (opcode == FSTP_ENCODED) - opcode |= 0x40; - buildfreg(); - } - else - { - ++mcount; - getindirect(&source); - if (source.size == 0x0) - kgerror(SIZE_UNK); - else if (source.size == 0x8) - opcode |= 0x40; - else if (source.size == 0xA) - opcode |= 0x25; /* low bits 0 -> 5 and 3 -> 7 */ - else if (source.size != 0x4) - kgerror(ILL_SIZE); - buildfloat(); - } -} - -/* [fbld fbstp] mem10r */ - -PUBLIC void mf_m10() -{ - ++mcount; - getindirect(&source); - if (source.size != 0xA) - kgerror(ILL_SIZE); - buildfloat(); -} - -/* ffree st(i) */ - -PUBLIC void mf_st() -{ - target.base = fpregchk(); - if (target.base == NOREG) - kgerror(FP_REG_REQ); - buildfreg(); -} - -/* [fucom fucomp fxch] optional-st(i) */ - -PUBLIC void mf_optst() -{ - if (sym == EOLSYM) - { - target.base = ST1REG; - buildfreg(); - } - else - mf_st(); -} - -/* [faddp fdivp fdivrp fmulp fsubp fsubrp] st(i),st */ - -PUBLIC void mf_stst() -{ - target.base = fpregchk(); - if (target.base == NOREG) - { - kgerror(FP_REG_REQ); - return; - } - getcomma(); - source.base = fpregchk(); - if (source.base == NOREG) - { - kgerror(FP_REG_REQ); - return; - } - if (source.base != ST0REG) - { - kgerror(ILL_FP_REG); - return; - } - buildfreg(); -} - -PUBLIC void mf_w_inher() -{ - sprefix = WAIT_OPCODE; - mf_inher(); -} - -/* [fsave fstenv] mem */ - -PUBLIC void mf_w_m() -{ - sprefix = WAIT_OPCODE; - mf_m(); -} - -/* fstcw mem2i */ - -PUBLIC void mf_w_m2() -{ - sprefix = WAIT_OPCODE; - mf_m2(); -} - -/* fstsw [mem2i ax] */ - -PUBLIC void mf_w_m2_ax() -{ - sprefix = WAIT_OPCODE; - mf_m2_ax(); -} - -/* ADC, ADD, AND, CMP, OR, SBB, SUB, XOR */ - -PUBLIC void mgroup1() -{ - getbinary(); - notsegorspecreg(&source); - if (mcount != 0x0) - { - if (source.base == NOREG) - { - if (target.indcount == 0x0 && (target.base == ALREG || - target.base == AXREG || - target.base == EAXREG && - (source.displ.data & (FORBIT | RELBIT | UNDBIT) || - !is8bitsignedoffset(source.displ.offset)))) - { - opcode |= 0x04 | segword; - buildimm(&source, FALSE); - } - else - { - buildunary(0x80 | segword); - buildimm(&source, TRUE); - } - } - else - { - opcode |= direction | segword; - buildregular(); - } - } -} - -/* RCL, RCR, ROL, ROR, SAL, SAR, SHL, SHR */ - -PUBLIC void mgroup2() -{ - ++mcount; - Ex(&target); - buildsegword(&target); - getshift(&source); - if (mcount != 0x0) - { - buildunary(0xD0 | segword); - if (source.base == CLREG) - opcode |= 0x2; - else if (source.displ.offset != 0x1) - { - opcode -= 0x10; - source.size = 0x1; - buildimm(&source, FALSE); - } - } -} - -/* LLDT, LTR, SLDT, STR, VERR, VERW */ - -PUBLIC void mgroup6() -{ - ++mcount; - Ew(&target); - oprefix = 0x0; - buildunary(0x0); -} - -/* INVLPG, LGDT, LIDT, LMSW, SGDT, SIDT, SMSW */ - -PUBLIC void mgroup7() -{ - ++mcount; - if (opcode == 0x20 || opcode == 0x30) - { - Ew(&target); - oprefix = 0x0; - } - else - { - getindirect(&target); - oprefix = 0x0; - if (target.size != 0x0 && target.size != 0x6) - error(MISMATCHED_SIZE); /* XXX - size 6 wrong for INVLPG? */ - } - buildunary(0x1); -} - -/* BT, BTR, BTS, BTC */ - -PUBLIC void mgroup8() -{ - ++mcount; - Ev(&target); - getcomma(); - /* Gv or Ib */ - getea(&source); - notindirect(&source); - notsegorspecreg(&source); - if (mcount != 0x0) - { - if (source.base == NOREG) - { - buildunary(0xBA); - source.size = 0x1; - buildimm(&source, TRUE); - } - else - { - yes_samesize(); - opcode += 0x83; - buildregular(); - } - } -} - -/* BSF, BSR, LAR, LSL (Intel manual opcode chart wrongly says GvEw for L*) */ - -PUBLIC void mGvEv() -{ - ++mcount; - Gv(&source); - getcomma(); - Ev(&target); - yes_samesize(); - buildregular(); -} - -/* bound [r16,m16&16 r32,m32&32] */ - -PUBLIC void mGvMa() -{ - ++mcount; - Gv(&source); - getcomma(); - getindirect(&target); - yes_samesize(); - buildregular(); -} - -/* LDS, LES, LFS, LGS, LSS */ - -PUBLIC void mGvMp() -{ - ++mcount; - Gv(&source); - getcomma(); - getindirect(&target); - if (target.size != 0x0 && target.size != 0x2 + source.size) - error(MISMATCHED_SIZE); - buildregular(); -} - -/* IMUL */ - -PUBLIC void mimul() -{ - ++mcount; - Ex(&target); - if (sym != COMMA) - { - buildsegword(&target); - buildunary(0xF6 | segword); - return; - } - getcomma(); - notindirect(&target); - source = target; /* direction is swapped */ - getea(&target); - notsegorspecreg(&target); - yes_samesize(); - if (sym != COMMA && (target.indcount != 0x0 || target.base != NOREG)) - { - page = PAGE1_OPCODE; - ++mcount; - opcode = 0xAF; - buildregular(); - } - else - { - if (sym == COMMA) - { - getsym(); - getea(&source2); - yesimmed(&source2); - } - else - { - source2 = target; - target = source; - } - source2.size = target.size; - if (is8bitsignedoffset(source2.displ.offset)) - { - source2.size = 0x1; - opcode = 0x6B; - } - else - { - source2.size = target.size; - opcode = 0x69; - } - buildregular(); - if (mcount != 0x0) - buildimm(&source2, FALSE); - } -} - -/* IN */ - -PUBLIC void min() -{ - ++mcount; - if (opcode & WORDBIT) /* inw; ind not supported */ - mnsize = 0x2; - if (sym == EOLSYM && mnsize != 0x0) - target.size = mnsize; - else - { - if (getaccumreg(&target)) - { - if (mnsize != 0x0 && regsize[target.base] != mnsize) - error(MISMATCHED_SIZE); - getcomma(); - } - else - target.size = regsize[target.base = mnsize < 0x2 ? ALREG : AXREG]; - opcode |= regsegword[target.base]; - if (!getdxreg(&source)) - { - getimmed(&source, 0x1); - opcode -= 0x8; - } - } - if (target.size > 0x1 && target.size != defsize) - oprefix = 0x66; -} - -/* DEC, INC */ - -PUBLIC void mincdec() -{ - ++mcount; - Ex(&target); - buildsegword(&target); - if (target.indcount == 0x0 && segword == WORDBIT) - opcode |= 0x40 | rm[target.base]; - else - buildunary(0xFE | segword); -} - -/* CBW, CWD, CMPSW, INSW, IRET, LODSW, POPA, POPF, PUSHA, PUSHF */ -/* MOVSW, OUTSW, SCASW, STOSW */ - -PUBLIC void minher16() -{ - minher(); - if (defsize != 0x2) - oprefix = 0x66; -} - -/* CWDE, CDQ, CMPSD, INSD, IRETD, LODSD, POPAD, POPFD, PUSHAD, PUSHFD */ -/* MOVSD, OUTSD, SCASD, STOSD */ - -PUBLIC void minher32() -{ - minher(); - if (defsize != 0x4) - oprefix = 0x66; -} - -/* AAD, AAM */ - -PUBLIC void minhera() -{ - ++mcount; - if (sym == EOLSYM) - { - target.displ.offset = 0xA; - target.size = 0x1; - buildimm(&target, FALSE); - } - else - getimmed(&target, 0x1); -} - -/* INT */ - -PUBLIC void mint() -{ - ++mcount; - getimmed(&target, 0x1); - if (!(immadr.data & (FORBIT | RELBIT | UNDBIT)) && - (opcode_t) immadr.offset == 0x3) - { - immcount = 0x0; - opcode = 0xCC; - } -} - -/* JCC */ - -PUBLIC void mjcc() -{ - if (jumps_long && opcode < 0x80) /* above 0x80 means loop - not long */ - mbcc(); - else - mshort(); -} - -/* JCXZ, JECXZ */ - -PUBLIC void mjcxz() -{ - if (opcode != defsize) - { - aprefix = 0x67; - ++mcount; /* quick fix - mshort() needs to know */ - } - opcode = 0xE3; - mshort(); - if (aprefix != 0x0) - --mcount; /* quick fix - main routine bumps it again */ -} - -/* LEA */ - -PUBLIC void mlea() -{ - Gv(&source); /* back to front */ - getcomma(); - ++mcount; - getindirect(&target); - yes_samesize(); - buildregular(); -} - -/* MOV */ - -PUBLIC void mmov() -{ - getbinary(); - if (segword >= SEGMOV) - { - oprefix = 0x0; - notimmed(&source); - if (segword > SEGMOV) /* special reg */ - notindirect(&target); - } - if (mcount != 0x0) - { - if (target.base == NOREG && target.index == NOREG && - (source.base == ALREG || source.base == AXREG || - source.base == EAXREG)) - { - opcode = 0xA0 | (direction ^ TOREGBIT) | segword; - lastexp = target.displ; - if ((source.size = displsize(&target)) != defsize) - aprefix = 0x67; - mcount += source.size; - } - else if (source.base == NOREG) - { - if (target.indcount == 0x0) - opcode = 0xB0 | (segword << 0x3) | rm[target.base]; - else - { - buildea(&target); - opcode = 0xC6 | segword; - } - buildimm(&source, FALSE); - } - else - { - if (isspecreg(source.base)) - { - page = PAGE1_OPCODE; - ++mcount; - opcode = 0x0; - } - opcode |= direction | segword; - buildregular(); - } - } -} - -/* MOVSX, MOVZX */ - -PUBLIC void mmovx() -{ - ++mcount; - Gv(&source); - getcomma(); - Ex(&target); - if (target.size == 0x0) - kgerror(SIZE_UNK); - if (target.size > 0x2) - kgerror(ILL_SIZE); - oprefix = 0x0; - if (source.size != defsize) - oprefix = 0x66; - buildsegword(&target); - opcode |= segword; - buildregular(); -} - -/* NEG, NOT */ - -PUBLIC void mnegnot() -{ - ++mcount; - Ex(&target); - buildsegword(&target); - buildunary(0xF6 | segword); -} - -/* OUT */ - -PUBLIC void mout() -{ - ++mcount; - if (opcode & WORDBIT) /* outw; outd not supported */ - mnsize = 0x2; - if (sym == EOLSYM && mnsize != 0x0) - source.size = mnsize; - else - { - if (!getdxreg(&target)) - { - getimmed(&target, 0x1); - opcode -= 0x8; - } - if (sym == COMMA) - { - getsym(); - if (!getaccumreg(&source)) - kgerror(AL_AX_EAX_EXP); - else if (mnsize != 0x0 && regsize[source.base] != mnsize) - error(MISMATCHED_SIZE); - } - else - source.size = regsize[source.base = mnsize < 0x2 ? ALREG : AXREG]; - opcode |= regsegword[source.base]; - } - if (source.size > 0x1 && source.size != defsize) - oprefix = 0x66; -} - -/* POP, PUSH */ - -PUBLIC void mpushpop() -{ - opcode_t oldopcode; - - ++mcount; - getea(&target); - buildsegword(&target); - notbytesize(&target); - if ((oldopcode = opcode) == POP_OPCODE) - { - notimmed(&target); - if (target.base == CSREG) - kgerror(ILL_SEG_REG); - } - if (mcount != 0x0) - { - if (target.indcount == 0x0) - { - if (segword == SEGMOV) - { - switch (target.base) - { - case CSREG: - opcode = 0x0E; - break; - case DSREG: - opcode = 0x1E; - break; - case ESREG: - opcode = 0x06; - break; - case SSREG: - opcode = 0x16; - break; - case FSREG: - opcode = 0xA0; - page = PAGE1_OPCODE; - ++mcount; - break; - case GSREG: - opcode = 0xA8; - page = PAGE1_OPCODE; - ++mcount; - break; - } - if (oldopcode == POP_OPCODE) - ++opcode; - } - else if (target.base != NOREG) - { - opcode = 0x50 | rm[target.base]; - if (oldopcode == POP_OPCODE) - opcode |= 0x8; - } - else - { - opcode = 0x68; - if (oldopcode == POP_OPCODE) - ++opcode; - buildimm(&target, TRUE); - } - } - else - { - buildea(&target); - if (oldopcode == PUSH_OPCODE) - postb |= 0x6 << REG_SHIFT; - } - } -} - -/* RET, RETF */ - -PUBLIC void mret() -{ - ++mcount; - if (sym != EOLSYM) - { - --opcode; - getimmed(&target, 0x2); - } -} - -/* SEG CS/DS/ES/FS/GS/SS */ - -PUBLIC void mseg() -{ - reg_pt reg; - - if (regsegword[reg = regchk()] != SEGMOV) - error(SEG_REG_REQ); - else - { - getsym(); - ++mcount; - opcode = (segoverride - CSREG)[reg]; - } -} - -/* SETCC */ - -PUBLIC void msetcc() -{ - ++mcount; - Eb(&target); - if (mcount != 0x0) - buildea(&target); -} - -/* SHLD, SHRD */ - -PUBLIC void mshdouble() -{ - ++mcount; - Ev(&target); - getcomma(); - Gv(&source); - yes_samesize(); - buildregular(); - getshift(&source2); - lastexp = target.displ; /* getshift() wiped it out */ - if (mcount != 0x0) - { - if (source2.base == CLREG) - opcode |= 0x1; - else - { - source2.size = 0x1; - buildimm(&source2, FALSE); - } - } -} - -/* - TEST - Similar to the regular group1 operators. - It does not allow the sign extended immediate byte forms - and does not use the relevant direction bit. -*/ - -PUBLIC void mtest() -{ - getbinary(); - notsegorspecreg(&source); - if (source.base == NOREG) - { - if (mcount != 0x0) - { - if (target.indcount == 0x0 - && (target.base == ALREG || target.base == AXREG - || target.base == EAXREG)) - opcode = 0xA8 | segword; - else - { - buildea(&target); - opcode = 0xF6 | segword; - } - } - buildimm(&source, FALSE); - } - else - { - opcode |= segword; - buildregular(); - } -} - -/* - XCHG - Similar to the regular group1 operators. - It does not allow any of the immediate forms - and does not use the irrelevant direction bit. -*/ - -PUBLIC void mxchg() -{ - getbinary(); - notimmed(&source); - notsegorspecreg(&source); - if (target.indcount == 0x0) - { - if (target.base == AXREG || target.base == EAXREG) - { - opcode = 0x90 + rm[source.base]; - return; - } - if (source.base == AXREG || source.base == EAXREG) - { - opcode = 0x90 + rm[target.base]; - return; - } - } - opcode |= segword; - buildregular(); -} - -PRIVATE void notbytesize(eap) -register struct ea_s *eap; -{ - if (eap->size == 0x1) - kgerror(ILL_SIZE); -} - -PRIVATE void notimmed(eap) -register struct ea_s *eap; -{ - if (eap->indcount == 0x0 && eap->base == NOREG) - kgerror(ILL_IMM_MODE); -} - -PRIVATE void notindirect(eap) -register struct ea_s *eap; -{ - if (eap->indcount != 0x0) - kgerror(ILL_IND); -} - -PRIVATE void notsegorspecreg(eap) -register struct ea_s *eap; -{ - if (regsegword[eap->base] >= SEGMOV) - kgerror(ILLREG); -} - -PRIVATE void yesimmed(eap) -register struct ea_s *eap; -{ - if (eap->indcount == 0x1) - eap->indcount = 0x0; - if (eap->indcount != 0x0 || eap->base != NOREG) - kgerror(IMM_REQ); -} - -PRIVATE void yes_samesize() -{ - if (target.size == 0x0) - target.size = source.size; - else if (source.size != 0x0 && target.size != source.size) - kgerror(MISMATCHED_SIZE); -} - -#endif /* I80386 */ - -#ifdef MC6809 - -/* 6809 opcode constants */ - -/* bits for indexed addressing */ - -#define INDIRECTBIT 0x10 -#define INDEXBIT 0x80 /* except 5 bit offset */ -#define PCRELBIT 0x04 /* PC relative (in certain cases) */ -#define RRBITS 0x60 /* register select bits */ - -PRIVATE opcode_t rrindex[] = /* register and index bits for indexed adr */ -{ - 0x60 | INDEXBIT, /* S */ - 0x40 | INDEXBIT, /* U */ - 0x00 | INDEXBIT, /* X */ - 0x20 | INDEXBIT, /* Y */ - PCRELBIT | INDEXBIT, /* PC */ -}; - -PRIVATE opcode_t pushpull[] = /* push/pull codes */ -{ - 0x40, /* S */ - 0x40, /* U */ - 0x10, /* X */ - 0x20, /* Y */ - 0x80, /* PC */ - 0x02, /* A */ - 0x04, /* B */ - 0x01, /* CC */ - 0x08, /* DP */ - 0x06, /* D */ -}; - -PRIVATE opcode_t tfrexg1[] = /* transfer/exchange codes for source reg */ -{ - 0x40, /* S */ - 0x30, /* U */ - 0x10, /* X */ - 0x20, /* Y */ - 0x50, /* PC */ - 0x80, /* A */ - 0x90, /* B */ - 0xA0, /* CC */ - 0xB0, /* DP */ - 0x00, /* D */ -}; - -PRIVATE opcode_t tfrexg2[] = /* transfer/exchange codes for target reg */ -{ - 0x04, /* S */ - 0x03, /* U */ - 0x01, /* X */ - 0x02, /* Y */ - 0x05, /* PC */ - 0x08, /* A */ - 0x09, /* B */ - 0x0A, /* CC */ - 0x0B, /* DP */ - 0x00, /* D */ -}; - -FORWARD void checkpostinc P((void)); -FORWARD void doaltind P((void)); -FORWARD void do1altind P((void)); -FORWARD void fixupind P((void)); -FORWARD void getindexnopost P((void)); -FORWARD void inderror P((error_pt errnum)); -FORWARD reg_pt indreg P((reg_pt maxindex)); -FORWARD void predec1 P((void)); -FORWARD void sustack P((reg_pt stackreg)); - -PRIVATE void checkpostinc() -{ - if (sym == ADDOP) - { - if (postb & INDIRECTBIT) - inderror(ILLMOD); /* single-inc indirect illegal */ - else - { - lastexp.offset &= 0xFF00; /* for printing if postbyte is 0: ,X+ */ - getsym(); - } - } - else if (sym == POSTINCOP) - { - postb |= 0x1; - getsym(); - } - else - postb |= 0x4; - fixupind(); -} - -/* common code for all-mode ops, alterable-mode ops, indexed ops */ - -PRIVATE void doaltind() -{ - mcount += 0x2; - if (sym == LBRACKET) - { - postb = INDIRECTBIT; - getsym(); - do1altind(); - if (sym != RBRACKET) - error(RBEXP); - } - else - do1altind(); -} - -PRIVATE void do1altind() -{ - bool_t byteflag; /* set if direct or short indexed adr forced */ - char *oldlineptr; - char *oldsymname; - reg_pt reg; - bool_t wordflag; /* set if extended or long indexed adr forced*/ - - if ((reg = regchk()) != NOREG) - { - switch (reg) - { - case AREG: - postb |= 0x86; - break; - case BREG: - postb |= 0x85; - break; - case DREG: - postb |= 0x8B; - break; - default: - if (indreg(MAXINDREG) != NOREG) - checkpostinc(); - return; - } - getsym(); - if (sym != COMMA) - inderror(COMEXP); - else - getindexnopost(); - return; - } - else if (sym == SUBOP) /* could be -R or - in expression */ - { - oldlineptr = lineptr; /* save state */ - oldsymname = symname; - getsym(); - reg = regchk(); - lineptr = oldlineptr; - symname = oldsymname; - if (reg != NOREG) - { - predec1(); /* it's -R */ - return; - } - sym = SUBOP; - } - else if (sym == COMMA) - { - postb |= INDEXBIT; - getsym(); - if (sym == SUBOP) - { - predec1(); - return; - } - else if (sym != PREDECOP) - { - if (indreg(MAXINDREG) != NOREG) - checkpostinc(); - return; - } - } - if (sym == PREDECOP) - { - postb |= 0x83; - getindexnopost(); - return; - } - - /* should have expression */ - - wordflag = byteflag = FALSE; - if (sym == LESSTHAN) - { - /* context-sensitive, LESSTHAN means byte-sized here */ - byteflag = TRUE; - getsym(); - } - else if (sym == GREATERTHAN) - { - /* context-sensitive, GREATERTHAN means word-sized here */ - wordflag = TRUE; - getsym(); - } - expres(); - if (sym == COMMA) - { /* offset from register */ - getsym(); - if ((reg = indreg(PCREG)) == NOREG) - return; - postb |= 0x8; /* default 8 bit offset */ - if (reg == PCREG) - { - reldata(); - if (!(lastexp.data & (RELBIT | UNDBIT))) - { - lastexp.offset = lastexp.offset - lc; - if (page != 0x0) - lastexp.offset -= 0x4; /* extra for instruction */ - else - lastexp.offset -= 0x3; /* 3 byte instruction - assuming 8 bit offset */ - } - } - if (byteflag) - { - if (!(lastexp.data & (RELBIT | UNDBIT)) && - !is8bitsignedoffset(lastexp.offset)) - error(ABOUNDS); /* forced short form is impossible */ - ++mcount; - } - else if (wordflag || lastexp.data & (FORBIT | RELBIT | UNDBIT) || - !is8bitsignedoffset(lastexp.offset)) - { /* 16 bit offset */ - if (postb & PCRELBIT && !(lastexp.data & RELBIT)) - --lastexp.offset; /* instruction 1 longer than already - allowed */ - postb |= 0x1; - mcount += 0x2; - } - else if (!(postb & PCRELBIT) && - (offset_t) (lastexp.offset + 0x10) < 0x20 && - !(postb & INDIRECTBIT && lastexp.offset != 0x0)) - { /* 5 bit offset */ - postb &= RRBITS | INDIRECTBIT; - if (lastexp.offset == 0x0) - postb |= 0x84; /* index with zero offset */ - else - postb |= (lastexp.offset & 0x1F); - } - else /* 8 bit offset */ - ++mcount; - fixupind(); - } - else if (postb & INDIRECTBIT) - { /* extended indirect */ - postb = 0x9F; - mcount += 0x2; - fixupind(); - } - else if (postb & INDEXBIT) - inderror(ILLMOD); /* e.g. LEAX $10 */ - else - { - if (byteflag || !wordflag && !(lastexp.data & (FORBIT | RELBIT)) && - (lastexp.offset >> 0x8) == dirpag) - { /* direct addressing */ - if (opcode >= 0x80) - opcode |= 0x10; - } - else /* extended addressing */ - { - if (opcode < 0x80) - opcode |= 0x70; - else - opcode |= 0x30; - ++mcount; - if (pass2 && (opcode == JSR_OPCODE || opcode == JMP_OPCODE) && - !(lastexp.data & IMPBIT) && - lastexp.offset + (0x81 - 0x3) < 0x101) - /* JSR or JMP could be done with BSR or BRA */ - error(SHORTB); - } - } -} - -PRIVATE void fixupind() -{ - if ((opcode & 0x30) == 0x0) /* change all but LEA opcodes */ - { - if (opcode < 0x80) - opcode |= 0x60; - else - opcode |= 0x20; - } -} - -PRIVATE void getindexnopost() -{ - getsym(); - if (indreg(MAXINDREG) != NOREG) - fixupind(); -} - -PRIVATE void inderror(errnum) -error_pt errnum; -{ - error(errnum); - if (postb & INDIRECTBIT) - sym = RBRACKET; /* fake right bracket to kill further errors */ - fixupind(); -} - -/* check current symbol is an index register (possibly excepting PC) */ -/* if so, modify postbyte RR and INDEXBIT for it, get next sym, return TRUE */ -/* otherwise generate error, return FALSE */ - -PRIVATE reg_pt indreg(maxindex) -reg_pt maxindex; -{ - reg_pt reg; - - if ((reg = regchk()) == NOREG) - inderror(IREGEXP); - else if (reg > maxindex) - { - inderror(ILLREG); - reg = NOREG; - } - else - { - postb |= rrindex[reg]; - getsym(); - } - return reg; -} - -/* all-mode ops */ - -PUBLIC void mall() -{ - if (sym == IMMEDIATE) - mimmed(); - else - malter(); -} - -/* alterable mode ops */ - -PUBLIC void malter() -{ - postb = 0x0; /* not yet indexed or indirect */ - doaltind(); -} - -/* indexed mode ops */ - -PUBLIC void mindex() -{ - postb = INDEXBIT; /* indexed but not yet indirect */ - doaltind(); -} - -/* immediate ops */ - -PUBLIC void mimmed() -{ - opcode_t nybble; - - mcount += 0x2; - if (sym != IMMEDIATE) - error(ILLMOD); - else - { - if (opcode >= 0x80 && ((nybble = opcode & 0xF) == 0x3 || - nybble == 0xC || nybble >= 0xE)) - ++mcount; /* magic for long immediate */ - symexpres(); - if (pass2 && mcount <= 0x2) - { - chkabs(); - checkdatabounds(); - } - } -} - -/* long branches */ - -PUBLIC void mlong() -{ - mcount += 0x3; /* may be 0x0 or 0x1 here */ - expres(); - if (pass2) - { - reldata(); - if (!(lastexp.data & (RELBIT | UNDBIT))) - { - lastexp.offset = lastexp.offset - lc - lcjump; - if (!(lastexp.data & IMPBIT) && - lastexp.offset + 0x81 < 0x101) - error(SHORTB); /* -0x81 to 0x7F, warning */ - } - } -} - -/* PSHS and PULS */ - -PUBLIC void msstak() -{ - sustack(SREG); -} - -/* TFR and EXG */ - -PUBLIC void mswap() -{ - reg_pt reg; - - mcount = 0x2; - if ((reg = regchk()) == NOREG) - error(REGEXP); - else - { - postb = tfrexg1[reg]; - getsym(); - if (sym != COMMA) - error(COMEXP); - else - { - getsym(); - if ((reg = regchk()) == NOREG) - error(REGEXP); - else if ((postb |= tfrexg2[reg]) - & 0x88 && (postb & 0x88) != 0x88) - error(ILLREG); /* registers not of same size */ - } - } -} - -/* PSHU and PULU */ - -PUBLIC void mustak() -{ - sustack(UREG); -} - -PRIVATE void predec1() -{ - if (postb & INDIRECTBIT) - inderror(ILLMOD); /* single-dec indirect illegal */ - else - { - postb |= 0x82; - getindexnopost(); - } -} - -/* common routine for PSHS/PULS/PSHU/PULU */ - -PRIVATE void sustack(stackreg) -reg_pt stackreg; -{ - reg_pt reg; - - mcount = 0x2; - while ((reg = regchk()) != NOREG) - { - if (reg == stackreg) - { - error(ILLREG); /* cannot stack self */ - break; - } - postb |= pushpull[reg]; - getsym(); - if (sym != COMMA) - break; - getsym(); - } -} - -#endif /* MC6809 */ - -/* routines common to all processors */ - -PUBLIC void getcomma() -{ - if (sym != COMMA) - error(COMEXP); - else - getsym(); -} - -/* inherent ops */ - -/* for I80386 */ -/* AAA, AAS, CLC, CLD, CLI, CLTS, CMC, CMPSB, DAA, DAS, HLT, INTO, INSB, */ -/* INVD, */ -/* LAHF, LEAVE, LOCK, LODSB, MOVSB, NOP, OUTSB, REP, REPE, REPNE, REPNZ, */ -/* REPZ, SAHF, SCASB, STC, STD, STI, STOSB, WAIT, WBINVD */ - -PUBLIC void minher() -{ - ++mcount; -} - -/* short branches */ - -PUBLIC void mshort() -{ - nonimpexpres(); - mshort2(); -} - -PRIVATE void mshort2() -{ - mcount += 0x2; - if (pass2) - { - reldata(); - if (lastexp.data & RELBIT) - showrelbad(); - else if (!(lastexp.data & UNDBIT)) - { - lastexp.offset = lastexp.offset - lc - mcount; - if (!is8bitsignedoffset(lastexp.offset)) - error(ABOUNDS); - } - } -} - -/* check if current symbol is a register, return register number or NOREG */ - -PRIVATE reg_pt regchk() -{ - register struct sym_s *symptr; - - if (sym == IDENT) - { - if ((symptr = gsymptr)->type & MNREGBIT) - { - if (symptr->data & REGBIT) - { -#ifdef I80386 - if (symptr->value_reg_or_op.reg == ST0REG && !fpreg_allowed) - error(FP_REG_NOT_ALLOWED); -#endif - return symptr->value_reg_or_op.reg; - } - } - else if (!(symptr->type & (LABIT | MACBIT | VARBIT))) - symptr->data |= FORBIT; /* show seen in advance */ - } - return NOREG; -} - -/* convert lastexp.data for PC relative */ - -PRIVATE void reldata() -{ - if ((lastexp.data ^ lcdata) & (IMPBIT | RELBIT | SEGM)) - { - if ((lastexp.data ^ lcdata) & RELBIT) - showrelbad(); /* rel - abs is weird, abs - rel is bad */ - else - { - pcrflag = OBJ_R_MASK; - lastexp.data = (lcdata & ~SEGM) | lastexp.data | RELBIT; - /* segment is that of lastexp.data */ - } - } - else /* same file, segment and relocation */ - lastexp.data = (lastexp.data | lcdata) & ~(RELBIT | SEGM); -} diff --git a/bin86-0.3/as/opcode.h b/bin86-0.3/as/opcode.h deleted file mode 100644 index 1e96079..0000000 --- a/bin86-0.3/as/opcode.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * bin86/as/opcode.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* opcode.h - routine numbers and special opcodes for assembler */ - -enum -{ -/* Pseudo-op routine numbers. - * Conditionals are first - this is used to test if op is a conditional. - */ - ELSEOP, - ELSEIFOP, - ELSEIFCOP, - ENDIFOP, - IFOP, - IFCOP, - -#define MIN_NONCOND ALIGNOP - ALIGNOP, - BLKWOP, - BLOCKOP, - BSSOP, - COMMOP, - COMMOP1, - DATAOP, - ENDBOP, - ENTEROP, - ENTRYOP, - EQUOP, - EVENOP, - EXPORTOP, - FAILOP, - FCBOP, - FCCOP, - FDBOP, - FQBOP, - GETOP, - GLOBLOP, - IDENTOP, - IMPORTOP, - LCOMMOP, - LCOMMOP1, - LISTOP, - LOCOP, - MACLISTOP, - MACROOP, - MAPOP, - ORGOP, - PROCEOFOP, - RMBOP, - SECTOP, - SETOP, - SETDPOP, - TEXTOP, -#ifdef I80386 - USE16OP, - USE32OP, -#endif - WARNOP, - -/* Machine-op routine numbers. */ -#ifdef I80386 - BCC, - BSWAP, - CALL, - CALLI, - DIVMUL, - ENTER, - EwGw, - ExGx, - F_INHER, - F_M, - F_M2, - F_M2_AX, - F_M2_M4, - F_M2_M4_M8, - F_M4_M8_OPTST, - F_M4_M8_ST, - F_M4_M8_STST, - F_M4_M8_M10_ST, - F_M10, - F_OPTST, - F_ST, - F_STST, - F_W_INHER, - F_W_M, - F_W_M2, - F_W_M2_AX, - GROUP1, - GROUP2, - GROUP6, - GROUP7, - GROUP8, - GvEv, - GvMa, - GvMp, - IMUL, - IN, - INCDEC, - INHER, - INHER16, - INHER32, - INHER_A, - INT, - JCC, - JCXZ, - LEA, - MOV, - MOVX, - NEGNOT, - OUT, - PUSHPOP, - RET, - SEG, - SETCC, - SH_DOUBLE, - TEST, - XCHG, -#endif /* I80386 */ - -#ifdef MC6809 - ALL, /* all address modes allowed, like LDA */ - ALTER, /* all but immediate, like STA */ - IMMED, /* immediate only (ANDCC, ORCC) */ - INDEXD, /* indexed (LEA's) */ - INHER, /* inherent, like CLC or CLRA */ - LONG, /* long branches */ - SHORT, /* short branches */ - SSTAK, /* S-stack (PSHS, PULS) */ - SWAP, /* TFR, EXG */ - USTAK, /* U-stack (PSHU,PULU) */ -#endif /* MC6809 */ -}; - -/* Special opcodes. */ -#ifdef I80386 -# define CMP_OPCODE_BASE 0x38 -# define CMPSB_OPCODE 0xA6 -# define CMPSW_OPCODE 0xA7 -# define ESCAPE_OPCODE_BASE 0xD8 -# define FST_ENCODED 0x12 -# define FSTP_ENCODED 0x13 -# define JMP_OPCODE 0xE9 -# define JMP_SHORT_OPCODE 0xEB -# define JSR_OPCODE 0xE8 -# define MOVSB_OPCODE 0xA4 -# define MOVSW_OPCODE 0xA5 -# define PAGE1_OPCODE 0x0F -# define POP_OPCODE 0x8F -# define PUSH_OPCODE 0xFF -# define WAIT_OPCODE 0x9B -#endif - -#ifdef MC6809 -# define JMP_OPCODE 0x7E -# define JSR_OPCODE 0xBD -# define PAGE1_OPCODE 0x10 -# define PAGE2_OPCODE 0x11 -#endif diff --git a/bin86-0.3/as/pops.c b/bin86-0.3/as/pops.c deleted file mode 100644 index a475df6..0000000 --- a/bin86-0.3/as/pops.c +++ /dev/null @@ -1,977 +0,0 @@ -/* - * bin86/as/pops.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* pops.c - handle pseudo-ops for assembler */ - -#include "const.h" -#include "type.h" -#include "address.h" -#include "flag.h" -#include "globvar.h" -#include "opcode.h" -#include "scan.h" - -PRIVATE bool_t elseflag; /* set if ELSE/ELSEIF are enabled */ - /* depends on zero = FALSE init */ -PRIVATE bool_t lcommflag; - -FORWARD void bumpsem P((struct flags_s *flagptr)); -FORWARD void constdata P((unsigned size)); -FORWARD void docomm P((void)); -FORWARD void doelseif P((pfv func)); -FORWARD void doequset P((int labits)); -FORWARD void doentexp P((int entbits, int impbits)); -FORWARD void doif P((pfv func)); -FORWARD struct sym_s *needlabel P((void)); -FORWARD void showredefinedlabel P((void)); -FORWARD void setloc P((unsigned seg)); - -PRIVATE void bumpsem(flagptr) -register struct flags_s *flagptr; -{ - int newcount; - - if (flagptr->global &&pass != 0) - { - /* bump semaphore count by an expression (default 1), */ - /* then set currentflag iff semaphore count is plus */ - if (sym == EOLSYM) - lastexp.offset = 1; - else - { - absexpres(); - if (lastexp.data & UNDBIT) - return; - } - newcount = (int) lastexp.offset; -#ifdef I80386 /* really sizeof (offset_t) != sizeof (int) */ - if (newcount != lastexp.offset) - datatoobig(); -#endif - newcount += flagptr->semaphore; - if ((int) lastexp.offset >= 0) - { - if (newcount < flagptr->semaphore) - { - error(COUNTOV); - newcount = 0x7fff; - } - } - else if (newcount >= flagptr->semaphore) - { - error(COUNTUN); - newcount = -0x8000; - } - flagptr->semaphore = newcount; - flagptr->current = newcount >= 0; - } -} - -/* check symbol is either undefined */ -/* or has the same segment & relocatability as lc */ - -PUBLIC bool_pt checksegrel(symptr) -register struct sym_s *symptr; -{ - if ((symptr->type & LABIT || - symptr->data & IMPBIT && !(symptr->data & UNDBIT)) && - ((symptr->data ^ lcdata) & (RELBIT | SEGM))) - { - error(SEGREL); - return FALSE; - } - return TRUE; -} - -/* check address fits in 1 byte (possibly with sign truncated) */ - -PUBLIC void checkdatabounds() -{ - if (!(lastexp.data & UNDBIT) && - (offset_t) (lastexp.offset + 0x80) >= 0x180) - datatoobig(); -} - -/* allocate constant data (zero except for size 1), default zero for size 1 */ - -PRIVATE void constdata(size) -unsigned size; -{ - offset_t remaining; - - absexpres(); - if (!((lcdata |= lastexp.data) & UNDBIT)) - { - lcjump = lastexp.offset * size; - popflags = POPLONG | POPHI | POPLO | POPLC; - if (size == 1 && sym == COMMA) - { - symabsexpres(); - checkdatabounds(); - for (remaining = lcjump; remaining != 0; --remaining) - { - putbin((opcode_pt) lastexp.offset); /* fill byte */ - putabs((opcode_pt) lastexp.offset); - } - lastexp.offset = lcjump; - } - else - accumulate_rmb(lastexp.offset * size); - } -} - -PUBLIC void datatoobig() -{ - error(DBOUNDS); -} - -/* common routine for COMM/.COMM */ - -PRIVATE void docomm() -{ - register struct sym_s *labptr; - - absexpres(); /* if undefined, value 0 and size unchanged */ - labptr = label; - if (checksegrel(labptr)) - { - if (labptr->type & (EXPBIT | LABIT)) - labelerror(ALREADY); - else - { - if (!(labptr->type & COMMBIT) || - lastexp.offset > labptr->value_reg_or_op.value) - labptr->value_reg_or_op.value = lastexp.offset; - labptr->type |= COMMBIT; - if (lcommflag) - labptr->type |= REDBIT; /* kludge - COMMBIT | REDBIT => SA */ - labptr->data = (lcdata & SEGM) | (FORBIT | IMPBIT | RELBIT); - showlabel(); - } - } - lcommflag = FALSE; -} - -/* common routine for ELSEIF/ELSEIFC */ - -PRIVATE void doelseif(func) -pfv func; -{ - if (iflevel == 0) - error(ELSEIFBAD); - else - { - ifflag = FALSE; - if (elseflag) - { - (*func) (); - if (!(lastexp.data & UNDBIT) && lastexp.offset != 0) - /* expression valid and TRUE, enable assembling */ - { - ifflag = TRUE; - elseflag = FALSE; - } - } - } -} - -/* common routine for EQU/SET */ - -PRIVATE void doequset(labits) -unsigned char labits; -{ - register struct sym_s *labptr; - unsigned char olddata; - unsigned char oldtype; - - labptr = label; - /* set up new label flags in case labe isl used in expression */ - labptr->type = (oldtype = labptr->type) | labits; - labptr->data = (olddata = labptr->data) & ~IMPBIT; - /* non-imported now */ - nonimpexpres(); - lastexp.data |= olddata & FORBIT; /* take all but FORBIT from - expression */ - if (oldtype & LABIT && !(olddata & UNDBIT)) - /* this is a previously defined label */ - - /* - redefinition only allowed if same relocatability, segment and - value - */ - { - if ((olddata ^ lastexp.data) & (RELBIT | UNDBIT) || - labptr->value_reg_or_op.value != lastexp.offset) - { - showredefinedlabel(); - return; - } - } - labptr->data = lastexp.data; - labptr->value_reg_or_op.value = lastexp.offset; - showlabel(); -} - -/* common routine for ENTRY/EXPORT */ - -PRIVATE void doentexp(entbits, impbits) -unsigned char entbits; -unsigned char impbits; -{ - struct sym_s *symptr; - - while (TRUE) - { - if ((symptr = needlabel()) != NULL) - { - if (symptr->type & COMMBIT) - error(ALREADY); - else if (impbits != 0) - { - if (pass != 0) - ; - else if (symptr->type & (EXPBIT | LABIT)) - symptr->type |= EXPBIT; - else - { - symptr->type |= REDBIT; - if (!(symptr->data & IMPBIT)) - symptr->data |= IMPBIT | SEGM; - } - } - else - { - if (pass != 0) - { - if (!(symptr->type & LABIT)) - error(UNLAB); - } - else - { - symptr->type |= entbits | EXPBIT; - symptr->data &= ~IMPBIT; - } - } - } - getsym(); - if (sym != COMMA) - break; - getsym(); - } -} - -/* common routine for IF/IFC */ - -PRIVATE void doif(func) -pfv func; -{ - if (iflevel >= MAXIF) - error(IFOV); - else - { - ++iflevel; - --ifstak; - ifstak->elseflag = elseflag; - elseflag = FALSE; /* prepare */ - - - /* parse the argument. - * [Fare] moved it here to allow nested if's, as - * the argument must be parsed even if we are not assembling ! - */ - (*func) (); - - if ((ifstak->ifflag = ifflag) != FALSE) - /* else not assembling before, so not now & no ELSE's */ - { - /* [Fari]: was here! (*func) (); */ - if (!(lastexp.data & UNDBIT) && lastexp.offset == 0) - /* else expression invalid or FALSE, don't change flags */ - { - ifflag = FALSE; /* not assembling */ - elseflag = TRUE;/* but ELSE will change that */ - } - } - } -} - -PUBLIC void fatalerror(errnum) -error_pt errnum; -{ - error(errnum); - skipline(); - listline(); - finishup(); -} - -/* swap position with label position, do error, put back posn */ -/* also clear label ptr */ - -PUBLIC void labelerror(errnum) -error_pt errnum; -{ - struct sym_s *oldgsymptr; - char *oldlineptr; - unsigned char oldsym; - char *oldsymname; - - oldgsymptr = gsymptr; - oldlineptr = lineptr; - oldsym = sym; - oldsymname = symname; - lineptr = linebuf; - getsym(); /* 1st symbol is label or symbol after - * missing one */ - error(errnum); - gsymptr = oldgsymptr; - lineptr = oldlineptr; - sym = oldsym; - symname = oldsymname; - label = NULL; -} - -PRIVATE struct sym_s *needlabel() -{ - register struct sym_s *symptr; - - if (sym != IDENT || - (symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT)) - { - error(LABEXP); - return NULL; - } - return symptr; -} - -/* .ALIGN pseudo-op */ - -PUBLIC void palign() -{ - absexpres(); - if (!((lcdata |= lastexp.data) & UNDBIT)) - { - popflags = POPLONG | POPHI | POPLO | POPLC; - if (lastexp.offset != 0 && - (lcjump = lc % lastexp.offset) != 0) - accumulate_rmb(lcjump = lastexp.offset - lcjump); - } -} - -/* .BLKW pseudo-op */ - -PUBLIC void pblkw() -{ - constdata(2); -} - -/* BLOCK pseudo-op */ - -PUBLIC void pblock() -{ - if (blocklevel >= MAXBLOCK) - error(BLOCKOV); - else - { - register struct block_s *blockp; - - ++blocklevel; - blockp = blockstak; - blockstak = --blockp; - blockp->data = lcdata; - blockp->dp = dirpag; - blockp->lc = lc; - porg(); /* same as ORG apart from stacking */ - } -} - -/* .BSS pseudo-op */ - -PUBLIC void pbss() -{ - setloc(BSSLOC); -} - -/* COMM pseudo-op */ - -PUBLIC void pcomm() -{ - if (label == NULL) - labelerror(MISLAB); - else if (label->type & VARBIT) - labelerror(VARLAB); /* variable cannot be COMM'd */ - else - docomm(); -} - -/* .COMM pseudo-op */ - -PUBLIC void pcomm1() -{ - unsigned oldseg; - - if (label != NULL) - labelerror(ILLAB); - oldseg = lcdata & SEGM; - setloc(BSSLOC); - if ((label = needlabel()) != NULL && checksegrel(label)) - { - /* Like import. */ - if (label->type & (EXPBIT | LABIT)) - error(ALREADY); - else - label->data = lcdata | (FORBIT | IMPBIT | RELBIT); - getsym(); - getcomma(); - if (label->type & (EXPBIT | LABIT)) - absexpres(); /* just to check it */ - else - docomm(); - } - setloc(oldseg); -} - -/* .DATA pseudo-op */ - -PUBLIC void pdata() -{ - setloc(DATALOC); -} - -/* ELSE pseudo-op */ - -PUBLIC void pelse() -{ - if (iflevel == 0) - error(ELSEBAD); - else - { - ifflag = FALSE; /* assume ELSE disabled */ - if (elseflag) - { - ifflag = TRUE; /* ELSE enabled */ - elseflag = FALSE; - } - } -} - -/* ELSEIF pseudo-op */ - -PUBLIC void pelseif() -{ - doelseif(absexpres); -} - -/* ELSEIFC pseudo-op */ - -PUBLIC void pelsifc() -{ - doelseif(scompare); -} - -/* ENDB pseudo-op */ - -PUBLIC void pendb() -{ - if (label != NULL) - labelerror(ILLAB); - if (blocklevel == 0) - error(ENDBBAD); - else - { - register struct block_s *blockp; - - blockp = blockstak; - lcdata = blockp->data; - dirpag = blockp->dp; - accumulate_rmb(blockp->lc - lc); - lc = blockp->lc; - --blocklevel; - blockstak = blockp + 1; - } -} - -/* ENDIF pseudo-op */ - -PUBLIC void pendif() -{ - if (iflevel == 0) - error(ENDIFBAD); - else - { - ifflag = ifstak->ifflag; - elseflag = ifstak->elseflag; - ++ifstak; - --iflevel; - } -} - -/* ENTER pseudo-op */ - -PUBLIC void penter() -{ - if (!(pedata & UNDBIT)) - error(REENTER); - else - { - if (!((pedata = (pedata & ~UNDBIT) | lcdata) & UNDBIT)) - { - progent = lc; - popflags = POPLC; - } - } -} - -/* ENTRY pseudo-op */ - -PUBLIC void pentry() -{ - doentexp(ENTBIT, 0); -} - -/* EQU pseudo-op */ - -PUBLIC void pequ() -{ - register struct sym_s *labptr; - - if ((labptr = label) == NULL) - labelerror(MISLAB); - else if (labptr->type & COMMBIT) - showredefinedlabel(); /* common cannot be EQU'd */ - else if (labptr->type & VARBIT) - labelerror(VARLAB); /* variable cannot be EQU'd */ - else - doequset(LABIT); -} - -/* .EVEN pseudo-op */ - -PUBLIC void peven() -{ - popflags = POPLONG | POPHI | POPLO | POPLC; - accumulate_rmb(lcjump = lastexp.data = lc & 1); -} - -/* EXPORT pseudo-op */ - -PUBLIC void pexport() -{ - doentexp(0, 0); -} - -/* FAIL pseudo-op */ - -PUBLIC void pfail() -{ - error(FAILERR); -} - -/* FCB pseudo-op */ - -PUBLIC void pfcb() -{ - char *bufptr; - offset_t firstbyte; - - bufptr = databuf.fcbuf; - absexpres(); - firstbyte = lastexp.offset; - while (TRUE) - { - checkdatabounds(); - *bufptr++ = lastexp.offset; - ++mcount; /* won't overflow, line length limits it */ - if (sym != COMMA) - break; - symabsexpres(); - } - lastexp.offset = firstbyte; - popflags = POPLO | POPLC; - fcflag = TRUE; -} - -/* FCC pseudo-op */ - -PUBLIC void pfcc() -{ - register char *bufptr; - unsigned char byte; - char delimiter; - register char *reglineptr; - - bufptr = databuf.fcbuf; - reglineptr = symname; - if ((delimiter = *reglineptr) != EOLCHAR) - ++reglineptr; - while (TRUE) - { - if (*reglineptr == EOLCHAR) - { - symname = reglineptr; - error(DELEXP); - break; - } - if (*reglineptr == delimiter) - { - if (*++reglineptr != delimiter) - break; - } - else if (*reglineptr == '\\' && reglineptr[1] != EOLCHAR) - ++reglineptr; - if ((byte = *reglineptr) < ' ') - { - symname = reglineptr; - error(CTLINS); - byte = ' '; - } - *bufptr++ = byte; - ++reglineptr; - } - lineptr = reglineptr; - getsym(); - if (bufptr > databuf.fcbuf) - { - lastexp.offset = databuf.fcbuf[0]; /* show 1st char only */ - mcount = bufptr - databuf.fcbuf; - /* won't overflow, line length limits it */ - fcflag = TRUE; - popflags = POPLO | POPLC; - } -} - -/* FDB pseudo-op */ - -PUBLIC void pfdb() -{ - struct address_s *adrptr; - unsigned firstdata; - offset_t firstword; - - adrptr = databuf.fdbuf; - expres(); - firstword = lastexp.offset; - firstdata = lastexp.data; - while (TRUE) - { - *adrptr++ = lastexp; - mcount += 2; /* won't overflow, line length limits it */ - if (sym != COMMA) - break; - symexpres(); - } - lastexp.offset = firstword; - lastexp.data = firstdata; - popflags = POPHI | POPLO | POPLC; - fdflag = TRUE; -} - -#if SIZEOF_OFFSET_T > 2 - -/* FQB pseudo-op */ - -PUBLIC void pfqb() -{ - struct address_s *adrptr; - offset_t firstdata; - offset_t firstword; - - adrptr = databuf.fqbuf; - expres(); - firstword = lastexp.offset; - firstdata = lastexp.data; - while (TRUE) - { - *adrptr++ = lastexp; - mcount += 4; /* won't overflow, line length limits it */ - if (sym != COMMA) - break; - symexpres(); - } - lastexp.offset = firstword; - lastexp.data = firstdata; - popflags = POPLONG | POPHI | POPLO | POPLC; - fqflag = TRUE; -} - -#endif /* SIZEOF_OFFSET_T > 2 */ - -/* .GLOBL pseudo-op */ - -PUBLIC void pglobl() -{ - if (binaryg) - error(NOIMPORT); - doentexp(0, IMPBIT); -} - -/* IDENT pseudo-op (not complete) */ - -PUBLIC void pident() -{ - if (sym != IDENT) - error(LABEXP); - else - getsym_nolookup(); /* should save ident string */ -} - -/* IF pseudo-op */ - -PUBLIC void pif() -{ - doif(absexpres); -} - -/* IFC pseudo-op */ - -PUBLIC void pifc() -{ - doif(scompare); -} - -/* IMPORT pseudo-op */ - -PUBLIC void pimport() -{ - struct sym_s *symptr; - - if (binaryg) - error(NOIMPORT); - while (TRUE) - { - if ((symptr = needlabel()) != NULL && checksegrel(symptr)) - { - if (symptr->type & (COMMBIT | EXPBIT | LABIT)) - /* IMPORT is null if label (to be) declared */ - error(ALREADY); - else - /* get current segment from lcdata, no need to mask rest */ - symptr->data = lcdata | (FORBIT | IMPBIT | RELBIT); - } - getsym(); - if (sym != COMMA) - break; - getsym(); - } -} - -/* LCOMM pseudo-op */ - -PUBLIC void plcomm() -{ - lcommflag = TRUE; - pcomm(); -} - -/* .LCOMM pseudo-op */ - -PUBLIC void plcomm1() -{ - lcommflag = TRUE; - pcomm1(); -} - -/* .LIST pseudo-op */ - -PUBLIC void plist() -{ - bumpsem(&list); -} - -/* LOC pseudo-op */ - -PUBLIC void ploc() -{ - if (label != NULL) - labelerror(ILLAB); - absexpres(); - if (!(lastexp.data & UNDBIT)) - { - if (lastexp.offset >= NLOC) - datatoobig(); - else - setloc((unsigned) lastexp.offset); - } -} - -/* .MACLIST pseudo-op */ - -PUBLIC void pmaclist() -{ - bumpsem(&maclist); -} - -/* .MAP pseudo-op */ - -PUBLIC void pmap() -{ - absexpres(); - if (!(lastexp.data & UNDBIT)) - { - mapnum = lastexp.offset; - popflags = POPLO; - if (lastexp.offset >= 0x100) - datatoobig(); - } -} - -/* ORG pseudo-op */ - -PUBLIC void porg() -{ - if (label != NULL) - labelerror(ILLAB); - absexpres(); - if (!((lcdata = lastexp.data) & UNDBIT)) - { - accumulate_rmb(lastexp.offset - lc); - binmbuf = lc = lastexp.offset; - popflags = POPLC; - } -} - -/* RMB pseudo-op */ - -PUBLIC void prmb() -{ - constdata(1); -} - -/* .SECT pseudo-op */ - -PUBLIC void psect() -{ - if (label != NULL) - labelerror(ILLAB); - while (sym == IDENT) - { - if (!(gsymptr->type & MNREGBIT)) - error(ILL_SECTION); - else switch (gsymptr->value_reg_or_op.op.routine) - { - case BSSOP: - pbss(); - break; - case DATAOP: - pdata(); - break; - case TEXTOP: - ptext(); - break; - default: - error(ILL_SECTION); - break; - } - getsym(); - if (sym == COMMA) - getsym(); - } -} - -/* SET pseudo-op */ - -PUBLIC void pset() -{ - register struct sym_s *labptr; - - if ((labptr = label) == NULL) - labelerror(MISLAB); - else if (labptr->type & COMMBIT) - labelerror(RELAB); /* common cannot be SET'd */ - else - doequset(labptr->type & LABIT ? 0 : VARBIT); -} - -/* SETDP pseudo-op */ - -PUBLIC void psetdp() -{ - absexpres(); - if (!(lastexp.data & UNDBIT)) - { - dirpag = lastexp.offset; - popflags = POPLO; - if (lastexp.offset >= 0x100) - datatoobig(); - } -} - -/* .TEXT pseudo-op */ - -PUBLIC void ptext() -{ - setloc(TEXTLOC); -} - -/* .WARN pseudo-op */ - -PUBLIC void pwarn() -{ - bumpsem(&warn); -} - -#ifdef I80386 - -/* USE16 pseudo-op */ - -PUBLIC void puse16() -{ - defsize = 2; -} - -/* USE16 pseudo-op */ - -PUBLIC void puse32() -{ - defsize = 4; -} - -#endif - -/* show redefined label and error, and set REDBIT */ - -PRIVATE void showredefinedlabel() -{ - register struct sym_s *labptr; - - labptr = label; /* showlabel() will kill label prematurely */ - showlabel(); - if (!(labptr->type & REDBIT)) - { - labptr->type |= REDBIT; - labelerror(RELAB); - } -} - -PUBLIC void showlabel() -{ - register struct sym_s *labptr; - - labptr = label; - lastexp.data = labptr->data; - lastexp.offset = labptr->value_reg_or_op.value; - popflags = POPLONG | POPHI | POPLO; - label = NULL; /* show handled by COMM, EQU or SET */ -} - -/* set location segment */ - -PRIVATE void setloc(seg) -unsigned seg; -{ - if (pass != 0 && seg != (lcdata & SEGM)) - putobj(seg | OBJ_SET_SEG); - { - register struct lc_s *lcp; - - lcp = lcptr; - lcp->data = lcdata; - lcp->lc = lc; - lcptr = lcp = lctab + (unsigned char) seg; - lcdata = (lcp->data & ~SEGM) | (unsigned char) seg; - binmbuf = lc = lcp->lc; - popflags = POPLC; - } -} diff --git a/bin86-0.3/as/proto.h b/bin86-0.3/as/proto.h deleted file mode 100644 index 0b70a4b..0000000 --- a/bin86-0.3/as/proto.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * bin86/as/proto.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* extern functions */ - -#if __STDC__ -#define P(x) x -#else -#define P(x) () -#endif - -/* as.c */ -int main P((int argc, char **argv)); -void as_abort P((char *message)); -void finishup P((void)); -void initp1p2 P((void)); - -/* assemble.c */ -void assemble P((void)); - -/* error.c */ -char *build_error_message P((error_pt errnum, char *buf)); - -/* express.c */ -void absexpres P((void)); -void chkabs P((void)); -void nonimpexpres P((void)); -void showrelbad P((void)); -void symabsexpres P((void)); -void symexpres P((void)); -void expres P((void)); -void factor P((void)); -void scompare P((void)); - -/* genbin.c */ -void binheader P((void)); -void bintrailer P((void)); -void genbin P((void)); -void initbin P((void)); -void putbin P((opcode_pt c)); - -/* genlist.c */ -char *build_2hex_number P((unsigned num, char *where)); -char *build_number P((unsigned num, unsigned width, char *where)); -void error P((error_pt errnum)); -void listline P((void)); -void writec P((int c)); -void writenl P((void)); -void writeoff P((offset_t offset)); -void writes P((char *s)); -void writesn P((char *s)); -void writew P((unsigned word)); - -/* genobj.c */ -void accumulate_rmb P((offset_t offset)); -void flushobj P((void)); -void genobj P((void)); -void initobj P((void)); -void objheader P((void)); -void objtrailer P((void)); -void putabs P((opcode_pt c)); -void putobj P((opcode_pt c)); - -/* gensym.c */ -void gensym P((void)); - -/* macro.c */ -void entermac P((struct sym_s *symptr)); -void pmacro P((void)); - -/* mops.c */ -#ifdef I80386 -void mbcc P((void)); -void mbswap P((void)); -void mcall P((void)); -void mcalli P((void)); -void mdivmul P((void)); -void menter P((void)); -void mEwGw P((void)); -void mExGx P((void)); -void mf_inher P((void)); -void mf_m P((void)); -void mf_m2 P((void)); -void mf_m2_ax P((void)); -void mf_m2_m4 P((void)); -void mf_m2_m4_m8 P((void)); -void mf_m4_m8_optst P((void)); -void mf_m4_m8_st P((void)); -void mf_m4_m8_stst P((void)); -void mf_m4_m8_m10_st P((void)); -void mf_m10 P((void)); -void mf_optst P((void)); -void mf_st P((void)); -void mf_stst P((void)); -void mf_w_inher P((void)); -void mf_w_m P((void)); -void mf_w_m2 P((void)); -void mf_w_m2_ax P((void)); -void mgroup1 P((void)); -void mgroup2 P((void)); -void mgroup6 P((void)); -void mgroup7 P((void)); -void mgroup8 P((void)); -void mGvEv P((void)); -void mGvMa P((void)); -void mGvMp P((void)); -void mimul P((void)); -void min P((void)); -void mincdec P((void)); -void minher P((void)); -void minher16 P((void)); -void minher32 P((void)); -void minhera P((void)); -void mint P((void)); -void mjcc P((void)); -void mjcxz P((void)); -void mlea P((void)); -void mmov P((void)); -void mmovx P((void)); -void mnegnot P((void)); -void mout P((void)); -void mpushpop P((void)); -void mret P((void)); -void mseg P((void)); -void msetcc P((void)); -void mshdouble P((void)); -void mtest P((void)); -void mxchg P((void)); -#endif /* I80386 */ - -#ifdef MC6809 -void mall P((void)); -void malter P((void)); -void mimmed P((void)); -void mindex P((void)); -void minher P((void)); -void mlong P((void)); -void msstak P((void)); -void mswap P((void)); -void mustak P((void)); -#endif /* MC6809 */ - -void getcomma P((void)); -void mshort P((void)); - -/* pops.c */ -bool_pt checksegrel P((struct sym_s *symptr)); -void checkdatabounds P((void)); -void datatoobig P((void)); -void fatalerror P((error_pt errnum)); -void labelerror P((error_pt errnum)); -void palign P((void)); -void pblkw P((void)); -void pblock P((void)); -void pbss P((void)); -void pcomm P((void)); -void pcomm1 P((void)); -void pdata P((void)); -void pelse P((void)); -void pelseif P((void)); -void pelsifc P((void)); -void pendb P((void)); -void pendif P((void)); -void penter P((void)); -void pentry P((void)); -void pequ P((void)); -void peven P((void)); -void pexport P((void)); -void pfail P((void)); -void pfcb P((void)); -void pfcc P((void)); -void pfdb P((void)); -void pfqb P((void)); -void pglobl P((void)); -void pident P((void)); -void pif P((void)); -void pifc P((void)); -void pimport P((void)); -void plcomm P((void)); -void plcomm1 P((void)); -void plist P((void)); -void ploc P((void)); -void pmaclist P((void)); -void pmap P((void)); -void porg P((void)); -void prmb P((void)); -void psect P((void)); -void pset P((void)); -void psetdp P((void)); -void ptext P((void)); -void puse16 P((void)); -void puse32 P((void)); -void pwarn P((void)); -void showlabel P((void)); - -/* readsrc.c */ -void initsource P((void)); -fd_t open_input P((char *name)); -void pget P((void)); -void pproceof P((void)); -void readline P((void)); -void skipline P((void)); - -/* scan.c */ -void context_hexconst P((void)); -void getsym P((void)); -void getsym_nolookup P((void)); -void initscan P((void)); - -/* table.c */ -void inst_keywords P((void)); -struct sym_s *lookup P((void)); -void statistics P((void)); - -/* type.c */ -void u2c2 P((char *buf, u16_pt offset)); -void u4c4 P((char *buf, u32_t offset)); -void u2cn P((char *buf, u16_pt offset, unsigned count)); -void u4cn P((char *buf, u32_t offset, unsigned count)); -bool_pt typeconv_init P((bool_pt big_endian, bool_pt long_big_endian)); - -char *strrchr(const char *s, int c); -void *malloc(int c); - -#if 0 -/* library - fcntl.h */ -int creat P((const char *__path, int __mode)); -int open P((const char *__path, int __oflag, ...)); - -/* library - stdlib.h */ -void abort P((void)); -void exit P((int __status)); -void *malloc P((unsigned __size)); - -/* library - string.h */ -int memcmp P((const void *__s1, const void *__s2, unsigned __max)); -void *memset P((void *__s, int __ch, unsigned __nbytes)); -char *strchr P((const char *__s, int __ch)); -int strcmp P((const char *__s1, const char *__s2)); -char *strcpy P((char *__target, const char *__source)); -unsigned strlen P((const char *__s)); -int strncmp P((const char *__s1, const char *__s2, int __max)); -char *strrchr P((const char *__s, int __ch)); - -/* library - unistd.h */ -char *brk P((char *__adr)); -int close P((int __fd)); -long lseek P((int __fd, long __offset, int __whence)); -int read P((int __fd, char *__buf, unsigned __nbytes)); -char *sbrk P((int __incr)); -int write P((int __fd, char *__buf, unsigned __nbytes)); - -#endif diff --git a/bin86-0.3/as/readsrc.c b/bin86-0.3/as/readsrc.c deleted file mode 100644 index 350fc4d..0000000 --- a/bin86-0.3/as/readsrc.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * bin86/as/readsrc.c - * - * Copyright (C) 1992 Bruce Evans - */ - -#define MAXLINE 256 /* when this is made bigger, fix pfcc not - * to store the string length in a byte- - * sized variable */ - -/* readsrc.c - read source files for assembler */ - -#include <sys/types.h> -#include <fcntl.h> -#include "const.h" -#include "type.h" -#include "flag.h" -#include "file.h" -#include "globvar.h" -#include "macro.h" -#include "scan.h" -#undef EXTERN -#define EXTERN -#include "source.h" - -struct fcbstruct /* file control block structure */ -{ - fd_t fd; /* file descriptor */ - char *lineptr; /* current spot in line */ - char *buf; /* start of buffer (after partial line) */ - char *first; /* start of partial line before buf */ - char *limit; /* end of used part of input buffer */ - unsigned blocksize; /* chars from last read and partial line flag */ - struct fbufstruct *includer;/* buffer of file which included current one */ -}; - -struct fbufstruct /* file buffer structure */ -{ - struct fcbstruct fcb; /* status after opening an include sub-file */ - char fpartline[MAXLINE + 1];/* buffer for partial line */ - char fbuf[INBUFSIZE + 1]; /* buffer to read into */ - char fname[1]; /* file name (variable length), 1 for null */ -}; - -struct get_s /* to record included files */ -{ - fd_t fd; - unsigned line; - long position; -}; - -PRIVATE char hid_filnambuf[FILNAMLEN + 1]; /* buffer for file name */ - -PRIVATE struct get_s hid_getstak[MAXGET]; /* GET stack */ -PRIVATE struct get_s *getstak; /* ptr */ - -PRIVATE struct fcbstruct input; /* current input file control block */ - /* input.lineptr is not kept up to date */ - /* input.fd depends on zero init */ -PRIVATE struct fbufstruct xyz; -PRIVATE struct fbufstruct *inputbuf; /* current input file buffer */ - /* its fcb only to date in includes */ - -PRIVATE char hid_linebuf[LINLEN]; /* line buffer */ -PRIVATE char *maclinebuf; -PRIVATE char *maclineptr; - -FORWARD void clearsource P((void)); -FORWARD void line_too_long P((void)); - -PRIVATE void clearsource() -{ - input.includer = inputbuf; - inputbuf = &xyz; - input.first = input.limit = input.buf = inputbuf->fbuf; - *(lineptr = linebuf = input.first - 1) = EOLCHAR; - input.blocksize = 0; -} - -PRIVATE void line_too_long() -{ - symname = linebuf + (LINLEN - 1); /* spot for the error */ - error(LINLONG); /* so error is shown in column LINLEN - 1 */ -} - -/* initialise private variables */ - -PUBLIC void initsource() -{ - filnamptr = hid_filnambuf; - getstak = hid_getstak + MAXGET; - clearsource(); /* sentinel to invoke blank skipping */ -} - -PUBLIC fd_t open_input(name) -char *name; -{ - fd_t fd; - - if ((unsigned) (fd = open(name, O_RDONLY)) > 255) - as_abort("error opening input file"); - clearsource(); - return fd; -} - -/* - handle GET pseudo_op - stack state of current file, open new file and reset global state vars - file must be seekable for the buffer discard/restore method to work -*/ - -PUBLIC void pget() -{ -#if OLD - if (infiln >= MAXGET) - error(GETOV); - else - { - skipline(); - listline(); - if (infiln != 0) - { - --getstak; - getstak->fd = infil; - getstak->line = linum; - getstak->position = lseek(infil, 0L, 1) - (inbufend - inbufptr); - ++infiln; - linum = 0; - infil = open_input(lineptr - 1); - } - } -#else - abort(); -#endif -} - -/* process end of file */ -/* close file, unstack old file if current one is included */ -/* otherwise switch pass 0 to pass 1 or exit on pass 2 */ -/* end of file may be from phyical end of file or an END statement */ - -PUBLIC void pproceof() -{ - if (infiln != 0) - close(infil); - if (lineptr == linebuf) - list.current = FALSE; /* don't list line after last unless error */ - if (infiln == infil0) - /* all conditionals must be closed before end of main file (not GETs) */ - { - if (blocklevel != 0) - error(EOFBLOCK); - if (iflevel != 0) - error(EOFIF); - if (lcdata & UNDBIT) - error(EOFLC); - lcptr->data = lcdata; - lcptr->lc = lc; - } - /* macros must be closed before end of all files */ - if (macload) - error(EOFMAC); - listline(); /* last line or line after last if error */ - if (infiln != infil0) - { - infil = getstak->fd; - linum = getstak->line; - if (--infiln != 0) - lseek(infil, getstak->position, 0); - ++getstak; - } - else if (!pass) - { - pass = TRUE; - objheader(); /* while pass 1 data all valid */ - binmbuf = 0; /* reset zero variables */ - maclevel = iflevel = blocklevel = - totwarn = toterr = linum = macnum = 0; - initp1p2(); /* reset other varaiables */ - binaryc = binaryg; -#ifdef I80386 - defsize = idefsize; -#endif - list.current = list.global; - maclist.current = maclist.global; - - warn.current = TRUE; - if (warn.semaphore < 0) - warn.current = FALSE; - if (infiln != 0) - infil = open_input(filnamptr); - binheader(); - } - else - finishup(); -} - -/* - read 1 line of source. - Source line ends with '\n', line returned is null terminated without '\n'. - Control characters other than blank, tab and newline are discarded. - Long lines (length > LINLEN) are truncated, and an error is generated. - On EOF, calls pproceof(), and gets next line unless loading a macro. - This is where macro lines are recursively expanded. -*/ - -PUBLIC void readline() -{ - listpre = FALSE; /* not listed yet */ - if (maclevel != 0) - { - register char *bufptr; /* hold *bufptr in a reg char variable */ - register char *reglineptr; /* if possible (not done here) */ - char *oldbufptr; - struct schain_s *parameters; - char paramnum; - unsigned char remaining; /* space remaining in line + 2 */ - /* value 0 not used except for temp predec */ - /* value 1 means error already gen */ - /* values 1 and 2 mean no space */ - - for (; maclevel != 0; - macpar = macstak->parameters, ++macstak, --maclevel) - if (*(bufptr = macstak->text) != ETB) - /* nonempty macro, process it and return without continuing the for loop */ - { - if (!macflag) - { - maclinebuf = linebuf; - maclineptr = lineptr; - macflag = TRUE; - } - remaining = (unsigned char)LINLEN + 2; - lineptr = linebuf = reglineptr = hid_linebuf; - while (*bufptr++ != EOLCHAR) - { - if (bufptr[-1] == MACROCHAR && *bufptr >= '0' && *bufptr <= '9') - { - parameters = macstak->parameters; - for (paramnum = *bufptr++; paramnum-- != '0';) - if ((parameters = parameters->next) == NULL) - break; - if (parameters != NULL) - { - for (oldbufptr = bufptr, bufptr = parameters->string; - *bufptr++ != 0;) - { - if (--remaining <= 1) - { - if (remaining != 0) - line_too_long(); - remaining = 1; - break; /* forget rest, param on 1 line */ - } - *reglineptr++ = bufptr[-1]; - } - bufptr = oldbufptr; - } - } - else - { - if (--remaining <= 1) - { - if (remaining != 0) - line_too_long(); - remaining = 1; - } - else - *reglineptr++ = bufptr[-1]; - } - } - macstak->text = bufptr; - *reglineptr = EOLCHAR; - return; - } - } - if (macflag) - { - linebuf = maclinebuf; - lineptr = maclineptr; - macflag = FALSE; - } -again: - ++linum; - ++lineptr; /* if eof, this is input.limit + 1 */ - if (input.blocksize != 0) /* and this routine just resets eof */ - { - if (lineptr < input.limit) /* move back partial line */ - { - register char *col; - - col = input.buf; - while ((*--col = *--input.limit) != EOLCHAR) - ; - input.first = col + 1; - ++input.limit; - input.blocksize = 0; - } - else /* may be non-terminated line, don't stop */ - lineptr = input.limit; - } - if (lineptr == input.limit) - { - lineptr = input.first; - input.blocksize = read(infil, input.buf, INBUFSIZE); - if (input.blocksize < 0) - abort(); - if (input.blocksize == 0) - { - clearsource(); - pproceof(); - if (macload) - { - symname = lineptr; - return; /* macro not allowed across eof */ - } - goto again; - } - input.first = input.buf; - *(input.limit = input.buf + input.blocksize) = EOLCHAR; - } - linebuf = lineptr; - if (lineptr >= input.limit) - *(lineptr = input.limit = input.buf) = EOLCHAR; -} - -PUBLIC void skipline() -{ - register char *reglineptr; - - reglineptr = lineptr - 1; - while (*reglineptr != EOLCHAR) - ++reglineptr; - lineptr = reglineptr; -} diff --git a/bin86-0.3/as/scan.c b/bin86-0.3/as/scan.c deleted file mode 100644 index d8c3cd2..0000000 --- a/bin86-0.3/as/scan.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * bin86/as/scan.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* scan.c - lexical analyser for assembler */ - -#include "const.h" -#include "type.h" -#include "globvar.h" -#undef EXTERN -#define EXTERN -#include "scan.h" - -PRIVATE int numbase; /* base for number */ - -PRIVATE char symofchar[256] = /* table to convert chars to their symbols */ -{ - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, EOLSYM, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - - WHITESPACE, EOLSYM, STRINGCONST, IMMEDIATE, /* !"# */ - HEXCONST, BINCONST, ANDOP, CHARCONST, /* $%&' */ - LPAREN, RPAREN, STAR, ADDOP, /* ()*+ */ - COMMA, SUBOP, IDENT, SLASH, /* ,-./ */ - - INTCONST, INTCONST, INTCONST, INTCONST, /* 0123 */ - INTCONST, INTCONST, INTCONST, INTCONST, /* 4567 */ - INTCONST, INTCONST, COLON, EOLSYM, /* 89:; */ - LESSTHAN, EQOP, GREATERTHAN, MACROARG, /* <=>? */ - - INDIRECT, IDENT, IDENT, IDENT, /* @ABC */ - IDENT, IDENT, IDENT, IDENT, /* DEFG */ - IDENT, IDENT, IDENT, IDENT, /* HIJK */ - IDENT, IDENT, IDENT, IDENT, /* LMNO */ - IDENT, IDENT, IDENT, IDENT, /* PQRS */ - IDENT, IDENT, IDENT, IDENT, /* TUVW */ - IDENT, IDENT, IDENT, LBRACKET, /* XYZ[ */ - OTHERSYM, RBRACKET, OTHERSYM, IDENT, /* \]^_ */ - - OTHERSYM, IDENT, IDENT, IDENT, /* `abc */ - IDENT, IDENT, IDENT, IDENT, /* defg */ - IDENT, IDENT, IDENT, IDENT, /* hijk */ - IDENT, IDENT, IDENT, IDENT, /* lmno */ - IDENT, IDENT, IDENT, IDENT, /* pqrs */ - IDENT, IDENT, IDENT, IDENT, /* tuvw */ - IDENT, IDENT, IDENT, OTHERSYM, /* xyz{ */ - OROP, OTHERSYM, NOTOP, OTHERSYM, /* |}~ */ - - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE, - WHITESPACE, WHITESPACE, WHITESPACE, WHITESPACE -}; - -FORWARD void intconst P((void)); - -PUBLIC void context_hexconst() -{ - numbase = 16; - intconst(); -} - -PUBLIC void getsym() -{ - register char *reglineptr; - - reglineptr = lineptr; -advance: - symname = reglineptr; - switch (sym = symofchar[*reglineptr++]) - { - case WHITESPACE: - goto advance; - case ADDOP: - if (*reglineptr == '+') - { - sym = POSTINCOP; - ++reglineptr; - } - break; - case BINCONST: - numbase = 2; - lineptr = reglineptr; - intconst(); - return; - case CHARCONST: - if ((number = *reglineptr) < ' ') - number = ' '; - if (*reglineptr != EOL) - ++reglineptr; - sym = INTCONST; - break; - case GREATERTHAN: /* context-sensitive */ - if (*reglineptr == '>') - { - sym = SROP; - ++reglineptr; - } - break; - case HEXCONST: - numbase = 16; - lineptr = reglineptr; - intconst(); - return; - case IDENT: - /* walk to end of identifier - magic INTCONST is max of INT, IDENT */ - while (symofchar[*reglineptr] <= INTCONST) - ++reglineptr; - lineptr = reglineptr; - gsymptr = lookup(); - return; - case INTCONST: - if (*(reglineptr - 1) == '0') - { - if (*reglineptr != 'x' && *reglineptr != 'X') - numbase = 8; - else - { - numbase = 16; - ++reglineptr; - } - } - else - { - --reglineptr; - numbase = 10; - } - lineptr = reglineptr; - intconst(); - return; - case LESSTHAN: /* context-sensitive */ - if (*reglineptr == '<') - { - sym = SLOP; - ++reglineptr; - } - break; - case SUBOP: - if (*reglineptr == '-') - { - sym = PREDECOP; - ++reglineptr; - } - break; - } - lineptr = reglineptr; - return; -} - -PUBLIC void getsym_nolookup() -{ - bool_t old_ifflag; - - old_ifflag = ifflag; - ifflag = FALSE; - getsym(); - ifflag = old_ifflag; -} - -PRIVATE void intconst() -{ - register char *reglineptr; - - number = 0; - reglineptr = lineptr; - for (; *reglineptr >= '0'; ++reglineptr) - { - if (*reglineptr > '9') - { - if (numbase != 16) - break; - if (*reglineptr >= 'a' && *reglineptr <= 'f') - { - if (number != 0) - number = numbase * number + (*reglineptr - 'a' + 10); - else - number = *reglineptr - 'a' + 10; - } - else if (*reglineptr >= 'A' && *reglineptr <= 'F') - { - if (number != 0) - number = numbase * number + (*reglineptr - 'A' + 10); - else - number = *reglineptr - 'A' + 10; - } - else - break; - } - else if (number != 0) - number = numbase * number + (*reglineptr - '0'); - else - number = *reglineptr - '0'; - } - if (*reglineptr == 'L' || *reglineptr == 'l') - ++reglineptr; - sym = INTCONST; - lineptr = reglineptr; -} - -PUBLIC void initscan() -{ - if (asld_compatible) - { - lindirect = LPAREN; - rindexp = RPEXP; - rindirect = RPAREN; - } - else - { - lindirect = LBRACKET; - rindexp = RBEXP; - rindirect = RBRACKET; - } -} diff --git a/bin86-0.3/as/scan.h b/bin86-0.3/as/scan.h deleted file mode 100644 index f4421b7..0000000 --- a/bin86-0.3/as/scan.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bin86/as/scan.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* scan.h - global variables for scanner for assembler */ - -#define EOLCHAR '\n' - -EXTERN struct sym_s *gsymptr; /* global symbol ptr */ -EXTERN char lindirect; /* left symbol for indirect addressing */ -EXTERN char *lineptr; /* current line position */ -EXTERN offset_t number; /* constant number */ -EXTERN int rindexp; /* error code for missing rindirect */ -EXTERN char rindirect; /* right symbol for indirect addressing */ -EXTERN char sym; /* current symbol */ -EXTERN char *symname; /* current symbol name */ diff --git a/bin86-0.3/as/source.h b/bin86-0.3/as/source.h deleted file mode 100644 index 5b4f847..0000000 --- a/bin86-0.3/as/source.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * bin86/as/source.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* source.h - global variables for source handlers for assembler */ - -EXTERN unsigned linum; /* line # */ -EXTERN bool_t listpre; /* flag to show line has already been listed */ diff --git a/bin86-0.3/as/table.c b/bin86-0.3/as/table.c deleted file mode 100644 index eab6e4b..0000000 --- a/bin86-0.3/as/table.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * bin86/as/table.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* table.c - symbol table handler for assembler */ - -#include "const.h" -#include "type.h" -#include "globvar.h" -#include "scan.h" - -#define hconv(ch) ((unsigned char) (ch) - 0x41) /* better form for hashing */ - -#ifdef I80386 -# ifdef MNSIZE -EXTERN char bytesizeops[]; -# endif -#endif -EXTERN char ops[]; -EXTERN char page1ops[]; -EXTERN char page2ops[]; -EXTERN char regs[]; -#ifdef I80386 -EXTERN char typesizes[]; -#endif - -#ifdef DEBUG -unsigned nhash; -unsigned nlookup; -unsigned nsym; -unsigned nx[30]; -FORWARD void printchain P((void)); -#endif - -FORWARD void install P((register char *keyptr, unsigned data)); - -PUBLIC void inst_keywords() -{ - install(regs, REGBIT); -#ifdef I80386 - install(typesizes, SIZEBIT); -#endif - install(ops, 0); - install(page1ops, PAGE1); - install(page2ops, PAGE2); -#ifdef I80386 -# ifdef MNSIZE - install(bytesizeops, PAGE1 | PAGE2); -# endif -#endif -} - -PRIVATE void install(keyptr, data) -register char *keyptr; -unsigned data; -{ - char lowcasebuf[20]; - unsigned namelength; - char *nameptr; - char *namend; - register struct sym_s *symptr; - - while (*keyptr != 0) - { - namelength = *keyptr++; - lineptr = (symname = keyptr) + namelength; - for (nameptr = lowcasebuf, namend = lowcasebuf + namelength; - nameptr < namend;) - { - if (*keyptr < 'A' || *keyptr > 'Z') - *nameptr++ = *keyptr++; - else - *nameptr++ = *keyptr++ + ('a' - 'A'); - } - symptr = lookup(); - symptr->type = MNREGBIT; - symptr->data = data; - symptr->value_reg_or_op.op.routine = *keyptr; - symptr->value_reg_or_op.op.opcode = keyptr[1]; - lineptr = (symname = lowcasebuf) + namelength; - symptr = lookup(); - symptr->type = MNREGBIT; - symptr->data = data; - symptr->value_reg_or_op.op.routine = *keyptr; - symptr->value_reg_or_op.op.opcode = keyptr[1]; - keyptr += 2; - } -} - -/* Lookup() searches symbol table for the string from symname to lineptr - 1. - * If string is not found and ifflag is TRUE, string is added to table, with - * type = 0 - * data = inidata (RELBIT | UNDBIT, possibly with IMPBIT | SEGM) - * Returns pointer to symbol entry (NULL if not found and not installed) - * unless symbol table overflows, when routine aborts. - */ - -PUBLIC struct sym_s *lookup() -{ - struct sym_s **hashptr; - register char *nameptr; - register struct sym_s *symptr; - register unsigned hashval; - register unsigned length; -#ifdef DEBUG - int tries; - - ++nlookup; - tries = 0; -#endif - - /* Hash function is a weighted xor of 1 to 4 chars in the string. - * This works seems to work better than looking at all the chars. - * It is important that the function be fast. - * The string comparision function should also be fast and it helps - * if it is optimized for mostly identical comparisions. - * The multiplication by MULTIPLIER should compile as a shift. - */ - -#define MULTIPLIER (SPTSIZ / (1 << USEFUL_BITS_IN_ASCII)) -#define USEFUL_BITS_IN_ASCII 6 - - nameptr = lineptr; - length = nameptr - symname; - if (length <= 3) - { - if (length <= 2) - hashval = hconv(nameptr[-1]) * MULTIPLIER; - else - hashval = hconv(nameptr[-2]) * MULTIPLIER, - hashval ^= hconv(nameptr[-1]); - } - else - hashval = hconv(nameptr[-(length / 2)]) * MULTIPLIER, - hashval ^= hconv(nameptr[-2]) << 2, - hashval ^= hconv(nameptr[-1]); - nameptr = symname; - if ((symptr = *(hashptr = spt + - (hashval ^ (hconv(nameptr[0]) << 1)) % SPTSIZ)) - != NULL) - { - do - { -#ifdef DEBUG - if (tries != 0) - --nx[tries]; - ++tries; - if (tries < sizeof nx / sizeof nx[0]) - ++nx[tries]; - if (tries >= 5) - printchain(hashptr - spt) -#endif - if ((unsigned char) length != symptr->length) - continue; - if (memcmp(symptr->name, nameptr, length) == 0) - return symptr; - } - while ((symptr = symptr->next) != NULL); - - /* Calculate last non-NULL hash ptr. - * This is faster than keeping hashptr up to date in previous loop - * since most lookups are successful and hash ptr is not needed. - */ - do - { - symptr = *hashptr; - hashptr = &symptr->next; - } - while (symptr->next != NULL); - } - if (!ifflag) - return NULL; - align(heapptr); - if (heapptr >= heapend) - fatalerror(SYMOV); -#ifdef DEBUG - ++nsym; - if (hashptr >= spt && hashptr < spt + SPTSIZ) - ++nhash; -#endif - *hashptr = symptr = (struct sym_s *) heapptr; - symptr->type = 0; - symptr->data = inidata; - symptr->length = length; - symptr->value_reg_or_op.value = (unsigned) (symptr->next = NULL); - heapptr = symptr->name; - do - *heapptr++ = *nameptr++; - while (--length != 0); - *heapptr++ = 0; - return symptr; -} - -#ifdef DEBUG - -static void printchain(hashval) -unsigned hashval; -{ - register struct sym_s *symptr; - - printf("%04x ", hashval); - for (symptr = spt[hashval]; symptr != NULL; symptr = symptr->next) - printf("%s ", symptr->name); - printf("\n"); -} - -#endif - -PUBLIC void statistics() -{ -#ifdef DEBUG - int i; - int weight; - - for (i = 0; i < SPTSIZ; ++i) - printchain(i); - printf("nhash = %d, nsym = %d, nlookup = %d nx =\n", nhash, nsym, nlookup); - weight = 0; - for (i = 0; i < 30; ++i) - { - printf("%5d", nx[i]); - weight += nx[i] * i; - } - printf("\n"); - printf("weight = %d%d\n", w; -#endif -} diff --git a/bin86-0.3/as/todo b/bin86-0.3/as/todo deleted file mode 100644 index 56c5424..0000000 --- a/bin86-0.3/as/todo +++ /dev/null @@ -1,10 +0,0 @@ -Improve string escaping. - -Produce bsd symbol tables. - -Accept gas format. - -Decide how to choose between 8-bit and 32-bit branches. 16-bit branches in -32-bit mode are unusable because top 16 bits of PC are messed up. - -Limit insns to specified processor (warn for 386 insns on 8086). diff --git a/bin86-0.3/as/type.h b/bin86-0.3/as/type.h deleted file mode 100644 index cb2aed5..0000000 --- a/bin86-0.3/as/type.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * bin86/as/type.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* type.h - types for assembler */ - -/* redefine foo_t's because their use has become non-portable */ - -#define bool_t bool_T -#define count_t count_T -#define fd_t fd_T -#define indcount_t indcount_T -#define offset_t offset_T -#define opcode_t opcode_T -#define opsize_t opsize_T -#define scale_t scale_T -#define sem_t sem_T -#define smallcount_t smallcount_T -#define soffset_t soffset_T -#define u8_t u8_T -#define u16_t u16_T -#define u32_t u32_T - -typedef unsigned char bool_t; -typedef int bool_pt; /* change to int for ANSI C */ -typedef unsigned count_t; -typedef unsigned error_pt; -typedef int fd_t; -typedef unsigned char indcount_t; -#ifdef I80386 -typedef unsigned long offset_t; -typedef long soffset_t; -# define SIZEOF_OFFSET_T 4 /* non-portable */ -#endif -#ifdef MC6809 -typedef unsigned offset_t; -typedef int soffset_t; -# define SIZEOF_OFFSET_T 2 /* but sizeof (offset_t) often breaks cpp */ -#endif -typedef unsigned opcode_pt; -typedef unsigned char opcode_t; -typedef unsigned opsize_pt; -typedef unsigned char opsize_t; -typedef unsigned reg_pt; -typedef unsigned char scale_t; -typedef unsigned char smallcount_t; -typedef /* signed */ char sem_t; -typedef unsigned u16_pt; -typedef unsigned short u16_t; -typedef unsigned long u32_pt; -typedef unsigned long u32_t; - -/* symbol table entry */ - -struct sym_s -{ - struct sym_s *next; /* next symbol in hash chain (NULL if none) */ - /* zero offset because it is accessed most */ - unsigned char type; - unsigned char data; /* flags valid for expressions as well as syms*/ - union - { - offset_t value; /* value, if sym is a label */ - unsigned char reg; /* register code, if sym is a register */ - struct - { - unsigned char routine; /* routine number */ - opcode_t opcode; /* opcode, if sym is a hardware op */ - } - op; /* if sym is pseudo-op or hardware op */ - } - value_reg_or_op; - unsigned char length; /* length of symbol string */ - char name[1]; /* string of variable length */ -}; - -/* address */ - -struct address_s -{ - offset_t offset; - unsigned char data; - struct sym_s *sym; -}; - -#ifdef I80386 - -/* effective address */ - -struct ea_s -{ - indcount_t indcount; - opsize_t size; - reg_pt base; - reg_pt index; - scale_t scale; - struct address_s displ; -}; - -#endif - -/* flags */ - -struct flags_s -{ - bool_t global; - bool_t current; - int semaphore; -}; - -/* location counter */ - -struct lc_s -{ - unsigned char data; - offset_t lc; -}; - -/* string chain */ - -struct schain_s -{ - struct schain_s *next; - char string[2]; /* variable length */ -}; - -/* block stack */ - -struct block_s -{ - unsigned char data; - unsigned char dp; - offset_t lc; -}; - -/* if stack */ - -struct if_s -{ - bool_t ifflag; - bool_t elseflag; -}; - -/* macro stack */ - -struct macro_s -{ - char *text; - struct schain_s *parameters; -}; - -/* symbol listing format */ - -struct sym_listing_s -{ - char name[SYMLIS_NAMELEN]; - char zname[2]; - char segm[1]; - char pad1[1]; - char value[4]; - char pad2[1]; - char ar[1]; - char pad3[1]; - char cein[1]; - char pad4[1]; - char nullterm; -}; - -#if __STDC__ -typedef void (*pfv)(void); -#else -typedef void (*pfv)(); -#endif - -#include "proto.h" diff --git a/bin86-0.3/as/work/q b/bin86-0.3/as/work/q deleted file mode 100644 index 0f6fefe..0000000 --- a/bin86-0.3/as/work/q +++ /dev/null @@ -1,4 +0,0 @@ -for i in $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s -do - $a/as $i -3 -w -u -done diff --git a/bin86-0.3/as/work/r b/bin86-0.3/as/work/r deleted file mode 100644 index aca1637..0000000 --- a/bin86-0.3/as/work/r +++ /dev/null @@ -1,4 +0,0 @@ -for i in $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s $k/*.s -do - $lb/as $i -3 -w -u -done diff --git a/bin86-0.3/as/work/r-good b/bin86-0.3/as/work/r-good deleted file mode 100644 index 1fa22e6..0000000 --- a/bin86-0.3/as/work/r-good +++ /dev/null @@ -1,1183 +0,0 @@ -sgdt sidt sldt _aprefix _oprefix -sgdt sidt sldt _aprefix _oprefix -.byte CBW JB JNBE .C9 -sgdt sidt sldt _aprefix _oprefix -edx sal _notimmed _getimmed _yesimmed -sgdt sidt sldt _aprefix _oprefix _getshift -sgdt sidt sldt _aprefix _oprefix _getshift -sgdt sidt sldt _aprefix _oprefix _getshift -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -LCOMM REPE STOW .4 .4A -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -edx sal _notimmed _getimmed _yesimmed -edx sal _notimmed _getimmed _yesimmed -INC JNA REPNE SETNC .131 -edx sal _notimmed _getimmed _yesimmed -edx sal _notimmed _getimmed _yesimmed -qword outsd rcrb rorb _mdivmul -JNL ROL CMPB .2D .140 -BNE INW JMPI LOOPNE .141 -dr0 SALB SHLB .7D .154 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -EXPORT RCLB ROLB .7F .156 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -edx sal _notimmed _getimmed _yesimmed -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -scasw stosw setc smsw .19A -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -XLAT ADDB ANDB .B8 .1B4 -LGDT LIDT LLDT INCB .B4 -LGDT LIDT LLDT INCB .B4 .1B8 -LGDT LIDT LLDT INCB .B4 .1B8 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -.byte CBW JB JNBE .C9 -BH JG PUSHA .F9 .1E9 -cmpsd iretd verr .FF .1EF -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -ELSEIF PUSHAD REP .E8 .1F4 -word insd xorb .EB ..FFFF -byte cmpsw .E .EA ..FFFE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -CWD MOVSX NOTB .102 .202 -LCOMM REPE STOW .4 .4A .111 -LCOMM REPE STOW .4 .4A .111 -edx sal _notimmed _getimmed _yesimmed -INC JNA REPNE SETNC .131 -INB LOOP SETNB .134 .234 -BMI .2 .2A .139 .239 -JNL ROL CMPB .2D .140 -JNL ROL CMPB .2D .140 .240 -JNL ROL CMPB .2D .140 .240 -LCOMM REPE STOW .4 .4A .111 .211 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -LGDT LIDT LLDT INCB .B4 .1B8 -.byte CBW JB JNBE .C9 .1C1 -.byte CBW JB JNBE .C9 .1C1 -edx sal _notimmed _getimmed _yesimmed -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -edx sal _notimmed _getimmed _yesimmed -word insd xorb .EB ..FFFF .1FF -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -LCOMM REPE STOW .4 .4A .111 .211 -LCOMM REPE STOW .4 .4A .111 .211 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -edx sal _notimmed _getimmed _yesimmed -edx sal _notimmed _getimmed _yesimmed -INC JNA REPNE SETNC .131 .231 -INC JNA REPNE SETNC .131 .231 -edx sal _notimmed _getimmed _yesimmed -edx sal _notimmed _getimmed _yesimmed -qword outsd rcrb rorb _mdivmul -qword outsd rcrb rorb _mdivmul -JNL ROL CMPB .2D .140 .240 -JNL ROL CMPB .2D .140 .240 -BNE INW JMPI LOOPNE .141 -BNE INW JMPI LOOPNE .141 -dr0 SALB SHLB .7D .154 -dr0 SALB SHLB .7D .154 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -EXPORT RCLB ROLB .7F .156 -EXPORT RCLB ROLB .7F .156 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -edx sal _notimmed _getimmed _yesimmed -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -scasw stosw setc smsw .19A -retf testb _segword _marpl .19B -scasw stosw setc smsw .19A -ENDB SAR SBB .A0 .1A0 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -jcxe jecxe .A .AA .1AA -XLAT ADDB ANDB .B8 .1B4 -XLAT ADDB ANDB .B8 .1B4 -LGDT LIDT LLDT INCB .B4 .1B8 -LGDT LIDT LLDT INCB .B4 .1B8 -LGDT LIDT LLDT INCB .B4 .1B8 -LGDT LIDT LLDT INCB .B4 .1B8 -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -.byte CBW JB JNBE .C9 .1C1 -.byte CBW JB JNBE .C9 .1C1 -byte cmpsw .E .EA ..FFFE .1FE -BH JG PUSHA .F9 .1E9 -BH JG PUSHA .F9 .1E9 -lodsw lmsw verw .FC .1EC -cmpsd iretd verr .FF .1EF -cmpsd iretd verr .FF .1EF -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -ELSEIF PUSHAD REP .E8 .1F4 -ELSEIF PUSHAD REP .E8 .1F4 -word insd xorb .EB ..FFFF .1FF -word insd xorb .EB ..FFFF .1FF -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -byte cmpsw .E .EA ..FFFE .1FE -CWD MOVSX NOTB .102 .202 -CWD MOVSX NOTB .102 .202 -LCOMM REPE STOW .4 .4A .111 .211 -LCOMM REPE STOW .4 .4A .111 .211 -LCOMM REPE STOW .4 .4A .111 .211 -edx sal _notimmed _getimmed _yesimmed -INC JNA REPNE SETNC .131 .231 -INC JNA REPNE SETNC .131 .231 -IN JNC SETNA .133 .233 -INB LOOP SETNB .134 .234 -CMC JNE SETNG .135 .235 -INB LOOP SETNB .134 .234 -BMI .2 .2A .139 .239 -BMI .2 .2A .139 .239 -JNL ROL CMPB .2D .140 .240 -JNL ROL CMPB .2D .140 .240 -JNL ROL CMPB .2D .140 .240 -JNL ROL CMPB .2D .140 .240 -0000 .bss AAA .1C3 -0001 .list EXTERN .1C4 -0002 .byte CBW JB JNBE .C9 .1C1 -0003 AAD .1C2 -0004 .1C7 -0005 .D0 .1C8 -0006 .data DAA JBE .1C5 -0007 LAR .1C6 -0008 .C3 -0009 RCL .C4 .1D0 -000a .C1 .1C9 -000b SGDT SIDT SLDT .C2 -000c AAM .C7 -000d .C8 -000e .C5 -000f EBX DECb .C6 -0010 .1D7 -0011 .1D8 -0012 AAS JA .D9 .1D5 -0013 RCR .1D6 -0014 DAS .1D3 -0015 .C0 .1D4 -0016 DB JAE JNAE .1D1 -0017 EBP SETDP -0018 .D3 -0019 .D4 -001a .D1 -001b FAR .D2 -001c .D7 -001d POPAD .D8 .1C0 -001e .D5 .1D9 -001f EAX .D6 -0020 BLOCK BCC SETAE -0021 .1B0 -0022 .A9 .1A9 -0023 .warn -0024 CDQ -0025 SCAB .B0 -0026 -0027 -0028 FCC .org .A3 .1A3 -0029 ADCB .A4 .1A4 -002a .A1 .1A1 -002b FCB LODB .A2 .1A2 -002c .A7 .1A7 -002d .word .A8 .1A8 -002e .A5 .1A5 -002f EDX SAL .A6 .1A6 -0030 EDI BCS -0031 SBBB SUBB -0032 ADC JC SCAW .B9 -0033 ADD -0034 LDS LOCK SETBE -0035 ENDB SAR SBB .A0 .1A0 -0036 DD SCAS .1B9 -0037 -0038 LODS .B3 .1B7 -0039 LGDT LIDT LLDT INCB .B4 .1B8 -003a .B1 .1B5 -003b FDB .B2 .1B6 -003c CWDE LODW .B7 .1B3 -003d XLAT ADDB ANDB .B8 .1B4 -003e .B5 .1B1 -003f ECX .B6 .1B2 -0040 IF -0041 -0042 IFC .199 -0043 -0044 .zerow DEC LES XCHG -0045 .text SHR -0046 -0047 -0048 .193 -0049 ENTER _Ev .194 -004a _Ew .191 -004b _Ex .192 -004c .197 -004d SAHF _source2 .198 -004e .195 -004f .196 -0050 -0051 -0052 BEQ JE -0053 IRET -0054 LFS -0055 .190 -0056 LEA -0057 XCHGB -0058 SETGE .9C -0059 POPFD .9D -005a .9 .9A -005b .9B -005c NEG -005d -005e .9E -005f GET SHL .9F -0060 -0061 -0062 SEG .E9 -0063 NEGB -0064 LGS -0065 .F0 .1E0 -0066 BGE .1F9 -0067 -0068 .E3 .1F7 -0069 _Gv .E4 .1F8 -006a _Gw .E1 .1F5 -006b _Gx .E2 .1F6 -006c .E7 .1F3 -006d ELSEIF PUSHAD REP .E8 .1F4 -006e JNGE .E5 .1F1 -006f .E6 .1F2 -0070 AH -0071 BGT RET .1F0 -0072 BH JG PUSHA .F9 .1E9 -0073 -0074 CH -0075 .E0 -0076 DH JGE -0077 SET PUSHF -0078 .F3 .1E3 -0079 PUSHFD .F4 .1E4 -007a BHI .F1 .1E1 -007b .F2 .1E2 -007c .F7 .1E7 -007d .F8 .1E8 -007e .F5 .1E5 -007f LAHF .F6 .1E6 -0080 tr7 .187 -0081 .188 -0082 J .185 -0083 tr6 .186 -0084 .183 -0085 MULB .184 -0086 DI .181 -0087 .182 -0088 .6C -0089 .6D -008a JNLE .6 .6A -008b .6B -008c PUBLIC -008d IMULB .170 -008e .6E .189 -008f .6F -0090 CALLI .173 -0091 .174 -0092 .171 -0093 CALL DIV .172 -0094 .177 -0095 .178 -0096 .175 -0097 .176 -0098 .5C -0099 .5D .180 -009a .5 .5A .179 -009b .5B -009c -009d -009e ELSEIFC .5E -009f WAIT .5F -00a0 dr7 -00a1 FAIL BLT -00a2 JL -00a3 dr6 -00a4 SI dr3 -00a5 cr2 IDIV .150 -00a6 cr3 dr1 JLE .169 -00a7 dr2 IMPORT -00a8 .8C .167 -00a9 .8D .168 -00aa .8 .8A .165 -00ab .8B .166 -00ac .163 -00ad ENDIF HLT .164 -00ae .8E .161 -00af .8F .162 -00b0 AL BHIS -00b1 .160 -00b2 BL .159 -00b3 -00b4 CL -00b5 -00b6 DL BLE CLC -00b7 CLD -00b8 .7C .153 -00b9 dr0 SALB SHLB .7D .154 -00ba .7 .7A .151 -00bb cr0 SHLD .7B .152 -00bc BLO CLI SETLE .157 -00bd .158 -00be .7E .155 -00bf EXPORT RCLB ROLB .7F .156 -00c0 IN JNC SETNA .133 .233 -00c1 INB LOOP SETNB .134 .234 -00c2 INC JNA REPNE SETNC .131 .231 -00c3 JNB LOOPZ .132 .232 -00c4 JNG SETNE .137 .237 -00c5 .138 .238 -00c6 CMC JNE SETNG .135 .235 -00c7 ARPL .136 .236 -00c8 BLOS .2C -00c9 JNL ROL CMPB .2D .140 .240 -00ca BMI .2 .2A .139 .239 -00cb CMP LOOPNZ SETNL .2B -00cc JNO -00cd JNP -00ce SETNO .2E -00cf SETNP .2F -00d0 JNS .147 -00d1 .148 -00d2 INS POPA SETNS .145 -00d3 AND INT ROR .146 -00d4 SP .143 -00d5 .144 -00d6 BNE INW JMPI LOOPNE .141 -00d7 POPF .142 -00d8 .1C -00d9 SETNZ .1D -00da CMPS .1 .1A -00db END JNZ .1B -00dc SETNLE -00dd JMP .130 .230 -00de CMPW LOOPE .1E .149 -00df REPNZ XOR .1F -00e0 BPS -00e1 .120 .220 -00e2 JP .119 .219 -00e3 RMB -00e4 -00e5 BOUND -00e6 JPE SETPO -00e7 IDENT -00e8 SETNGE .4C .113 .213 -00e9 NOT .4D .114 .214 -00ea LCOMM REPE STOW .4 .4A .111 .211 -00eb .4B .112 .212 -00ec JPO SETPE .117 .217 -00ed MOV .118 .218 -00ee STOS .4E .115 .215 -00ef .4F .116 .216 -00f0 BPC SETNAE -00f1 POP -00f2 BP JO -00f3 -00f4 LOC SETNBE -00f5 NOP .110 .210 -00f6 .129 .229 -00f7 REPZ -00f8 COMM .3C .127 .227 -00f9 BPL .3D .128 .228 -00fa .3 .3A .125 .225 -00fb .3B .126 .226 -00fc .123 .223 -00fd STOB .124 .224 -00fe .3E .121 .221 -00ff .3F .122 .222 -0100 -0101 -0102 -0103 DIVB -0104 SS -0105 STR -0106 -0107 -0108 -0109 -010a ORG MOVW -010b IMUL -010c OR -010d ORB -010e MOVS -010f -0110 -0111 -0112 BR -0113 -0114 -0115 IDIVB -0116 LEAVE STC -0117 STD -0118 -0119 -011a -011b -011c EQU STI -011d MOVB -011e -011f -0120 ESI BTS -0121 -0122 -0123 BTR -0124 CS LSS -0125 -0126 DS -0127 ESP .even JCXZ JECXZ BSF -0128 ES -0129 -012a FS -012b -012c GS -012d -012e -012f -0130 BTC -0131 -0132 JS BT -0133 BSR -0134 -0135 -0136 -0137 LTR -0138 -0139 -013a JCXE JECXE -013b -013c -013d LSL -013e -013f PTR -0140 BVS -0141 SETZ -0142 MACRO -0143 -0144 ENTRY -0145 -0146 -0147 -0148 -0149 PWORD -014a SETS -014b -014c -014d SCASB STOSB -014e _jumps_long -014f OUT SCASD STOSD -0150 BVC -0151 DWORD EXTRN -0152 -0153 MUL XLATB SETL -0154 -0155 -0156 RETI SETO -0157 SETP -0158 INCLUDE SETA -0159 SETB -015a SCASW STOSW SETC SMSW -015b RETF TESTB -015c SETE -015d FWORD TEST -015e TBYTE SETG -015f -0160 _calljmp_kludge .107 .207 -0161 OUTB .108 .208 -0162 INTO OUTSW .105 .205 -0163 .106 .206 -0164 ELSE .103 .203 -0165 SUB .104 .204 -0166 DW MOVSW .101 .201 -0167 CWD MOVSX NOTB .102 .202 -0168 LODSW LMSW VERW -0169 -016a CLTS -016b -016c -016d CMPSB -016e INSW .109 .209 -016f CMPSD IRETD VERR -0170 AX -0171 MOVSB PUSH SARB SHRB -0172 BX .ascii OUTS -0173 .extern MOVSD SHRD -0174 CX -0175 .map OUTSB -0176 DX .space OUTW -0177 QWORD OUTSD RCRB RORB -0178 -0179 INSB .100 .200 -017a BYTE CMPSW -017b WORD INSD XORB -017c -017d LODSD -017e -017f LODSB -0180 -0181 -0182 JZ -0183 -0184 -0185 -0186 .comm -0187 -0188 -0189 -018a -018b -018c -018d -018e -018f -0190 _mgroup1 -0191 .maclist _mgroup2 -0192 _mgroup3 -0193 -0194 -0195 .globl _mgroup6 -0196 _mgroup7 -0197 _mgroup8 -0198 .long -0199 -019a -019b -019c -019d -019e -019f -01a0 -01a1 -01a2 -01a3 -01a4 -01a5 -01a6 .lcomm -01a7 -01a8 -01a9 -01aa -01ab -01ac -01ad -01ae -01af -01b0 -01b1 -01b2 -01b3 -01b4 -01b5 -01b6 -01b7 -01b8 -01b9 -01ba -01bb -01bc -01bd -01be -01bf -01c0 -01c1 -01c2 -01c3 -01c4 -01c5 -01c6 -01c7 -01c8 -01c9 -01ca .define -01cb -01cc -01cd .short -01ce -01cf -01d0 -01d1 .fail -01d2 -01d3 -01d4 -01d5 -01d6 -01d7 -01d8 -01d9 -01da -01db -01dc -01dd -01de -01df -01e0 -01e1 -01e2 -01e3 -01e4 .blkw -01e5 -01e6 -01e7 -01e8 -01e9 -01ea -01eb -01ec -01ed -01ee -01ef .align -01f0 -01f1 -01f2 -01f3 .blkb -01f4 -01f5 -01f6 -01f7 -01f8 -01f9 -01fa -01fb MOVZX -01fc -01fd -01fe -01ff -0200 if -0201 _gsymptr -0202 seg -0203 -0204 lgs -0205 bound -0206 bge setpo -0207 ident _mimul -0208 setnge _mcalli -0209 -020a lcomm repe stow -020b -020c setpe -020d rep -020e stos -020f -0210 setnae _getunary -0211 bgt ret -0212 je -0213 -0214 setnbe -0215 -0216 jge -0217 set repz -0218 comm -0219 -021a bhi -021b -021c -021d stob -021e -021f -0220 setna -0221 loop setnb -0222 ifc repne setnc -0223 loopz -0224 dec les setne -0225 shr -0226 setng -0227 arpl -0228 blos -0229 cmpb -022a _fqflag _fdflag _fcflag -022b loopnz setnl _mshort -022c -022d _mloadfullpointer -022e setno -022f setnp -0230 ah -0231 _min -0232 bh beq jg popa setns -0233 -0234 ch lfs -0235 -0236 dh jmpi lea loopne -0237 popf -0238 -0239 setnz -023a cmps -023b -023c neg setnle _buildea _yes_samesize -023d _sib -023e cmpw loope -023f get repnz shl _mmovx -0240 bcc _getbinary -0241 fail -0242 jb -0243 -0244 cdq -0245 idiv _minher32 -0246 -0247 import -0248 fcc -0249 _minher16 -024a -024b fcb -024c _displsize _getcomma -024d endif -024e -024f edx sal _notimmed _getimmed _yesimmed -0250 edi bcs bhis -0251 _mmov -0252 adc ja -0253 add -0254 lds _mshdouble -0255 sar sbb -0256 db -0257 -0258 -0259 salb shlb -025a _datatoobig -025b fdb shld _immcount -025c setle -025d -025e -025f ecx export rclb rolb -0260 aaa -0261 -0262 cbw -0263 aad -0264 -0265 mulb -0266 daa jbe -0267 lar -0268 -0269 rcl -026a jnle -026b _mint -026c public aam -026d imulb -026e -026f ebx -0270 calli -0271 -0272 aas jc -0273 call rcr -0274 das _opcode _asld_compatible -0275 -0276 dd jae -0277 ebp -0278 -0279 -027a -027b far -027c _mnsize -027d -027e elseifc -027f eax wait -0280 bps in -0281 _immadr -0282 -0283 rmb .WARN negb -0284 -0285 -0286 jpe -0287 _mtest -0288 .ORG -0289 not _baseind16 _direction -028a _chkabs -028b -028c jpo -028d elseif .WORD mov pushad -028e jnge -028f -0290 bpc _buildimm -0291 pop -0292 pusha .10E .20E -0293 _lbranch .10F .20F -0294 sp loc .10C .20C -0295 nop .10D _mretf .20D -0296 .10A .20A -0297 pushf .10B .20B -0298 -0299 bpl pushfd -029a -029b _buildsegword -029c -029d -029e -029f lahf -02a0 .BSS jnc -02a1 .LIST inb -02a2 .BYTE inc jna jp -02a3 jnb -02a4 jng xchg -02a5 -02a6 .DATA cmc jne _mxchg -02a7 -02a8 _minhera -02a9 enter jnl rol -02aa bmi _getaccumreg _regchk -02ab cmp -02ac jno -02ad jnp sahf -02ae _lc _mincdec -02af -02b0 jns -02b1 -02b2 bp ins jo -02b3 and int iret ror -02b4 -02b5 -02b6 bne inw _mbcc _mjcc -02b7 xchgb _notindirect _getindirect -02b8 setge -02b9 popfd -02ba -02bb end jnz _regsegword _mcall -02bc -02bd jmp -02be -02bf xor -02c0 TR7 block setae -02c1 blt -02c2 j -02c3 TR6 -02c4 -02c5 scab -02c6 di jle -02c7 -02c8 -02c9 adcb _databuf -02ca _notsegreg _indregchk _mseg _pcrflag -02cb lodb -02cc _mlea -02cd hlt _buildregular -02ce -02cf decb -02d0 _lcdata -02d1 sbbb subb -02d2 scaw _regbits -02d3 -02d4 lock setbe _segoverride -02d5 endb -02d6 ble clc scas -02d7 cld _mnegnot -02d8 lods -02d9 lgdt lidt lldt incb -02da -02db _mpushpop -02dc blo cli cwde lodw -02dd xlat addb andb -02de _nonimpexpres -02df _mret _showrelbad -02e0 DR7 _reldata _page -02e1 extern -02e2 jl jnbe -02e3 DR6 -02e4 si DR3 .ZEROW -02e5 CR2 .TEXT -02e6 CR3 DR1 -02e7 DR2 -02e8 -02e9 -02ea -02eb sgdt sidt sldt _aprefix _oprefix _getshift _sprefix -02ec -02ed _minher -02ee -02ef -02f0 al -02f1 -02f2 bl -02f3 div -02f4 cl -02f5 -02f6 dl jnae -02f7 setdp -02f8 -02f9 DR0 _mjcxz -02fa -02fb CR0 -02fc -02fd popad -02fe -02ff _target -0300 _rm -0301 -0302 .39 -0303 -0304 -0305 sub .40 -0306 .LCOMM -0307 cwd -0308 .33 -0309 .34 -030a .31 .12E .22E -030b .32 .12F .22F -030c .37 .12C .22C -030d .38 .12D .22D -030e .35 .12A .22A -030f .36 .12B .22B -0310 -0311 -0312 .49 -0313 -0314 -0315 .30 -0316 -0317 -0318 .43 .11C .21C -0319 .44 .11D .21D -031a .41 .11A .21A -031b movzx .42 .11B .21B -031c .47 -031d USE16 .48 -031e .45 .11E .21E -031f .46 .11F .21F -0320 bvs -0321 -0322 .19 .14E -0323 .14F -0324 .14C -0325 .20 .14D -0326 .COMM dw .14A -0327 .14B -0328 .13 -0329 .14 -032a .11 -032b .12 -032c .17 -032d .18 -032e _ss .15 -032f out .16 -0330 ax bvc .13C .23C -0331 .MACLIST USE32 .13D .23D -0332 bx .29 .13A .23A -0333 mul .13B .23B -0334 cx -0335 .GLOBL .10 -0336 dx .13E .23E -0337 .13F .23F -0338 .LONG .23 -0339 .24 -033a .21 -033b .22 -033c .27 -033d .28 -033e .25 -033f .26 -0340 esi bts -0341 _mEvGv -0342 .79 -0343 btr -0344 ss .BLKW lss -0345 .80 -0346 -0347 esp bsf -0348 .73 .15C -0349 .74 .15D _mGvEv -034a .71 .15A -034b .72 .15B -034c or .77 -034d .78 -034e .75 .15E -034f .ALIGN .76 .15F -0350 btc -0351 -0352 br .89 -0353 .BLKB bsr -0354 -0355 .70 -0356 -0357 ltr -0358 .83 -0359 .84 -035a .81 .16E -035b .82 .16F -035c .87 .16C -035d use16 lsl .88 .16D -035e .85 .16A -035f ptr .86 .16B -0360 .17C -0361 .17D -0362 .59 .17A -0363 .17B -0364 cs -0365 str .60 -0366 ds .17E -0367 .17F -0368 es .53 -0369 .54 -036a fs org .DEFINE .51 -036b .52 -036c gs .57 -036d .SHORT orb .58 -036e .55 -036f .56 -0370 _sym -0371 .FAIL use32 -0372 js bt .69 .18E -0373 .18F -0374 .18C -0375 .50 .18D -0376 stc .18A -0377 std .18B -0378 .63 -0379 .64 -037a .61 -037b .62 -037c equ sti .67 -037d .68 -037e .65 -037f .66 -0380 _source _buildunary -0381 outb -0382 into outsw -0383 -0384 else -0385 _factor -0386 movsw -0387 .EVEN movsx notb -0388 lodsw lmsw verw .FC .1EC -0389 .FD .1ED -038a clts .F .FA .1EA -038b .FB .1EB -038c -038d cmpsb -038e insw _expres .FE .1EE -038f cmpsd iretd verr .FF .1EF -0390 -0391 movsb push sarb shrb -0392 outs -0393 movsd shrd -0394 -0395 outsb -0396 outw -0397 qword outsd rcrb rorb _mdivmul -0398 .EC -0399 insb -039a byte cmpsw .E .EA ..FFFE .1FE -039b word insd xorb .EB ..FFFF .1FF -039c .1FC -039d lodsd .1FD -039e .EE .1FA -039f lodsb .EF _mout .1FB -03a0 -03a1 setz -03a2 macro .99 -03a3 -03a4 entry -03a5 _error _kgerror -03a6 _msetcc -03a7 -03a8 .93 -03a9 pword .94 -03aa sets .91 _notcsreg -03ab .92 -03ac .97 -03ad scasb stosb .98 _menter -03ae .95 -03af scasd stosd .96 -03b0 -03b1 dword extrn -03b2 -03b3 xlatb setl -03b4 -03b5 .90 -03b6 reti seto -03b7 setp -03b8 include seta .19C -03b9 setb .19D -03ba scasw stosw setc smsw .19A -03bb retf testb _segword _marpl .19B -03bc sete _getea -03bd fword test -03be tbyte setg .19E -03bf .19F -03c0 -03c1 -03c2 jz -03c3 -03c4 -03c5 -03c6 -03c7 jcxz jecxz -03c8 .BC -03c9 .BD -03ca .B .BA .1BE -03cb .BB .1BF -03cc _notbytesize .1BC -03cd .1BD -03ce .BE .1BA -03cf .BF .1BB -03d0 _getsym -03d1 -03d2 .ASCII -03d3 .EXTERN -03d4 -03d5 .MAP -03d6 .SPACE -03d7 -03d8 .AC .1AC -03d9 .AD .1AD -03da jcxe jecxe .A .AA .1AA -03db .AB .1AB -03dc _regsize _defsize -03dd -03de .AE .1AE -03df .AF .1AF -03e0 -03e1 -03e2 .1DE -03e3 divb _lcjump .1DF -03e4 .1DC -03e5 .1DD -03e6 _pass .1DA -03e7 .1DB -03e8 .DC -03e9 .DD -03ea movw .D .DA -03eb imul .DB _mbound -03ec _yeswordsize -03ed -03ee movs .DE -03ef .DF -03f0 _rmfunny .1CC -03f1 _postb .1CD -03f2 .1CA -03f3 .1CB -03f4 -03f5 idivb -03f6 leave .1CE -03f7 .1CF -03f8 .CC -03f9 .CD -03fa .C _getdxreg .CA -03fb .CB -03fc -03fd movb -03fe .CE -03ff _lastexp .CF -nhash = 731, nsym = 1463, nlookup = 18376 nx = - 011029 2760 2820 185 97 20 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 731 406 200 87 29 8 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -weight = 26368, compares = 27603 diff --git a/bin86-0.3/as/work/t b/bin86-0.3/as/work/t deleted file mode 100644 index 29ebfd6..0000000 --- a/bin86-0.3/as/work/t +++ /dev/null @@ -1,3 +0,0 @@ -cp work/$1 as -sync -time sh t1 diff --git a/bin86-0.3/as/work/t1 b/bin86-0.3/as/work/t1 deleted file mode 100644 index c2a47d5..0000000 --- a/bin86-0.3/as/work/t1 +++ /dev/null @@ -1,10 +0,0 @@ -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u -./as q -w -u diff --git a/bin86-0.3/as/work/z b/bin86-0.3/as/work/z deleted file mode 100644 index 108c07e..0000000 --- a/bin86-0.3/as/work/z +++ /dev/null @@ -1,5 +0,0 @@ -r q -w -u -_exit b -c -_nhash/x -_hid_spt+0x40/32x diff --git a/bin86-0.3/bcc/bcc.doc b/bin86-0.3/bcc/bcc.doc deleted file mode 100644 index 7f2a8ed..0000000 --- a/bin86-0.3/bcc/bcc.doc +++ /dev/null @@ -1,165 +0,0 @@ -Bcc options ------------ - -bcc [-03EGOPSVcegv] [-Aas_option] [-Bexecutable_prefix] [-Ccc1_option] - [-Ddefine] [-Iinclude_dir] [-Lld_option] [-Qc386_option] [-Ttmpdir] - [-Uundef] [-o outfile] [-fpt error] [ld_options] [infiles] - -The 6809 version does not support -0, -3 or -G. -Only the c386 version supports -Q. - -defaults (off or none except for these): --03 native -outfile stdout for preprocessor output - somewhere/file.[ci] -> file.s for compiler output - somewhere/file.[cis] -> file.o for assembler output - a.out for ld output - --0 8086 target (works even on 80386 host) --3 80386 target (works even on 8086 host) --A pass remainder of option to assembler (e.g. -A-l -Alistfile for a listing) --B prefix for executable search path (as usual; after the -B prefixes comes - the environment variable BCC_EXEC_PREFIX if that is set, followed by the - compiled-in default (something like /usr/libexec/i386/bcc/)) --C pass remainder of option to cc1 (e.g. -C-c for caller-saves) --D define (as usual) --E produce preprocessor output (as usual) --G produce gnu-Minix objects (link with gnu ld) --I include search path (as usual) --L pass remainder of option to linker --O optimize (does nothing) --P produce preprocessor output with no line numbers (as usual) --Q pass full option to c386 --S produce assembler file (as usual) --T temporary directory (overrides previous value and default; default is - from the environment variable TMPDIR if that is set, otherwise /tmp) --U undefine (as usual) --V print names of files being compiled --c produce object file (as usual) --e run the preprocess pass separately. This takes less memory, and may help - or harm by giving more traditional semantics like token pasting with /**/. --f error (float emulation not supported) --g produce debugging info (does nothing) --o output file name follows (assembler, object or executable) (as usual) --p error (profiling not supported) --t error (substitution of some cc passes not supported) --v print names and args of subprocesses being run - -Other options are passed to the linker, in particular -i-, -lx, -M, -m, -s. -The -i option is always passed to the linker but can be cancelled using -i-. - -This is supposed to match the V7 manual except for -0, -3, -A, -C, -G, -L, --T, -V, -e, -v and where not supported. - -cc1 options ----------- - -cc1 [-03EPcdfltw[-]] [-Ddefine] [-Iinclude_dir] [-Uundef] [-o outfile] [infile] - -The 6809 version does not support -0 or -3 but it supports -p. - -defaults (off or none except for these): --03 native --c on for 6809 --f on for 6809 -outfile stdout -infile stdin - --0 8086 target (works even on 80386 host) --3 80386 target (works even on 8086 host) --D define (as usual) --E produce preprocessor output (as usual) --I include search path (as usual) --P produce preprocessor output with no line numbers (as usual) --c produce code with caller saving regs before function calls --d print debugging information in assembly output --f produce code with 1st argument passed in a register --l produce code for 2 3 1 0 long byte order (only works in 16-bit versions) --o assembler output file name follows --p produce (almost) position-independent code --t print source code in assemby output --w print what cc1 thinks is the location counter in assembly output - -All the options except -D, -I and -o may be turned off by following the -option letter by a '-'. Options are processed left to right so the last -setting has precedence. - -The following is defined before option processing: - -__BCC__ 1 - -The following may be defined after option processing: - -__AS09__ 1 if 6809 version -__AS386_16__ 1 if -0 option on 80*86 -__AS386_32__ 1 if -3 option on 80*86 -__CALLER_SAVES__ 1 if -c option -__FIRST_ARG_IN_AX__ 1 if -f option on 80*86 -__FIRST_ARG_IN_X__ 1 if -f option on 6809 -__LONG_BIG_ENDIAN__ 1 if -l option -__POS_INDEPENDENT__ 1 if -p option on 6809 - -The following are standard builtins: - -__FILE__ stringized name of current input file -__LINE__ current line number - -As options ----------- - -as [-03agjuw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src - -The 6809 version does not support -0, -3, -a or -j. - -defaults (off or none except for these; no output is produced without a flag): --03 native -list stdout (beware of clobbering next arg) -name basename of the source name - --0 start with 16-bit code segment --3 start with 32-bit code segment --a enable partial compatibility with asld --b produce binary file, filename may follow (obsolete) --g only put global symbols in object file --j force all jumps to be long --l produce list file, filename may follow --m print macro expansions in listing --n name of module follows (goes in object instead of source name) --o produce object file, filename follows --s produce symbol file, filename follows (obsolete) --u take undefined symbols as imported-with-unspecified segment --w don't print warnings - -The -u and -w options are perhaps back to front because they are needed for -cc1 output and Minix's make does the wrong thing with .s files left around. -However, all assembler code not written by compilers should assemble with -them turned off. - -Ld options ----------- - -For the version that produces Minix a.out format: -ld [-03Mims[-]] [-T textaddr] [-llib_extension] [-o outfile] infile... - -For the version that produces gnu-Minix a.out format: -ld [-03Mimrs[-]] [-T textaddr] [-llib_extension] [-o outfile] infile... - -The 6809 version does not support -i or -r. - -defaults (off or none except for these): --03 native -outfile a.out - --0 produce header with 16-bit magic and use subdir i86 for -lx --3 produce header with 32-bit magic and use subdir i386 for -lx --M print symbols linked on stdout --T text base address follows (in format suitable for strtoul) --i separate I&D output --lx add library /local/lib/subdir/libx.a to list of files linked --m print modules linked on stdout --o output file name follows --r produce output suitable for further relocation --s strip symbols - -All the options except -T, -l and -o may be turned off by following the option -letter by a '-', as for cc1. diff --git a/bin86-0.3/bccfp/Makefile b/bin86-0.3/bccfp/Makefile deleted file mode 100644 index 6caa362..0000000 --- a/bin86-0.3/bccfp/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# Makefile for bcc 386 software floating point library - -.SUFFIXES: .x # .x files are .s files that need C-preprocessing -.x.o: - $(CPP) $(CPPFLAGS) $< >tmp - $(AS) tmp -n $* -o $@ - -AS =as -3 -CFLAGS =-O -CPP =/lib/cpp -CPPFLAGS =-P -FPDIST =Makefile $(FPSRC) test.c bccfp.tex -FPSRC =fadd.x fcomp.x fdiv.x fmul.x fbsr.x \ - fperr.c fperror.x fptoi.x fpushd.x fpulld.x \ - fpushi.x fpushf.x fpullf.x frexp.x ftst.x \ - gcclib.x \ - fabs.x ldexp.x modf.c \ - fperr.h fplib.h -FPOBJ =fadd.o fcomp.o fdiv.o fmul.o fpbsr.o \ - fperr.o fperror.o fptoi.o fpushd.o fpulld.o \ - fpushi.o fpushf.o fpullf.o frexp.o ftst.o \ - fabs.o ldexp.o modf.o -JUNK =tmp -LIB =. - -test: test.c $(LIB)/libfp.a - $(CC) -o $@ test.c $(LIB)/libfp.a -lm - -$(FPOBJ): fplib.h -fperr.c fperror.x: fperr.h - -$(LIB)/libfp.a: $(FPOBJ) - ar rc $(LIB)/libfp.a $(FPOBJ) - rm -f $(JUNK) - -dist: $(FPDIST) - /bin/tar cvf - $(FPDIST) | /bin/compress -b 13 >bccfp.tar.Z - uue bccfp.tar.Z - -clean: - rm -f $(FPOBJ) $(JUNK) test - -realclean: clean - rm -f $(LIB)/libfp.a bccfp.tar.Z bccfp.uue diff --git a/bin86-0.3/bccfp/changes b/bin86-0.3/bccfp/changes deleted file mode 100644 index 2cc632a..0000000 --- a/bin86-0.3/bccfp/changes +++ /dev/null @@ -1,30 +0,0 @@ -fcomp: -Fixes for negative 0 (perhaps this shouldn't be generated, like denormals -and infinities (these would cause even more trouble) but Fsub routine or -something generated one). - -frexp.x: -Deleted 3rd arg (used to return value when bcc wasn't doing it right). - -Fixed frexp(value = 0) and ldexp(value = 0) returning nonzero. - -Most files: -Changed comment symbol to '!' for new assembler (not the native ';' in -case this is ported to ACK someday). - -Avoided using ebp and unnecessary register saves. - -Changed assembler style to make it a bit more portable or like I do it -(no '$' for hex, 8[esp] instead of [esp+8], use only .define and not export -or .globl, use '#' (could use nothing) instead of '*' for immediate). -The partly-supported 8(ebp) and .globl would be still more portable. - -Changed terminology 'mantissa' to 'fraction'. - -Round to even. Required for 'paranioa' not to find any defects. - -Used preprocessor. - -Parametrized most of the magic numbers. Phew! - -Supported denormals. Now 'paranioa' doesn't find any flaws. diff --git a/bin86-0.3/bccfp/fabs.x b/bin86-0.3/bccfp/fabs.x deleted file mode 100644 index fe81676..0000000 --- a/bin86-0.3/bccfp/fabs.x +++ /dev/null @@ -1,17 +0,0 @@ -! bcc 386 floating point routines (version 2) -- _fabs -! author: Bruce Evans - -#include "fplib.h" - -! double fabs(double value); -! returns the absolute value of a number -! this works for all NaNs, like the 80*87 fabs, but perhaps we should check -! for exceptions that can happen when an 80*87 register is loaded - - .globl _fabs - .align ALIGNMENT -_fabs: - mov eax,PC_SIZE+D_LOW[esp] - mov edx,PC_SIZE+D_HIGH[esp] - and edx,~D_SIGN_MASK - ret diff --git a/bin86-0.3/bccfp/fadd.x b/bin86-0.3/bccfp/fadd.x deleted file mode 100644 index d1e60b1..0000000 --- a/bin86-0.3/bccfp/fadd.x +++ /dev/null @@ -1,485 +0,0 @@ -! bcc 386 floating point routines (version 2) -! -- Fadd, Faddd, Faddf, Fsub, Fsubd, Fsubf, normalize2 -! author: Bruce Evans - -#include "fplib.h" - -#define FRAME_SIZE (3 * GENREG_SIZE + PC_SIZE) - - .extern Fpushf - .extern fpdenormal - .extern fpoverflow - .extern fpunderflow - - .globl Fadd - .align ALIGNMENT -Fadd: - push ebp - push edi - push esi - mov eax,FRAME_SIZE+D_LOW[esp] - mov edx,FRAME_SIZE+D_HIGH[esp] - mov ebx,FRAME_SIZE+D_SIZE+D_LOW[esp] - mov ecx,FRAME_SIZE+D_SIZE+D_HIGH[esp] - call addition - mov FRAME_SIZE+D_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret #D_SIZE - - .globl Faddd - .align ALIGNMENT -Faddd: - push ebp - push edi - push esi - mov eax,FRAME_SIZE+D_LOW[esp] - mov edx,FRAME_SIZE+D_HIGH[esp] - mov ecx,D_HIGH[ebx] - mov ebx,D_LOW[ebx] - call addition - mov FRAME_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret - - .globl Faddf - .align ALIGNMENT -Faddf: - push ebp - push edi - push esi - call Fpushf - pop ebx ! yl - pop ecx ! yu - mov eax,FRAME_SIZE+D_LOW[esp] ! xl - mov edx,FRAME_SIZE+D_HIGH[esp] ! xu - call addition - mov FRAME_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret - - .globl Fsub - .align ALIGNMENT -Fsub: - push ebp - push edi - push esi - mov eax,FRAME_SIZE+D_LOW[esp] - mov edx,FRAME_SIZE+D_HIGH[esp] - mov ebx,FRAME_SIZE+D_SIZE+D_LOW[esp] - mov ecx,FRAME_SIZE+D_SIZE+D_HIGH[esp] - xor ecx,#D_SIGN_MASK ! complement sign - call addition - mov FRAME_SIZE+D_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret #D_SIZE - - .globl Fsubd - .align ALIGNMENT -Fsubd: - push ebp - push edi - push esi - mov eax,FRAME_SIZE+D_LOW[esp] - mov edx,FRAME_SIZE+D_HIGH[esp] - mov ecx,D_HIGH[ebx] - mov ebx,D_LOW[ebx] - xor ecx,#D_SIGN_MASK ! complement sign - call addition - mov FRAME_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret - - .globl Fsubf - .align ALIGNMENT -Fsubf: - push ebp - push edi - push esi - call Fpushf - pop ebx ! yl - pop ecx ! yu - mov eax,FRAME_SIZE+D_LOW[esp] ! xl - mov edx,FRAME_SIZE+D_HIGH[esp] ! xu - xor ecx,#D_SIGN_MASK ! complement sign - call addition - mov FRAME_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret - - .align ALIGNMENT -exp_y_0: - -! Check for x denormal, to split off special case where both are denormal, -! so the norm bit (or 1 higher) is known to be set for addition, so addition -! can be done faster - - test esi,#D_EXP_MASK - jnz x_normal_exp_y_0 - test esi,esi ! test top bits of x fraction - jnz both_denorm ! denormal iff nonzero fraction with zero exp - test eax,eax ! test rest of fraction - jz return_edx_eax ! everything 0 (XXX - do signs matter?) -both_denorm: - call fpdenormal - test ebp,#D_SIGN_MASK - jnz denorm_subtract - -! Add denormal x to denormal or zero y - -#if D_NORM_BIT != D_EXP_SHIFT -#include "error, carry into norm bit does not go into exponent" -#endif - - add eax,ebx - adc esi,edi - or edx,esi - ret - -denorm_subtract: - sub eax,ebx - sbb esi,edi - or edx,esi - ret - - .align ALIGNMENT -x_normal_exp_y_0: - test edi,edi ! this is like the check for x denormal - jnz y_denorm - test ebx,ebx - jz return_edx_eax ! y = 0 -y_denorm: - call fpdenormal - or ecx,#1 << D_EXP_SHIFT ! normalize y by setting exponent to 1 - jmp got_y - - .align ALIGNMENT -return_edx_eax: - ret - - .align ALIGNMENT -add_bigshift: - cmp ecx,#D_FRAC_BIT+2 - jae return_edx_eax ! x dominates y - sub ecx,#REG_BIT - shrd ebp,ebx,cl - shrd ebx,edi,cl - shr edi,cl - add eax,edi - adc esi,#0 - xchg ebp,ebx - br normalize - - .align ALIGNMENT -addition: - mov esi,edx ! this mainly for consistent naming - and esi,#D_EXP_MASK | D_FRAC_MASK ! discard sign so comparison is simple - mov edi,ecx ! free cl for shifts - and edi,#D_EXP_MASK | D_FRAC_MASK - cmp esi,edi - ja xbigger - jb swap - cmp eax,ebx - jae xbigger -swap: - xchg edx,ecx - xchg eax,ebx - xchg esi,edi -xbigger: - -! edx holds sign of result from here on -! and exponent of result before the normalization step - - mov ebp,edx ! prepare difference of signs - xor ebp,ecx - - and ecx,#D_EXP_MASK ! extract exp_y and check for y 0 or denormal - beq exp_y_0 ! otherwise x is not 0 or denormal either - and edi,#D_FRAC_MASK ! extract fraction - or edi,#D_NORM_MASK ! normalize -got_y: - and esi,#D_FRAC_MASK ! extract fraction - or esi,#D_NORM_MASK ! normalize - - sub ecx,edx ! carries from non-exp bits in edx killed later - neg ecx - and ecx,#D_EXP_MASK - shr ecx,#D_EXP_SHIFT ! difference of exponents - -got_x_and_y: - and ebp,#D_SIGN_MASK ! see if signs are same - bne subtract ! else roundoff reg ebp has been cleared - - cmp cl,#REG_BIT - bhis add_bigshift - shrd ebp,ebx,cl - shrd ebx,edi,cl - shr edi,cl - add eax,ebx - adc esi,edi - -! result edx(D_SIGN_MASK | D_EXP_MASK bits):esi:eax:ebp but needs normalization - - mov edi,edx - and edi,#D_EXP_MASK - test esi,#D_NORM_MASK << 1 - jnz add_loverflow - -add_round: - cmp ebp,#1 << (REG_BIT-1) ! test roundoff register - jb add_done ! no rounding - jz tie -add_roundup: - add eax,#1 - adc esi,#0 - test esi,#D_NORM_MASK << 1 - jnz pre_add_loverflow ! rounding may cause overflow! -add_done: - mov ecx,edx ! duplicated code from 'done' - and edx,#D_SIGN_MASK - or edx,edi - and esi,#D_FRAC_MASK - or edx,esi - ret - - .align ALIGNMENT -tie: - test al,#1 ! tie case, round to even - jz add_done ! even, no rounding - jmp add_roundup - - .align ALIGNMENT -pre_add_loverflow: - sub ebp,ebp ! clear rounding register - ! probably avoiding tests for more rounding -add_loverflow: - shrd ebp,eax,#1 - jnc over_set_sticky_bit - or ebp,#1 -over_set_sticky_bit: - shrd eax,esi,#1 - shr esi,#1 - add edi,1 << D_EXP_SHIFT - cmp edi,#D_EXP_INFINITE << D_EXP_SHIFT - jl add_round -overflow: - call fpoverflow - mov eax,ecx ! XXX - wrong reg - ret - -! result edx(D_SIGN_MASK | D_EXP_MASK bits): -! esi((D_NORM_MASK << 1) | D_NORM_MASK | D_FRAC_MASK bits):eax:ebp:ebx -! but needs normalization - - .align ALIGNMENT -normalize: - mov edi,edx - and edi,#D_EXP_MASK - test esi,#D_NORM_MASK << 1 - bne loverflow - -! result edx(D_SIGN_MASK bit):edi(D_EXP_MASK bits): -! esi(D_NORM_MASK | D_FRAC_MASK bits):eax:ebp:ebx -! but needs normalization - - .globl normalize2 -normalize2: - test esi,#D_NORM_MASK ! already-normalized is very common - jz normalize3 -round: - cmp ebp,#1 << (REG_BIT-1) ! test roundoff register - jb done ! no rounding - jz near_tie -roundup: - add eax,#1 - adc esi,#0 - test esi,#D_NORM_MASK << 1 - bne pre_loverflow ! rounding may cause overflow! -done: -cmp edi,#D_EXP_INFINITE << D_EXP_SHIFT -jae overflow - and edx,#D_SIGN_MASK ! extract sign of largest and result - or edx,edi ! include exponent with sign - and esi,#D_FRAC_MASK ! discard norm bit - or edx,esi ! include fraction with sign and exponent - ret - - .align ALIGNMENT -near_tie: - test ebx,ebx - jnz roundup - test al,#1 ! tie case, round to even - jz done ! even, no rounding - jmp roundup - - .align ALIGNMENT -not_in_8_below: - shld ecx,esi,#REG_BIT-D_NORM_BIT+16 ! in 9 to 16 below? - jz not_in_16_below ! must be way below (17-20 for usual D_NORM_BIT) - mov cl,bsr_table[ecx] ! bsr(esi) - (D_NORM_BIT-16) - neg ecx ! (D_NORM_BIT-16) - bsr(esi) - add ecx,#16 - jmp got_shift - - .align ALIGNMENT -not_in_16_below: - mov cl,bsr_table[esi] ! bsr(esi) directly - neg ecx ! -bsr(esi) - add ecx,#D_NORM_BIT ! D_NORM_BIT - bsr(esi) - jmp got_shift - - .align ALIGNMENT -normalize3: - test esi,esi - jz shift32 - -! Find first nonzero bit in esi -! Don't use bsr, it is very slow (const + 3 * bit_found) -! We know that there is some nonzero bit, and the norm bit and above are clear - - sub ecx,ecx ! prepare unsigned extension of cl - shld ecx,esi,#REG_BIT-D_NORM_BIT+8 ! any bits in 8 below norm bit? - jz not_in_8_below - mov cl,bsr_table[ecx] ! bsr(esi) - (D_NORM_BIT-8) - neg ecx ! (D_NORM_BIT-8) - bsr(esi) - add ecx,#8 ! D_NORM_BIT - bsr(esi) -got_shift: - shld esi,eax,cl - shld eax,ebp,cl - shld ebp,ebx,cl - shl ebx,cl - shl ecx,D_EXP_SHIFT - sub edi,ecx - bhi round ! XXX - can rounding change the exponent to > 0? - ! not bgt since edi may be 0x80000000 - neg edi - shr edi,#D_EXP_SHIFT - inc edi - br fpunderflow - - .align ALIGNMENT -pre_loverflow: - sub ebp,ebp ! clear rounding registers - sub ebx,ebx ! probably avoiding tests for more rounding - -loverflow: - shr esi,#1 ! carry bit stayed in the reg - rcr eax,#1 - rcr ebp,#1 - rcr ebx,#1 - add edi,1 << D_EXP_SHIFT - cmp edi,#D_EXP_INFINITE << D_EXP_SHIFT - blt round - call fpoverflow - mov eax,ecx ! XXX - wrong reg - ret - - .align ALIGNMENT -shift32: - test eax,eax - jz shift64 - mov esi,eax - mov eax,ebp - mov ebp,ebx - sub ebx,ebx - sub edi,#REG_BIT << D_EXP_SHIFT -shiftxx: - test esi,#~(D_NORM_MASK | D_FRAC_MASK) - jz over_adjust ! else too big already - shrd ebx,ebp,#D_BIT-D_FRAC_BIT - shrd ebp,eax,#D_BIT-D_FRAC_BIT - shrd eax,esi,#D_BIT-D_FRAC_BIT - shr esi,#D_BIT-D_FRAC_BIT - add edi,#(D_BIT-D_FRAC_BIT) << D_EXP_SHIFT -over_adjust: - test edi,edi - bgt normalize2 - neg edi - shr edi,#D_EXP_SHIFT - inc edi - br fpunderflow - - .align ALIGNMENT -shift64: - test ebp,ebp - jz shift96 - mov esi,ebp - mov eax,ebx - sub ebp,ebp - mov ebx,ebp - sub edi,#(2*REG_BIT) << D_EXP_SHIFT - jmp shiftxx - - .align ALIGNMENT -shift96: - test ebx,ebx ! XXX - this test is probably unnecessary - ! since the shift must be small unless we - ! are subtracting 2 almost-equal numbers, - ! and then the bits beyond 64 will mostly - ! be 0 - jz return_esi_eax ! all zero - mov esi,ebx - sub ebx,ebx - sub edi,#(3*REG_BIT) << D_EXP_SHIFT - jmp shiftxx - - .align ALIGNMENT -return_esi_eax: - mov edx,esi - ret - - .align ALIGNMENT -subtract: - sub ebp,ebp ! set up roundoff register - cmp ecx,#REG_BIT - jae subtract_bigshift - shrd ebp,ebx,cl - shrd ebx,edi,cl - shr edi,cl - neg ebp ! begin subtraction esi:eax:0 - edi:ebx:ebp - sbb eax,ebx - sbb esi,edi - sub ebx,ebx - mov edi,edx - and edi,#D_EXP_MASK - br normalize2 - - .align ALIGNMENT -subtract_bigshift: - cmp ecx,#D_FRAC_BIT+2 - bhis return_edx_eax ! x dominates y - sub ecx,#REG_BIT - shrd ebp,ebx,cl - shrd ebx,edi,cl - shr edi,cl - not ebp ! begin subtraction esi:eax:0:0 - 0:edi:ebx:ebp - not ebx - add ebp,#1 - adc ebx,#0 - cmc - sbb eax,edi - sbb esi,#0 - xchg ebp,ebx - mov edi,edx - and edi,#D_EXP_MASK - br normalize2 - - .data - .extern bsr_table diff --git a/bin86-0.3/bccfp/fcomp.x b/bin86-0.3/bccfp/fcomp.x deleted file mode 100644 index 71148ab..0000000 --- a/bin86-0.3/bccfp/fcomp.x +++ /dev/null @@ -1,89 +0,0 @@ -! bcc 386 floating point routines (version 2) -- Fcomp, Fcompd, Fcompf -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern Fpushf - -! Pop 2 doubles from stack and compare them, return result in flags so -! normal signed branches work (unlike 80x87 which returns the result in -! the zero and carry flags). - - .globl Fcomp - .align ALIGNMENT -Fcomp: - pop ecx ! get return address - pop eax ! xl - pop edx ! xu - push ecx ! put back ret address - pop 2nd double later - -! All this popping is bad on 486's since plain mov takes 1+ cycle and pop -! takes 4 cycles. But this code is designed for 386's where popping is -! nominally the same speed and saves code space and so maybe instruction -! fetch time as well as the instruction to adjust the stack (ret #n takes -! no longer than plain ret but inhibits gotos). - - mov ebx,PC_SIZE+D_LOW[esp] ! yl - mov ecx,PC_SIZE+D_HIGH[esp] ! yu - jmp compare - -! Pop double from stack and compare with double at [ebx] - - .globl Fcompd - .align ALIGNMENT -Fcompd: - mov eax,PC_SIZE+D_LOW[esp] ! xl - mov edx,PC_SIZE+D_HIGH[esp] ! xu - mov ecx,D_HIGH[ebx] ! yu - mov ebx,D_LOW[ebx] ! yl - -compare: - test edx,#D_SIGN_MASK ! is x >= 0? - jz cmp0 ! yes; just compare x and y - test ecx,#D_SIGN_MASK ! no; but is y >= 0? - jz cmp0 ! yes; just compare x and y - - xchg edx,ecx ! x, y < 0, so ... - xchg eax,ebx ! ... swap x and y ... - xor edx,#D_SIGN_MASK ! ... and toggle signs - xor ecx,#D_SIGN_MASK - -cmp0: - cmp edx,ecx ! compare upper dwords - jnz checkneg0 ! if upper dwords differ, job is almost done - mov edx,eax ! upper dwords equal, so ... - mov ecx,ebx ! ... must make unsigned comparison of lower dwords - shr edx,#1 ! shift past sign - shr ecx,#1 - cmp edx,ecx ! compare top 31 bits of lower dwords - jnz return ! if these differ, job is done - and eax,#1 ! compare lowest bits - and ebx,#1 - cmp eax,ebx - -return: - ret #D_SIZE ! return, popping 1 double from stack - -checkneg0: - test edx,#D_EXP_MASK | D_FRAC_MASK ! check to catch unusual case ... - jnz recheck - test eax,eax - jnz recheck - test ecx,#D_EXP_MASK | D_FRAC_MASK - jnz recheck - test ebx,ebx - jz return ! ... both are (+-) zero, return 'z' - -recheck: - cmp edx,ecx ! the upper words were really different - ret #D_SIZE - - .globl Fcompf - .align ALIGNMENT -Fcompf: - call Fpushf - pop ebx ! yl - pop ecx ! yu - mov eax,PC_SIZE+D_LOW[esp] ! xl - mov edx,PC_SIZE+D_HIGH[esp] ! xu - jmp compare diff --git a/bin86-0.3/bccfp/fdiv.x b/bin86-0.3/bccfp/fdiv.x deleted file mode 100644 index 4a5cf74..0000000 --- a/bin86-0.3/bccfp/fdiv.x +++ /dev/null @@ -1,312 +0,0 @@ -#define EF_SIZE 4 - -! bcc 386 floating point routines (version 2) -- Fdiv, Fdivd, Fdivf -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - -#define FRAME_SIZE (3 * GENREG_SIZE + PC_SIZE) - - .extern Fpushf - .extern fpdivzero - .extern fpoverflow - .extern fpunderflow - -! double Fdiv(double x, double y) returns x / y - -! pop 2 doubles from stack, divide first by second, and push quotient on stack - -! we denote upper and lower dwords of x and y (or their fractions) -! by (xu,xl), (yu,yl) - - .globl Fdivf - .align ALIGNMENT -Fdivf: - sub esp,#D_SIZE ! make space for dummy double on stack - push ebp - push edi ! save some regs - push esi - mov eax,FRAME_SIZE-PC_SIZE+D_SIZE[esp] ! move return address ... - mov FRAME_SIZE-PC_SIZE[esp],eax ! ... to usual spot - call Fpushf - pop esi ! yl - pop edi ! yu - mov eax,FRAME_SIZE+D_SIZE+D_LOW[esp] ! xl - mov edx,FRAME_SIZE+D_SIZE+D_HIGH[esp] ! xu - jmp division - - .globl Fdiv - .align ALIGNMENT -Fdiv: - push ebp - push edi ! save some regs - push esi - mov eax,FRAME_SIZE+D_LOW[esp] ! xl - mov edx,FRAME_SIZE+D_HIGH[esp] ! xu - mov esi,FRAME_SIZE+D_SIZE+D_LOW[esp] ! yl - mov edi,FRAME_SIZE+D_SIZE+D_HIGH[esp] ! yu - jmp division - - .align ALIGNMENT -exp_y_0: - mov ebx,edi - or ebx,esi - beq zerodivide - mov ebx,#1 -fix_y: - test edi,edi ! XXX - sloow - js y_unpacked - shld edi,esi,#1 - shl esi,#1 - dec bx - jmp fix_y - - .align ALIGNMENT -exp_x_0: - mov ecx,edx - or ecx,eax - beq retz - mov ecx,#1 ! change exponent from 0 to 1 -fix_x: - test edx,#1 << (REG_BIT-1-2) ! XXX - sloow - jnz x_unpacked - shld edx,eax,#1 - shl eax,#1 - dec cx - jmp fix_x - -! Fdivd pops double from stack, divides it by double at [ebx], -! and pushes quotient back on stack - - .globl Fdivd - .align ALIGNMENT -Fdivd: - sub esp,#D_SIZE ! make space for dummy double on stack - push ebp - push edi ! save some regs - push esi - mov eax,FRAME_SIZE-PC_SIZE+D_SIZE[esp] ! move return address ... - mov FRAME_SIZE-PC_SIZE[esp],eax ! ... to usual spot - mov eax,FRAME_SIZE+D_SIZE+D_LOW[esp] ! xl - mov edx,FRAME_SIZE+D_SIZE+D_HIGH[esp] ! xu - mov esi,D_LOW[ebx] ! yl - mov edi,D_HIGH[ebx] ! yu - -division: - -! The full calculations are - -! (xu,xl,0) = yu * (zu,zl) + (0,r,0) (normal 96/32 -> 64 bit division) -! yl * zu = yu * q1 + r1 (32*32 -> 64 bit mul and 64/32 -> 32 bit div) - -! so - -! (xu,xl,0,0) = (yu,yl) * (zu,zl-q1) + (0,0,r-r1,yl*(q1-zl)) - -! where the calculations zl-q1, r-r1 and yl*(q1-zl) are more complicated -! than the notation suggests. They may be negative and the one with the -! multiplication may not fit in 32 bits and in both cases the overflow -! has to be moved into higher bit positions. - -! See Knuth for why (zu,zl-q1) is the correct 64-bit quotient to within -! 1 bit either way (assuming the normalization x < 2 * y). - -! We only need to calculate the remainder (0,0,r-r1,yl*(q1-zl)) to resolve -! tie cases. It tells whether the approximate quotient is too high or too -! low. - -#define NTEMPS 5 - - sub esp,#NTEMPS*GENREG_SIZE ! space to remember values for rounding of tie case - -! Offsets from esp for these values (offsets using FRAME_SIZE are invalid -! while these temps are active) -r = 0 -q1 = 4 -r1 = 8 -yl = 12 -zl = 16 - -! Step 1: unpack and normalize x to fraction in edx:eax (left shifted as -! far as possible less 2 so that x < y, and later z < y); unpack and normalize -! y to a fraction in edi:esi (left shifted as far as possible), put difference -! of signs (= sign of quotient) in ecx(D_SIGN_MASK) and difference of exponents -! (= exponent of quotient before normalization) in cx. - - mov ebp,edx ! xu - xor ebp,edi ! xu ^ yu - and ebp,#D_SIGN_MASK ! sign of result is difference of signs - -! Unpack y first to trap 0 / 0 - - mov ebx,edi ! remember yu for exponent of y - shld edi,esi,#D_BIT-D_FRAC_BIT ! extract fraction of y ... - shl esi,#D_BIT-D_FRAC_BIT - and ebx,#D_EXP_MASK ! exponent of y - jz exp_y_0 - shr ebx,#D_EXP_SHIFT ! in ebx (actually in bx, with high bits 0) - or edi,#D_NORM_MASK << (D_BIT-D_FRAC_BIT) ! normalize -y_unpacked: - -! Unpack x - - mov ecx,edx ! remember xu for exponent of x - shld edx,eax,#D_BIT-D_FRAC_BIT-2 ! extract fraction of x ... - shl eax,#D_BIT-D_FRAC_BIT-2 - and edx,#(D_NORM_MASK << (D_BIT-D_FRAC_BIT-2+1))-1 - ! XXX - above may be shifted 1 extra unnecessarily - and ecx,#D_EXP_MASK ! exponent of x - jz exp_x_0 - shr ecx,#D_EXP_SHIFT ! in ecx (actually in cx, with high bits 0) - or edx,#D_NORM_MASK << (D_BIT-D_FRAC_BIT-2) ! normalize -x_unpacked: - - sub cx,bx ! not ecx,ebx because we want to use high bit for sign - add cx,#D_EXP_BIAS ! adjust exponent of quotient - - or ecx,ebp ! include sign with exponent - -! Step 2: quotient of fractions -> (edx,eax) - -! 2a: (xu,xl,0) div yu = (zu,zl) -> (ebx,esi) - - div eax,edi ! (xu,xl) div yu = zu in eax; remainder (rem) in edx - mov ebx,eax ! save zu in ebx - sub eax,eax ! clear eax: (edx,eax) = (rem,0) - div eax,edi ! (rem,0) div yu = zl in eax - mov r[esp],edx - mov zl[esp],eax - xchg eax,esi ! store zl in esi; save yl in eax - mov yl[esp],eax - -! 2b: (yl * zu) div yu -> (0,eax) - - mul eax,ebx ! yl * zu -> (edx,eax) - div eax,edi ! (yl * zu) div yu in eax - mov q1[esp],eax - mov r1[esp],edx - -! 2c: (xu,xl) / (yu,yl) = (zu,zl) - (yl * zu) div yu -> (edx,eax) - - mov edx,ebx ! zu - xchg eax,esi ! eax <- zl; esi <- (yl * zu) div yu - sub eax,esi - sbb edx,#0 - -! Step 3: normalise quotient - - test edx,#1 << (REG_BIT-2) ! is fraction too small? (can only be by 1 bit) - jnz div4 - shld edx,eax,#1 ! yes; multiply fraction ... - shl eax,#1 ! ... by 2 ... - dec cx ! ... and decrement exponent - -! Step 4: shift and round - -div4: - mov ebx,eax ! save for rounding - shrd eax,edx,#D_BIT-D_FRAC_BIT-1 ! shift fraction of result ... - shr edx,#D_BIT-D_FRAC_BIT-1 ! ... to proper position - and ebx,#(1 << (D_BIT-D_FRAC_BIT-1))-1 ! look at bits shifted out - cmp ebx,#D_NORM_MASK >> (D_BIT-D_FRAC_BIT) ! compare with middle value - jb div5 ! below middle, don't round up - ja roundup ! above middle, round up - -! The low bits don't contain enough information to resolve the tie case, -! because the quotient itself is only an approximation. -! Calculate the exact remainder. -! This case is not very common, so don't worry much about speed. -! Unfortunately we had to save extra in all cases to prepare for it. - - push edx - push eax - - sub esi,esi ! the calculation requires 33 bits - carry to here - mov eax,2*GENREG_SIZE+q1[esp] - sub eax,2*GENREG_SIZE+zl[esp] - pushfd - mul dword EF_SIZE+2*GENREG_SIZE+yl[esp] - popfd - jnc foo - sub edx,2*GENREG_SIZE+yl[esp] - sbb esi,#0 -foo: - add edx,2*GENREG_SIZE+r[esp] - adc esi,#0 - sub edx,2*GENREG_SIZE+r1[esp] - sbb esi,#0 - mov ebx,eax - mov edi,edx - - pop eax - pop edx - -! Can finally decide rounding of tie case - - js div5 ! remainder < 0 from looking at top 64 bits - jnz roundup ! remainder > 0 from looking at top 64 bits - or edi,ebx ! test bottom 64 bits - jnz roundup ! remainder > 0 - - test al,#1 ! at last we know it is the tie case, check parity bit - jz div5 ! already even, otherwise round up to make even - -roundup: - add eax,#1 ! add rounding bit - adc edx,#0 - test edx,#D_NORM_MASK << 1 ! has fraction overflowed (very unlikely) - jz div5 -! Why were the shifts commented out? - shrd eax,edx,#1 ! yes, divide fraction ... - shr edx,#1 ! ... by 2 ... - inc cx ! ... and increment exponent - -! Step 5: put it all together - -div5: - mov ebx,ecx ! extract sign - and ebx,D_SIGN_MASK - cmp cx,#D_EXP_INFINITE ! is exponent too big? - jge overflow - test cx,cx - jle underflow - shl ecx,#D_EXP_SHIFT - - and edx,#D_FRAC_MASK ! remove norm bit - or edx,ecx ! include exponent ... - or edx,ebx ! ... and sign - -return: - add esp,#NTEMPS*GENREG_SIZE ! reclaim temp space - mov FRAME_SIZE+D_SIZE+D_LOW[esp],eax ! "push" lower dword of product ... - mov FRAME_SIZE+D_SIZE+D_HIGH[esp],edx ! ... and upper dword - pop esi ! restore registers - pop edi - pop ebp - ret #D_SIZE - -retz: - sub edx,edx ! clear upper dword - sub eax,eax ! ... and lower dword - jmp return - -overflow: - mov edx,ecx ! put sign in usual reg - call fpoverflow - mov eax,ecx ! XXX - wrong reg - jmp return - -underflow: - mov esi,edx ! put upper part of fraction in usual reg - mov edx,ecx ! sign - movsx edi,cx ! put shift in usual reg - neg edi - inc edi - call fpunderflow - jmp return - -zerodivide: - mov edx,ebp ! sign - call fpdivzero - mov eax,ecx ! XXX - wrong reg - jmp return diff --git a/bin86-0.3/bccfp/fmul.x b/bin86-0.3/bccfp/fmul.x deleted file mode 100644 index aa62b5c..0000000 --- a/bin86-0.3/bccfp/fmul.x +++ /dev/null @@ -1,150 +0,0 @@ -! bcc 386 floating point routines (version 2) -- Fmul, Fmuld, Fmulf -! author: Bruce Evans - -#include "fplib.h" - -#define FRAME_SIZE (3 * GENREG_SIZE + PC_SIZE) - - .extern Fpushf - .extern fpoverflow - .extern fpunderflow - .extern normalize2 - - .globl Fmul - .align ALIGNMENT -Fmul: - push ebp - push edi - push esi - mov eax,FRAME_SIZE+D_LOW[esp] - mov edx,FRAME_SIZE+D_HIGH[esp] - mov ebx,FRAME_SIZE+D_SIZE+D_LOW[esp] - mov ecx,FRAME_SIZE+D_SIZE+D_HIGH[esp] - call multiplication - mov FRAME_SIZE+D_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret #D_SIZE - - .globl Fmuld - .align ALIGNMENT -Fmuld: - push ebp - push edi - push esi - mov eax,FRAME_SIZE+D_LOW[esp] - mov edx,FRAME_SIZE+D_HIGH[esp] - mov ecx,D_HIGH[ebx] - mov ebx,D_LOW[ebx] - call multiplication - mov FRAME_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret - - .globl Fmulf - .align ALIGNMENT -Fmulf: - push ebp - push edi - push esi - call Fpushf - pop ebx ! yl - pop ecx ! xu - mov eax,FRAME_SIZE+D_LOW[esp] ! xl - mov edx,FRAME_SIZE+D_HIGH[esp] ! xu - call multiplication - mov FRAME_SIZE+D_LOW[esp],eax - mov FRAME_SIZE+D_HIGH[esp],edx - pop esi - pop edi - pop ebp - ret - - .align ALIGNMENT -exp_x_0: - mov edx,#1 << D_EXP_SHIFT ! change exponent from 0 to 1 - jmp x_unpacked ! XXX - check for denormal? - - .align ALIGNMENT -exp_y_0: - mov ecx,#1 << D_EXP_SHIFT - jmp y_unpacked - - .align ALIGNMENT -multiplication: - mov ebp,edx ! xu - xor ebp,ecx ! xu ^ yu - and ebp,#D_SIGN_MASK ! sign of result is difference of signs - - mov esi,edx ! free edx for multiplications - and esi,#D_FRAC_MASK ! discard sign and exponent - and edx,#D_EXP_MASK ! exponent(x) - jz exp_x_0 - or esi,#D_NORM_MASK ! normalize -x_unpacked: - - mov edi,ecx ! this mainly for consistent naming - and edi,#D_FRAC_MASK - and ecx,#D_EXP_MASK ! exponent(y) - jz exp_y_0 - or edi,#D_NORM_MASK -y_unpacked: - - add ecx,edx ! add exponents - -! exponent is in ecx, sign in ebp, operands in esi:eax and edi:ebx, edx is free -! product to go in esi:eax:ebp:ebx -! terminology: x * y = (xu,xl) * (yu,yl) -! = (xu * yu,0,0) + (0,xu * yl + xl * yu,0) + (0,0,xl * yl) - - push ecx - push ebp - mov ecx,eax - mul ebx ! xl * yl - mov ebp,edx ! (xl * yl).u in ebp - xchg ebx,eax ! (xl * yl).l in ebx (final), yl in eax - mul esi ! xu * yl - push eax ! (xu * yl).l on stack - push edx ! (xu * yl).u on stack - mov eax,esi ! xu - mul edi ! xu * yu - mov esi,edx ! (xu * yu).u in esi (final except carries) - xchg ecx,eax ! (xu * yu).l in ecx, xl in eax - mul edi ! xl * yu - - add ebp,eax ! (xl * yl).u + (xl * yu).l - pop eax ! (xu * yl).u - adc eax,edx ! (xu * yl).u + (xl * yu).u - adc esi,#0 - pop edx ! (xu * yl).l - add ebp,edx ! ((xl * yl).u + (xl * yu).l) + (xu * yl).l - adc eax,ecx ! ((xu * yl).u + (xl * yu).u) + (xu * yu).l - adc esi,#0 - pop edx ! sign - pop edi ! exponent - sub edi,#(D_EXP_BIAS+1-(D_EXP_BIT+2)) << D_EXP_SHIFT ! adjust -! cmp edi,#(D_EXP_INFINITE-1+(D_EXP_BIT+2)) << D_EXP_SHIFT -! jae outofbounds ! 0 will be caught as underflow by normalize2 -cmp edi,#(2*D_EXP_INFINITE-(D_EXP_BIAS+1)+(D_EXP_BIT+2)) << D_EXP_SHIFT -ja underflow - br normalize2 - - .align ALIGNMENT -overflow: - mov edx,ebp ! put sign in usual reg - call fpoverflow - mov eax,ecx ! XXX - wrong reg - ret - - .align ALIGNMENT -underflow: - mov edx,ebp ! put sign in usual reg - neg edi - shr edi,#D_EXP_SHIFT - inc edi - br fpunderflow diff --git a/bin86-0.3/bccfp/fpbsr.x b/bin86-0.3/bccfp/fpbsr.x deleted file mode 100644 index 8ff38d7..0000000 --- a/bin86-0.3/bccfp/fpbsr.x +++ /dev/null @@ -1,25 +0,0 @@ -! bcc 386 floating point routines (version 2) -- bsr_table -! author: Bruce Evans - -#include "fplib.h" - - .globl bsr_table - .data - .align ALIGNMENT -bsr_table: ! table to replace bsr on range 0-255 -.byte -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 -.byte 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -.byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 -.byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 -.byte 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 -.byte 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 -.byte 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 -.byte 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -.byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 diff --git a/bin86-0.3/bccfp/fperr.c b/bin86-0.3/bccfp/fperr.c deleted file mode 100644 index d5372dc..0000000 --- a/bin86-0.3/bccfp/fperr.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * bin86/bccfp/fperr.c - * - * Copyright (C) 1992 Bruce Evans - */ - -#include <stdio.h> -#include <signal.h> - -#include "fperr.h" - -void fperr(errno) -int errno; -{ - -#if defined(DEBUG) || 0 - switch(errno) { - - case EFDENORMAL: - fputs("\nDenormal - ", stderr); - break; - - case EFINFINITY: - fputs("\nInfinity - ", stderr); - break; - - case EFNAN: - fputs("\nNaN - ", stderr); - break; - - case EFOVERFLOW: - fputs("\nOverflow - ", stderr); - break; - - case EFUNDERFLOW: - fputs("\nUnderflow - ", stderr); - break; - - case EFDIVZERO: - fputs("\nZero divide - ", stderr); - break; - - default: - fprintf(stderr, "\nUnknown error 0x%x - ", errno); - } - fflush(stderr); -#endif - - kill(getpid(), SIGFPE); -} diff --git a/bin86-0.3/bccfp/fperr.h b/bin86-0.3/bccfp/fperr.h deleted file mode 100644 index 42d54fd..0000000 --- a/bin86-0.3/bccfp/fperr.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bin86/bccfp/fperr.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* fperr.h */ - -#define EFDENORMAL 1 -#define EFINFINITY 2 -#define EFNAN 3 -#define EFOVERFLOW 4 -#define EFUNDERFLOW 5 -#define EFDIVZERO 6 diff --git a/bin86-0.3/bccfp/fperror.x b/bin86-0.3/bccfp/fperror.x deleted file mode 100644 index 04f3f74..0000000 --- a/bin86-0.3/bccfp/fperror.x +++ /dev/null @@ -1,126 +0,0 @@ -! bcc 386 floating point routines (version 2) -! --- fpdenormal, fperror, fpinfinity, fpNaN, fpoverflow, fpunderflow,fpdivzero -! author: Bruce Evans - -#include "fperr.h" -#include "fplib.h" - - .extern _fperr - -! Cause a denormal-operand exception -! Preserves all general registers if signal handler returns - - .globl fpdenormal - .align ALIGNMENT -fpdenormal: -#if 0 - push eax - mov eax,#EFDENORMAL - call fperror - pop eax -#endif - ret - -! Cause an exception with error code eax, preserving all genregs except eax - - .globl fperror - .align ALIGNMENT -fperror: - push ebp ! set up usual frame ... - mov ebp,esp ! ... for debugging - push edx ! save default - push ecx - push eax ! error code is arg to C routine - call _fperr - add esp,#GENREG_SIZE - pop ecx ! restore default - pop edx - pop ebp - ret - - .align ALIGNMENT -fphuge: - mov ecx,#D_HUGE_LOW ! prepare number +-HUGEVAL - or edx,#D_HUGE_HIGH ! ... in case signal handler returns - jmp fperror - -! Cause an infinite-operand exception -! Return +-HUGEVAL in edx:ecx with sign from edx - - .globl fpinfinity - .align ALIGNMENT -fpinfinity: - mov eax,#EFINFINITY - jmp fphuge ! almost right - -! Cause an NaN-operand exception -! Return +-HUGEVAL in edx:ecx with sign from edx - - .globl fpNaN - .align ALIGNMENT -fpNaN: - mov eax,#EFNAN ! there are different types of NaNs but... - jmp fphuge ! WRONG - -! Cause an overflow exception -! Return +-HUGEVAL in edx:ecx with sign from edx - - .globl fpoverflow - .align ALIGNMENT -fpoverflow: - mov eax,#EFOVERFLOW - jmp fphuge ! almost right - -! Cause an underflow exception (actually assume it is masked for now) -! Return denormal or 0.0 in edx:ecx -! XXX - this should cause a denormal exception or none for the denormal case -! Args: sign in edx, fraction in esi:eax, right shift in edi -! Returns: denormalized number in edx:eax - - .globl fpunderflow - .align ALIGNMENT -fpunderflow: -#if 0 - mov eax,#EFUNDERFLOW - jmp fperror -#endif - cmp edi,#REG_BIT - jb denormalize1 - mov eax,esi - sub esi,esi - sub edi,#REG_BIT - cmp edi,#REG_BIT - jb denormalize1 -denormalize_underflow: -#if 0 - mov eax,#EFUNDERFLOW - jmp fperror -#endif - sub eax,eax - mov edx,eax - ret - - .align ALIGNMENT -denormalize1: - mov ecx,edi - shrd eax,esi,cl - shr esi,cl - mov ecx,esi - or ecx,eax - jz denormalize_underflow - and edx,#D_SIGN_MASK - or edx,esi - ret - -! Cause an fp division by zero exception -! Return +-HUGEVAL in edx:ecx with sign from edx - - .globl fpdivzero - .align ALIGNMENT -fpdivzero: - mov eax,#EFDIVZERO - test edx,#D_EXP_MASK - jnz fphuge ! almost right - sub ecx,ecx - mov edx,ecx - jmp fperror diff --git a/bin86-0.3/bccfp/fplib.h b/bin86-0.3/bccfp/fplib.h deleted file mode 100644 index b346c61..0000000 --- a/bin86-0.3/bccfp/fplib.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * bin86/bccfp/fplib.h - * - * Copyright (C) 1992 Bruce Evans - */ - -#define ALIGNMENT 4 -#define CHAR_BIT 8 -#define D_BIT (D_SIZE * CHAR_BIT) -#define D_EXP_BIAS ((1 << (D_EXP_BIT - 1)) - 1) -#define D_EXP_BIT 11 -#define D_EXP_INFINITE ((1 << D_EXP_BIT) - 1) -#define D_EXP_MASK (((1 << D_EXP_BIT) - 1) << D_EXP_SHIFT) -#define D_EXP_SHIFT (REG_BIT - (1 + D_EXP_BIT)) -#define D_FRAC_BIT 53 -#define D_FRAC_MASK (D_NORM_MASK - 1) -#define D_HIGH 4 -#define D_HUGE_HIGH (D_EXP_MASK - 1) -#define D_HUGE_LOW 0xFFFFFFFF -#define D_LOW 0 -#define D_NORM_BIT (D_FRAC_BIT - 1 - REG_BIT) -#define D_NORM_MASK (1 << D_NORM_BIT) -#define D_SIGN_BIT 63 -#define D_SIGN_MASK (1 << (D_SIGN_BIT - REG_BIT)) -#define D_SIZE 8 -#define F_BIT (F_SIZE * CHAR_BIT) -#define F_EXP_BIAS ((1 << (F_EXP_BIT - 1)) - 1) -#define F_EXP_BIT 8 -#define F_EXP_INFINITE ((1 << F_EXP_BIT) - 1) -#define F_EXP_MASK (((1 << F_EXP_BIT) - 1) << F_EXP_SHIFT) -#define F_EXP_SHIFT (REG_BIT - (1 + F_EXP_BIT)) -#define F_FRAC_BIT 24 -#define F_FRAC_MASK (F_NORM_MASK - 1) -#define F_HIGH 0 -#define F_HUGE_HIGH (F_EXP_MASK - 1) -#define F_NORM_BIT (F_FRAC_BIT - 1) -#define F_NORM_MASK (1 << F_NORM_BIT) -#define F_SIGN_BIT 31 -#define F_SIGN_MASK (1 << F_SIGN_BIT) -#define F_SIZE 4 -#define FREE_D_SIGN_BIT_TEST (D_SIGN_BIT % REG_BIT == REG_BIT - 1) -#define GENREG_SIZE 4 -#define INT_BIT 32 -#define INT_MAX 0x7FFFFFFF -#define INT_MIN (-0x7FFFFFFF - 1) -#define PC_SIZE 4 -#define REG_BIT 32 -#define SHORT_BIT 16 -#define UINT_MAX 0xFFFFFFFF diff --git a/bin86-0.3/bccfp/fptoi.x b/bin86-0.3/bccfp/fptoi.x deleted file mode 100644 index 30de729..0000000 --- a/bin86-0.3/bccfp/fptoi.x +++ /dev/null @@ -1,117 +0,0 @@ -! bcc 386 floating point routines (version 2) -! -- dtoi, dtol, dtoui, dtoul, ftoi, ftol (todo: ftoui, ftoul) -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern fpoverflow - .extern Fpushf - -! Convert double x at [ebx] to int and return in eax - - .globl dtoi - .globl dtol - .align ALIGNMENT -dtoi: -dtol: - mov eax,D_HIGH[ebx] - mov ecx,eax - and ecx,#D_EXP_MASK ! extract exponent - jz retz ! if 0 return 0 - test eax,#D_SIGN_MASK - jnz negative - call into_dtoui - cmp eax,#INT_MAX - ja overflow_int_max - ret - - .align ALIGNMENT -negative: - and eax,#~D_SIGN_MASK - call into_dtoui - cmp eax,#INT_MIN - ja overflow_int_min - neg eax - ret - - .align ALIGNMENT -overflow_int_max: - call fpoverflow - mov eax,#INT_MAX - ret - - .align ALIGNMENT -overflow_int_min: - js return ! actually INT_MIN is OK - call fpoverflow - mov eax,#INT_MIN -return: - ret - - .align ALIGNMENT -retz: - sub eax,eax ! clear return value - ret - -! Convert double x at [ebx] to unsigned and return in eax - - .globl dtoui - .globl dtoul - .align ALIGNMENT -dtoui: -dtoul: - mov eax,D_HIGH[ebx] - mov ecx,eax - and ecx,#D_EXP_MASK ! extract exponent - jz retz ! if 0 return 0 - test eax,#D_SIGN_MASK - jnz overflow_0 -into_dtoui: - mov edx,D_LOW[ebx] - - and eax,#D_FRAC_MASK ! extract fraction - or eax,#D_NORM_MASK ! restore normalization bit - - shr ecx,#D_EXP_SHIFT ! convert exponent to number - sub ecx,#D_EXP_BIAS+D_NORM_BIT ! adjust radix point - jl dtoui_rightshift ! should we shift left or right? - cmp ecx,#D_BIT-D_FRAC_BIT ! can shift left by at most this - ja overflow_uint_max ! if more, overflow - shld eax,edx,cl - ret - - .align ALIGNMENT -dtoui_rightshift: - neg ecx ! make shift count > 0 - cmp ecx,#REG_BIT ! big shifts would be taken mod REG_BIT ... - jae retz ! ... no good - shr eax,cl ! otherwise it is faster to do the shift ... - ret ! ... then to jump for the slightly smaller - ! ... shift counts that shift out all bits - - .align ALIGNMENT -overflow_0: - call fpoverflow - sub eax,eax - ret - - .align ALIGNMENT -overflow_uint_max: - call fpoverflow - mov eax,#UINT_MAX - ret - -! ftoi is like dtoi except ebx points to a float instead of a double. -! This is a quickly-written slowish version that does not take advantage -! of the float being smaller. - - .globl ftoi - .globl ftol - .align ALIGNMENT -ftoi: -ftol: - call Fpushf - mov ebx,esp - call dtoi - add esp,#D_SIZE - ret diff --git a/bin86-0.3/bccfp/fpulld.x b/bin86-0.3/bccfp/fpulld.x deleted file mode 100644 index 928a846..0000000 --- a/bin86-0.3/bccfp/fpulld.x +++ /dev/null @@ -1,20 +0,0 @@ -! bcc 386 floating point routines (version 2) -- Fpulld -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - -! Pop double from stack and store at address [ebx] - - .globl Fpulld - .align ALIGNMENT -Fpulld: - pop ecx - pop dword D_LOW[ebx] - pop dword D_HIGH[ebx] - jmp ecx ! return - -! This popping method is much slower on 486's because popping to memory -! takes 5+ while moving twice takes 2 and the return address doesn't -! have to be moved. However, popping is a little faster on a non-cached -! 386/20 with static column RAM although the memory access pattern is -! better for a double-width move than for popping. What about a cached 386? diff --git a/bin86-0.3/bccfp/fpullf.x b/bin86-0.3/bccfp/fpullf.x deleted file mode 100644 index 417ef92..0000000 --- a/bin86-0.3/bccfp/fpullf.x +++ /dev/null @@ -1,101 +0,0 @@ -! bcc 386 floating point routines (version 2) -- Fpullf -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern fpoverflow - .extern fpunderflow - -! pop double from stack, convert to float and store at address [ebx] - - .globl Fpullf - .align ALIGNMENT -Fpullf: - -! Step 1: load and shift left - - mov eax,PC_SIZE+D_LOW[esp] ! lower dword - mov edx,PC_SIZE+D_HIGH[esp] ! upper dword - mov ecx,edx ! copy upper dword into ecx ... - and ecx,#D_SIGN_MASK ! ... and extract sign - and edx,#D_EXP_MASK | D_FRAC_MASK ! extract exponent and fraction - sub edx,#(D_EXP_BIAS-F_EXP_BIAS) << D_EXP_SHIFT ! adjust exponent bias - jz underflow - cmp edx,#F_EXP_INFINITE << D_EXP_SHIFT ! check if exponent lies in reduced range - jae outofbounds - shld edx,eax,#D_EXP_BIT-F_EXP_BIT ! shift exponent and fraction - -! Step 2: round - - test eax,#1 << (REG_BIT-1-(D_EXP_BIT-F_EXP_BIT)) ! test upper rounding bit - jz step3 ! below middle, don't round up - test eax,#(1 << (REG_BIT-1-(D_EXP_BIT-F_EXP_BIT)))-1 ! test other rounding bits - jnz roundup ! above middle, round up - test dl,#1 ! in middle, check parity bit - jz step3 ! already even, otherwise round up to make even - -roundup: - inc edx ! carry 1 - test edx,#F_FRAC_MASK ! is fraction now 0? (carry into F_EXPMASK) - jnz step3 ! no -- carry complete - cmp edx,#(F_EXP_INFINITE << F_EXP_SHIFT) & ~F_NORM_MASK ! yes (very unlikely): check for overflow - ! XXX - I think these tests say 0x7e7fffff overflows - jae overflow - -! Step 3: put it all together - -step3: - or edx,ecx ! include sign - mov F_HIGH[ebx],edx ! store the result in [ebx] - ret #D_SIZE ! return and release double from stack - - .align ALIGNMENT -outofbounds: - jns overflow ! have just compared exponent with the max -underflow: -! call fpunderflow ! XXX - push ecx ! save sign - mov ecx,edx - and ecx,#~D_FRAC_MASK ! assume fraction is below exp - cmp ecx,#-((D_EXP_BIAS-F_EXP_BIAS) << D_EXP_SHIFT) ! was exp = 0? - jz exp_x_0 - shr ecx,#D_EXP_SHIFT - neg ecx - and edx,#D_FRAC_MASK - or edx,#D_NORM_MASK - shld edx,eax,#D_EXP_BIT-F_EXP_BIT-1 - shl eax,#D_EXP_BIT-F_EXP_BIT-1 - push ebx ! save to use for rounding - sub ebx,ebx - shrd ebx,eax,cl - shrd eax,edx,cl - shr edx,cl - cmp eax,#1 << (REG_BIT-1) - jb over_denorm_roundup - ja denorm_roundup - test dl,#1 - jz over_denorm_roundup -denorm_roundup: -#if F_NORM_BIT != F_EXP_SHIFT -#include "carry into norm bit doesn't go into low exp bit" -#endif - inc edx -over_denorm_roundup: - pop ebx - pop ecx - or edx,ecx - mov F_HIGH[ebx],edx - ret #D_SIZE - - .align ALIGNMENT -exp_x_0: ! XXX check for denormals - they underflow - pop ecx - mov dword F_HIGH[ebx],#0 - ret #D_SIZE - - .align ALIGNMENT -overflow: - mov edx,ebx ! put sign in usual reg - call fpoverflow - mov F_HIGH[ebx],dword #F_HUGE_HIGH ! XXX - should use infinity - ret #D_SIZE ! ... if fpoverflow does diff --git a/bin86-0.3/bccfp/fpushd.x b/bin86-0.3/bccfp/fpushd.x deleted file mode 100644 index 68caab0..0000000 --- a/bin86-0.3/bccfp/fpushd.x +++ /dev/null @@ -1,60 +0,0 @@ -! bcc 386 floating point routines (version 2) -- dtof, Fpushd, Fneg, Fnegd -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern Fpullf - -! dtof converts the double at [ebx] to a float and pushes the float onto -! the stack (D_SIZE bytes are allocated for the float although only the bottom -! F_SIZE are used). -! This is a quickly-written slowish version. - - .globl dtof - .align ALIGNMENT -dtof: - pop eax - sub esp,#D_SIZE ! build result here - push eax ! put back return address - call Fpushd - lea ebx,D_SIZE+PC_SIZE[esp] - call Fpullf - ret - -! Push double at address [ebx] onto stack - - .globl Fpushd - .align ALIGNMENT -Fpushd: - pop ecx - push dword D_HIGH[ebx] - push dword D_LOW[ebx] - jmp ecx ! return - -! Push double at address [ebx] onto stack, negating it on the way. - -! Don't worry about generating -0 because other routines have to allow for -! it anyway. - -! Perhaps this and Fneg should check for denormals and illegal operands -! (I think only signalling NaNs are illegal). -! fchs doesn't check, but fld does. -! Our Fpushd is not quite like fld because no conversions are involved. - - .globl Fnegd - .align ALIGNMENT -Fnegd: - pop ecx - mov eax,D_HIGH[ebx] - xor eax,#D_SIGN_MASK ! toggle sign - push eax - push dword D_LOW[ebx] - jmp ecx ! return - -! Negate double on stack - - .globl Fneg - .align ALIGNMENT -Fneg: - xorb PC_SIZE+D_SIZE-1[esp],D_SIGN_MASK >> (REG_BIT-CHAR_BIT) ! toggle sign - ret diff --git a/bin86-0.3/bccfp/fpushf.x b/bin86-0.3/bccfp/fpushf.x deleted file mode 100644 index 7cb2f8d..0000000 --- a/bin86-0.3/bccfp/fpushf.x +++ /dev/null @@ -1,74 +0,0 @@ -! bcc 386 floating point routines (version 2) -- Fpushf, Fnegf -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern fpdenormal - -! Load float at [ebx], convert to double and push on stack - - .globl Fpushf - .align ALIGNMENT -Fpushf: - mov edx,F_HIGH[ebx] -into_Fpushf: - test edx,#F_EXP_MASK ! is exponent 0? - jz exp_x_0 - - mov ecx,edx ! extract sign - and ecx,#F_SIGN_MASK - - and edx,#F_EXP_MASK | F_FRAC_MASK ! extract exponent and fraction - sub eax,eax ! clear lower dword - shrd eax,edx,#D_EXP_BIT-F_EXP_BIT ! shift exponent and fraction to new position - shr edx,#D_EXP_BIT-F_EXP_BIT - - add edx,#(D_EXP_BIAS-F_EXP_BIAS) << D_EXP_SHIFT ! adjust exponent bias - or edx,ecx ! include sign - - pop ecx - push edx ! upper dword - push eax ! lower dword - jmp ecx ! return - - .align ALIGNMENT -exp_x_0: - mov eax,edx - and eax,#F_FRAC_MASK - jnz x_denorm - pop ecx - push eax ! upper dword = 0 - push eax ! lower dword = 0 - jmp ecx ! return - - .align ALIGNMENT -x_denorm: - call fpdenormal - bsr ecx,eax ! zzzz - neg ecx - add ecx,#F_NORM_BIT - shl eax,cl - and eax,#F_FRAC_MASK - neg ecx - add ecx,#D_EXP_BIAS-F_EXP_BIAS+1 - shl ecx,#D_EXP_SHIFT - and edx,#F_SIGN_MASK ! assumed same as D_SIGN_MASK - or edx,ecx - sub ecx,ecx - shrd ecx,eax,#D_EXP_BIT-F_EXP_BIT - shr eax,#D_EXP_BIT-F_EXP_BIT - or edx,eax - - pop eax - push edx ! upper dword - push ecx ! lower dword - jmp eax ! return - -! Fnegf: as Fpushf, but negate double before pushing onto stack - - .globl Fnegf - .align ALIGNMENT -Fnegf: - mov edx,F_HIGH[ebx] - xor edx,#F_SIGN_MASK ! toggle sign - jmp into_Fpushf ! join Fpushf diff --git a/bin86-0.3/bccfp/fpushi.x b/bin86-0.3/bccfp/fpushi.x deleted file mode 100644 index b19aae2..0000000 --- a/bin86-0.3/bccfp/fpushi.x +++ /dev/null @@ -1,126 +0,0 @@ -! bcc 386 floating point routines (version 2) -! -- Fpushi, Fpushl, Fpushs, Fpushc, Fpushuc, Fpushui, Fpushul, Fpushus -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - -! Convert the short in ax to double and push on stack - - .globl Fpushs - .align ALIGNMENT -Fpushs: - cwde - add eax,#0 ! fast 3-byte instruction to align - -! Convert the int or long in eax to double and push on stack - - .globl Fpushi - .globl Fpushl -! .align ALIGNMENT ! don't do this until it pads with nop's -Fpushi: -Fpushl: - test eax,eax - jz return_eax ! got 0 in eax - mov ebx,#(D_EXP_BIAS+D_NORM_BIT) << D_EXP_SHIFT ! set no-sign and exponent - jns normalize ! sign and fraction bits already set up - mov ebx,#D_SIGN_MASK | ((D_EXP_BIAS+D_NORM_BIT) << D_EXP_SHIFT) ! adjust sign - neg eax ! adjust fraction - jmp normalize - - .align ALIGNMENT -ret1: - mov eax,#D_EXP_BIAS << D_EXP_SHIFT - add eax,#0 ! fast 3-byte instruction to align - -! .align ALIGNMENT ! don't do this until it pads with nop's -return_eax: - pop ecx - push eax ! upper dword - push dword #0 ! lower dword = 0 - jmp ecx ! return - -! Convert the (unsigned) char in al to double and push on stack - - .globl Fpushc - .globl Fpushuc - .align ALIGNMENT -Fpushc: -Fpushuc: - and eax,#(1 << CHAR_BIT)-1 - add eax,#0 ! fast 3-byte instruction to align - -! Convert the unsigned short in ax to double and push on stack - - .globl Fpushus -! .align ALIGNMENT ! don't do this until it pads with nop's -Fpushus: - and eax,#(1 << SHORT_BIT)-1 - add eax,#0 ! fast 3-byte instruction to align - -! Convert the unsigned int or long in eax to double and push on stack - - .globl Fpushui - .globl Fpushul -! .align ALIGNMENT ! don't do this until it pads with nop's -Fpushui: -Fpushul: - cmp eax,#1 ! this tests for both 0 and 1 - jb return_eax ! got 0 in eax - jz ret1 - mov ebx,#(D_EXP_BIAS+D_NORM_BIT) << D_EXP_SHIFT ! set no-sign and exponent - -! .align ALIGNMENT ! don't do this until it pads with nop's -normalize: - sub edx,edx ! clear lower dword of result - -! Find first nonzero bit -! Don't use bsr, it is slow (const + 3n on 386, const + n on 486) - - sub ecx,ecx ! prepare unsigned extension of cl - test eax,#~D_FRAC_MASK - jnz large - test eax,#0xFF << (D_NORM_BIT-8) - jnz middle - shl eax,#8 - sub ebx,#8 << D_EXP_SHIFT - test eax,#0xFF << (D_NORM_BIT-8) - jnz middle - shl eax,#8 - sub ebx,#8 << D_EXP_SHIFT -middle: - shld ecx,eax,#D_NORM_BIT - mov cl,bsr_table[ecx] - add ecx,#REG_BIT-D_NORM_BIT-D_NORM_BIT - neg ecx - shl eax,cl - shl ecx,#D_EXP_SHIFT - sub ebx,ecx -return: - and eax,#D_FRAC_MASK ! remove normalization bit - or eax,ebx ! include exponent (and sign) to fraction - pop ecx - push eax ! upper dword - push edx ! lower dword - jmp ecx ! return - - .align ALIGNMENT -large: - shld ecx,eax,#REG_BIT-(D_NORM_BIT+8) - jnz huge - shld ecx,eax,#REG_BIT-D_NORM_BIT - mov cl,bsr_table[ecx] -got_shift_right: - shrd edx,eax,cl - shr eax,cl - shl ecx,#D_EXP_SHIFT - add ebx,ecx - jmp return - - .align ALIGNMENT -huge: - mov cl,bsr_table[ecx] - add cl,#8 - jmp got_shift_right - - .data - .extern bsr_table diff --git a/bin86-0.3/bccfp/frexp.x b/bin86-0.3/bccfp/frexp.x deleted file mode 100644 index 318fc34..0000000 --- a/bin86-0.3/bccfp/frexp.x +++ /dev/null @@ -1,66 +0,0 @@ -! bcc 386 floating point routines (version 2) -- _frexp -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern fpdenormal - -! void frexp(double value, int *exponent); -! splits a double into exponent and fraction (where 0.5 <= fraction < 1.0) - - .globl _frexp - .align ALIGNMENT -_frexp: -push ebx -#undef PC_SIZE -#define PC_SIZE 8 - mov eax,PC_SIZE+D_LOW[esp] ! lower dword of x - mov ebx,PC_SIZE+D_HIGH[esp] ! upper dword of x - mov edx,PC_SIZE+D_SIZE[esp] ! exponent pointer - mov ecx,ebx ! extract exponent here - and ecx,#D_EXP_MASK - jz exp_x_0 - - shr ecx,#D_EXP_SHIFT ! exponent + bias -got_x: - sub ecx,#D_EXP_BIAS-1 ! D_EXP_BIAS is for 1.x form, we want 0.1x form - mov [edx],ecx ! return exponent - and ebx,#D_SIGN_MASK | D_FRAC_MASK ! extract sign and fraction - or ebx,#(D_EXP_BIAS-1) << D_EXP_SHIFT ! set new exponent for 0.1x -mov edx,ebx -pop ebx - ret - - .align ALIGNMENT -exp_x_0: - test ebx,#D_FRAC_MASK - jnz xu_denorm - test eax,eax - jnz xl_denorm - mov [edx],ecx ! return zero exponent - mov ebx,ecx ! guard against -0 (may not be necessary) -mov edx,ebx -pop ebx - ret - - .align ALIGNMENT -xl_denorm: - call fpdenormal - bsr ecx,eax ! zzzz - neg ecx - add ecx,#REG_BIT-1 - shl eax,cl - shld ebx,eax,#D_NORM_BIT+1 - shl eax,#D_NORM_BIT+1 - sub ecx,#D_NORM_BIT+1 - jmp got_x - - .align ALIGNMENT -xu_denorm: - call fpdenormal - bsr ecx,ebx - neg ecx - add ecx,#D_NORM_BIT - shld ebx,eax,cl - shl eax,cl - jmp got_x diff --git a/bin86-0.3/bccfp/ftst.x b/bin86-0.3/bccfp/ftst.x deleted file mode 100644 index 2a92ef1..0000000 --- a/bin86-0.3/bccfp/ftst.x +++ /dev/null @@ -1,28 +0,0 @@ -! bcc 386 floating point routines (version 2) -- Ftst, Ftstd, Ftstf -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - -#if 0 /* bcc doesn't generate Ftst (but it might in future) */ - .globl Ftst -#endif - .align ALIGNMENT -Ftst: - cmp dword PC_SIZE+D_HIGH[esp],#0 ! need only test upper dword of x - ret #D_SIZE - -! Compare double at address [ebx] with 0 - - .globl Ftstd - .align ALIGNMENT -Ftstd: - cmp dword D_HIGH[ebx],#0 ! need only test upper dword of x - ret - -! Compare float at address [ebx] with 0 - - .globl Ftstf - .align ALIGNMENT -Ftstf: - cmp dword F_HIGH[ebx],#0 - ret diff --git a/bin86-0.3/bccfp/ldexp.x b/bin86-0.3/bccfp/ldexp.x deleted file mode 100644 index bc9dd03..0000000 --- a/bin86-0.3/bccfp/ldexp.x +++ /dev/null @@ -1,74 +0,0 @@ -! bcc 386 floating point routines (version 2) -- _ldexp -! authors: Timothy Murphy (tim@maths.tcd.ie), Bruce Evans - -#include "fplib.h" - - .extern fpoverflow - .extern fpunderflow - -! void ldexp(double value, int exponent); -! returns value * (2 ** exponent) - - .globl _ldexp - .align ALIGNMENT -_ldexp: -push ebx -#undef PC_SIZE -#define PC_SIZE 8 - mov ebx,PC_SIZE+D_HIGH[esp] ! upper dword of x - mov ecx,PC_SIZE+D_SIZE[esp] ! exponent arg - mov eax,ebx ! extract exponent (of x) here - and eax,#D_EXP_MASK -! jz exp_y_0 ! may need check for preposterous exponent arg too - - shr eax,#D_EXP_SHIFT ! shift to low bits just for testing - jz underflow ! denormal? - add eax,ecx ! test-add the exponents - jz underflow ! XXX probably need to fiddle norm bit - cmp eax,#D_EXP_INFINITE ! check if still within range - jae outofbounds ! the unsigned compare catches all overflow cases - ! because the exponent of x is non-negative - - shl ecx,#D_EXP_SHIFT ! shift exponent arg bits into final position ... - add ebx,ecx ! ... safe to add it to exponent of x now - mov eax,PC_SIZE+D_LOW[esp] ! lower dword of x -mov edx,ebx -pop ebx - ret - - - .align ALIGNMENT -outofbounds: - test ecx,ecx ! overflow or underflow? - jns overflow -underflow: - mov edx,ebx ! put sign in usual reg - push edi - push esi - mov edi,eax ! put exponent in usual reg - mov eax,2*GENREG_SIZE+PC_SIZE+D_LOW[esp] - ! put lower dword of x in usual reg - mov esi,ebx ! put upper dword of x in usual reg - and esi,#D_EXP_MASK | D_FRAC_MASK - test esi,#D_EXP_MASK - jz foo - and esi,#D_FRAC_MASK - or esi,#D_NORM_MASK -foo: - neg edi -! inc edi ! XXX ? - call fpunderflow - pop esi - pop edi - mov ebx,edx ! XXX = wrong reg -pop ebx - ret - - .align ALIGNMENT -overflow: - mov edx,ebx ! put sign in usual reg - call fpoverflow - mov eax,ecx ! XXX = wrong reg - mov ebx,edx ! XXX = wrong reg -pop ebx - ret diff --git a/bin86-0.3/bccfp/modf.c b/bin86-0.3/bccfp/modf.c deleted file mode 100644 index a83f801..0000000 --- a/bin86-0.3/bccfp/modf.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * bin86/bccfp/modf.c - * - * Copyright (C) 1992 Bruce Evans - */ - -#include <math.h> - -/* Slooow version. */ - -double modf(x, pint) -double x; -double *pint; -{ - if (x >= 0) - *pint = floor(x); - else - *pint = ceil(x); - return x - *pint; -} diff --git a/bin86-0.3/bccfp/test.c b/bin86-0.3/bccfp/test.c deleted file mode 100644 index 05b5d84..0000000 --- a/bin86-0.3/bccfp/test.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * bin86/bccfp/test.c - * - * Copyright (C) 1992 Bruce Evans - */ - -#include <sys/times.h> -#include <limits.h> -#include <stdio.h> -#include <time.h> - -#define CONVTYPE int -#define MAX (MIN + NITER - 1) -#define MIN INT_MIN - -#define NITER 100000 - -double one = 1; -double two = 2; -double big = 1e99; - -double d; -double d1; -float f; - -int main() -{ - CONVTYPE cti; - CONVTYPE cto; - clock_t delta; - struct tms finish; - int i; - struct tms start; - -#if 0 - times(&start); - for (cti = MIN; cti <= MAX; ++cti) - { - d = cti; - cto = d; - if (cti != cto) - printf("%08x %08x\n", cti, cto); - if (cti % 10000000 == 0) - { - printf("%8x ok ", cti); - fflush(stdout); - } - } - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for %d i -> d and d -> i conversions was %g s (%d t)\n", - MAX - MIN + 1, delta / (double) CLOCKS_PER_SEC, delta); -#endif - - times(&start); - for (cti = MIN; cti <= MAX; ++cti) - d = cti; - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for %d i -> d conversions was %g s (%d t)\n", - MAX - MIN + 1, delta / (double) CLOCKS_PER_SEC, delta); - - times(&start); - for (cti = MIN; cti <= MAX; ++cti) - { - d = cti; - cto = d; - } - times(&finish); - delta = finish.tms_utime - start.tms_utime - delta; - printf("Time for %d d -> i conversions was %g s (%d t)\n", - MAX - MIN + 1, delta / (double) CLOCKS_PER_SEC, delta); - - d = 0; - times(&start); - for (i = 0; i < NITER; ++i) - d = d + 1; - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for adding %d 1.0's to 0.0 was %g s (%d t), result = %g\n", - NITER, delta / (double) CLOCKS_PER_SEC, delta, d); - - d = 0; - times(&start); - for (; d < NITER;) - d = d + 1; - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for adding %d 1.0's to 0.0 (d index) was %g s (%d t), result = %g\n", - NITER, delta / (double) CLOCKS_PER_SEC, delta, d); - - times(&start); - for (i = 1; i <= NITER; ++i) - { - d1 = i; - d = d1 * d1; - } - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for %d mults was %g s (%d t), result = %g\n", - NITER, delta / (double) CLOCKS_PER_SEC, delta, d); - - times(&start); - for (i = 1; i <= NITER; ++i) - { - d1 = i; - d = 1 / d1; - } - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for %d divs was %g s (%d t), result = %g\n", - NITER, delta / (double) CLOCKS_PER_SEC, delta, d); - - f = 0; - times(&start); - for (i = 0; i < NITER; ++i) - f = f + 1; - times(&finish); - delta = finish.tms_utime - start.tms_utime; - printf("Time for adding %d 1.0f's to 0.0f was %g s (%d t), result = %g\n", - NITER, delta / (double) CLOCKS_PER_SEC, delta, f); - - return 0; -} diff --git a/bin86-0.3/ld/6809/config.h b/bin86-0.3/ld/6809/config.h deleted file mode 100644 index b2203ab..0000000 --- a/bin86-0.3/ld/6809/config.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * bin86/ld/6809/config.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* config.h - configuration for linker */ - -/* one of these target processors must be defined */ - -#undef I8086 /* Intel 8086 */ -#undef I80386 /* Intel 80386 */ -#define MC6809 /* Motorola 6809 */ - -/* one of these target operating systems must be defined */ - -#define EDOS /* generate EDOS executable */ -#undef MINIX /* generate Minix executable */ - -/* these may need to be defined to suit the source processor */ - -#undef S_ALIGNMENT 4 /* source memory alignment, power of 2 */ - /* don't use for 8 bit processors */ - /* don't use even for 80386 - overhead for */ - /* alignment cancels improved access */ - -/* these should be defined if they are supported by the source compiler */ - -#undef PROTO /* compiler handles prototypes */ - -/* these must be defined to suit the source libraries */ - -#define CREAT_PERMS 0666 /* permissions for creat() */ -#define EXEC_PERMS 0111 /* extra permissions to set for executable */ diff --git a/bin86-0.3/ld/Makefile b/bin86-0.3/ld/Makefile deleted file mode 100644 index a7da6d7..0000000 --- a/bin86-0.3/ld/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -CC =gcc -CFLAGS =-O1 -fomit-frame-pointer -INC_CFLAGS =-DBSD_A_OUT -I../a.out.h -D__linux__ -LDFLAGS =-s - -OBJS =dumps.o io.o ld.o readobj.o table.o typeconv.o \ - writebin.o - -.SUFFIXES: -.SUFFIXES: .c .o - -.c.o: - $(CC) $(CFLAGS) $(INC_CFLAGS) -c $< - -all: ld86 - -ld86: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) - -clean: - $(RM) $(OBJS) ld86 core - -dumps.o: dumps.c const.h config.h obj.h type.h globvar.h -io.o: io.c const.h config.h type.h globvar.h -ld.o: ld.c const.h config.h type.h byteord.h globvar.h -readobj.o: readobj.c const.h config.h byteord.h obj.h type.h globvar.h -table.o: table.c const.h config.h align.h obj.h type.h globvar.h -typeconv.o: typeconv.c const.h config.h type.h globvar.h -writebin.o: writebin.c const.h config.h obj.h type.h globvar.h diff --git a/bin86-0.3/ld/align.h b/bin86-0.3/ld/align.h deleted file mode 100644 index f34652c..0000000 --- a/bin86-0.3/ld/align.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bin86/ld/align.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* align.h - memory alignment requirements for linker */ - -#ifndef S_ALIGNMENT -# define align(x) -#else -# define align(x) ((x) = (void *)(((int) (x) + (S_ALIGNMENT-1)) & ~(S_ALIGNMENT-1))) - /* assumes sizeof(int) == sizeof(char *) */ -#endif diff --git a/bin86-0.3/ld/ar.h b/bin86-0.3/ld/ar.h deleted file mode 100644 index 780d457..0000000 --- a/bin86-0.3/ld/ar.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * bin86/ld/ar.h - * - * Copyright (C) 1992 Bruce Evans - */ - -#ifndef _AR_H -#define _AR_H - -#define ARMAG "!<arch>\n" -#define SARMAG 8 -#define ARFMAG "`\n" - -struct ar_hdr { - char ar_name[16]; - char ar_date[12]; - char ar_uid[6]; - char ar_gid[6]; - char ar_mode[8]; - char ar_size[10]; - char ar_fmag[2]; -}; - -#endif /* _AR_H */ diff --git a/bin86-0.3/ld/bugs b/bin86-0.3/ld/bugs deleted file mode 100644 index b671f30..0000000 --- a/bin86-0.3/ld/bugs +++ /dev/null @@ -1,17 +0,0 @@ -1. Should cause error when an address which requires > 16 bits is referenced - using 16 bits. - -TODO: - integrate byteord.h with compiler as well as assembler - -TODO: - integrate align.h with compiler and assembler - use alignment for *86 like compiler - use more portable macro - ((x) + (-(int) (x) & MASK)) when it is either necessary or - faster - -TODO: - do malloc stuff better, as in compiler - -2. Error message about "foo.a is not an object file" is confusing - should - name archive member. diff --git a/bin86-0.3/ld/byteord.h b/bin86-0.3/ld/byteord.h deleted file mode 100644 index 0e2b403..0000000 --- a/bin86-0.3/ld/byteord.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * bin86/ld/byteord.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* byteord.h - byte order dependencies for C compiler, assembler, linker */ - -/* These are for the targets of everything and for linker source too. */ - -#ifdef I8086 -# define BIG_ENDIAN 0 -# define LONG_BIG_ENDIAN 0 /* except longs are back to front for Xenix */ -#endif - -#ifdef I80386 -# define BIG_ENDIAN 0 -# define LONG_BIG_ENDIAN 0 -#endif - -#ifdef MC6809 -# define BIG_ENDIAN 1 /* byte order in words is high-low */ -# define LONG_BIG_ENDIAN 1 /* byte order in longs is high-low */ -#endif diff --git a/bin86-0.3/ld/config.h b/bin86-0.3/ld/config.h deleted file mode 100644 index 173d1c4..0000000 --- a/bin86-0.3/ld/config.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * bin86/ld/config.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* config.h - configuration for linker */ - -/* one of these target processors must be defined */ - -#undef I8086 /* Intel 8086 */ -#define I80386 /* Intel 80386 */ -#undef MC6809 /* Motorola 6809 */ - -/* one of these target operating systems must be defined */ - -#undef EDOS /* generate EDOS executable */ -#define MINIX /* generate Minix executable */ - -/* these may need to be defined to suit the source processor */ - -#define S_ALIGNMENT 4 /* source memory alignment, power of 2 */ - /* don't use for 8 bit processors */ - /* don't use even for 80386 - overhead for */ - /* alignment cancels improved access */ - -/* these should be defined if they are supported by the source compiler */ - -#define PROTO /* compiler handles prototypes */ - -/* these must be defined to suit the source libraries */ - -#define CREAT_PERMS 0666 /* permissions for creat() */ -#define EXEC_PERMS 0111 /* extra permissions to set for executable */ diff --git a/bin86-0.3/ld/const.h b/bin86-0.3/ld/const.h deleted file mode 100644 index a933bdc..0000000 --- a/bin86-0.3/ld/const.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * bin86/ld/const.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* const.h - constants for linker */ - -#define FALSE 0 -#ifndef NULL -#define NULL 0 -#endif -#define TRUE 1 - -#define EXTERN extern -#define FORWARD static -#define PRIVATE static -#define PUBLIC - -#include "config.h" diff --git a/bin86-0.3/ld/dumps.c b/bin86-0.3/ld/dumps.c deleted file mode 100644 index c91653f..0000000 --- a/bin86-0.3/ld/dumps.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * bin86/ld/dumps.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* dumps.c - print data about symbols and modules for linker */ - -#include "const.h" -#include "obj.h" -#include "type.h" -#include "globvar.h" - -/* print list of modules and whether they are loaded */ - -PUBLIC void dumpmods() -{ - struct modstruct *modptr; - - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - { - putstr(modptr->loadflag ? "L " : " "); - putbstr(20, modptr->modname); - putbyte('\n'); - } -} - -/* print data about symbols (in loaded modules only) */ - -PUBLIC void dumpsyms() -{ - flags_t flags; - struct modstruct *modptr; - struct symstruct **symparray; - struct symstruct *symptr; - char uflag; - - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - if (modptr->loadflag) - { - for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) - if (symptr->modptr == modptr) - { - uflag = FALSE; - if (((flags = symptr->flags) & (C_MASK | I_MASK)) == I_MASK) - uflag = TRUE; - putbstr(20, uflag ? "" : modptr->modname); - putstr(" "); - putbstr(20, symptr->name); - putstr(" "); - putbyte(hexdigit[flags & SEGM_MASK]); - putstr(" "); - if (uflag) - putstr(" "); - else -#ifdef LONG_OFFSETS - put08lx(symptr->value); -#else - put08x(symptr->value); -#endif - putstr(flags & A_MASK ? " A" : " R"); - if (uflag) - putstr(" U"); - if (flags & C_MASK) - putstr(" C"); - if (flags & N_MASK) - putstr(" N"); - putbyte('\n'); - } - } -} diff --git a/bin86-0.3/ld/globvar.h b/bin86-0.3/ld/globvar.h deleted file mode 100644 index 0c382c7..0000000 --- a/bin86-0.3/ld/globvar.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bin86/ld/globvar.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* globvar.h - global variables for linker */ - -#ifdef EXTERN -EXTERN char hexdigit[]; -#else -#define EXTERN -PUBLIC char hexdigit[] = "0123456789abcdef"; -#endif -EXTERN unsigned errcount; /* count of errors */ -EXTERN struct entrylist *entryfirst; /* first on list of entry symbols */ -EXTERN struct modstruct *modfirst; /* data for 1st module */ -EXTERN struct redlist *redfirst; /* first on list of redefined symbols */ diff --git a/bin86-0.3/ld/io.c b/bin86-0.3/ld/io.c deleted file mode 100644 index 999dbd3..0000000 --- a/bin86-0.3/ld/io.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * bin86/ld/io.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* io.c - input/output and error modules for linker */ - -#include <sys/types.h> -#include <sys/stat.h> -#ifndef __linux__ -#define MY_STAT_H -#endif -#include <fcntl.h> -#include <unistd.h> -#include "const.h" -#include "obj.h" /* needed for LONG_OFFSETS and offset_t */ -#include "type.h" -#include "globvar.h" - -#define DRELBUFSIZE 2048 -#define ERR (-1) -#define ERRBUFSIZE 1024 -#define INBUFSIZE 1024 -#define OUTBUFSIZE 2048 -#define TRELBUFSIZE 1024 - -#ifdef BSD_A_OUT -PRIVATE char *drelbuf; /* extra output buffer for data relocations */ -PRIVATE char *drelbufptr; /* data relocation output buffer ptr */ -PRIVATE char *drelbuftop; /* data relocation output buffer top */ -#endif -PRIVATE char *errbuf; /* error buffer (actually uses STDOUT) */ -PRIVATE char *errbufptr; /* error buffer ptr */ -PRIVATE char *errbuftop; /* error buffer top */ -PRIVATE char *inbuf; /* input buffer */ -PRIVATE char *inbufend; /* input buffer top */ -PRIVATE char *inbufptr; /* end of input in input buffer */ -PRIVATE int infd; /* input file descriptor */ -PRIVATE char *inputname; /* name of current input file */ -PRIVATE char *outbuf; /* output buffer */ -PRIVATE char *outbufptr; /* output buffer ptr */ -PRIVATE char *outbuftop; /* output buffer top */ -PRIVATE int outfd; /* output file descriptor */ -PRIVATE unsigned outputperms; /* permissions of output file */ -PRIVATE char *outputname; /* name of output file */ -PRIVATE char *refname; /* name of program for error reference */ -#ifdef BSD_A_OUT -PRIVATE char *trelbuf; /* extra output buffer for text relocations */ -PRIVATE char *trelbufptr; /* text relocation output buffer ptr */ -PRIVATE char *trelbuftop; /* text relocation output buffer top */ -PRIVATE int trelfd; /* text relocation output file descriptor */ -#endif -PRIVATE unsigned warncount; /* count of warnings */ - -FORWARD void errexit P((char *message)); -FORWARD void flushout P((void)); -#ifdef BSD_A_OUT -FORWARD void flushtrel P((void)); -#endif -FORWARD void outhexdigs P((offset_t num)); -FORWARD void outputerror P((char *message)); -FORWARD void put04x P((unsigned num)); -FORWARD void putstrn P((char *message)); -FORWARD void refer P((void)); - -PUBLIC void ioinit(progname) -char *progname; -{ - infd = ERR; - if (*progname) - refname = progname; /* name must be static (is argv[0]) */ - else - refname = "link"; -#ifdef BSD_A_OUT - drelbuf = malloc(DRELBUFSIZE); - drelbuftop = drelbuf + DRELBUFSIZE; -#endif - errbuf = malloc(ERRBUFSIZE); - errbufptr = errbuf; - errbuftop = errbuf + ERRBUFSIZE; - inbuf = malloc(INBUFSIZE); - outbuf = malloc(OUTBUFSIZE);/* outbuf invalid if this fails but then */ - /* will not be used - tableinit() aborts */ - outbuftop = outbuf + OUTBUFSIZE; -#ifdef BSD_A_OUT - trelbuf = malloc(TRELBUFSIZE); - trelbuftop = trelbuf + TRELBUFSIZE; -#endif -} - -PUBLIC void closein() -{ - if (infd != ERR && close(infd) < 0) - inputerror("cannot close"); - infd = ERR; -} - -PUBLIC void closeout() -{ -#ifdef BSD_A_OUT - unsigned nbytes; -#endif - - flushout(); -#ifdef BSD_A_OUT - flushtrel(); - nbytes = drelbufptr - drelbuf; - if (write(trelfd, drelbuf, nbytes) != nbytes) - outputerror("cannot write"); -#endif - if (close(outfd) == ERR) - outputerror("cannot close"); -#ifdef BSD_A_OUT - if (close(trelfd) == ERR) - outputerror("cannot close"); -#endif -} - -PUBLIC void errtrace(name, level) -char *name; -{ - while (level-- > 0) - putbyte(' '); - putstrn(name); -} - -PUBLIC void executable() -{ - int oldmask; - - if (errcount == 0) - { - oldmask = umask(0); - umask(oldmask); - chmod(outputname, outputperms | (EXEC_PERMS & ~oldmask)); - } -} - -PUBLIC void flusherr() -{ - write(STDOUT_FILENO, errbuf, errbufptr - errbuf); - errbufptr = errbuf; -} - -PRIVATE void flushout() -{ - unsigned nbytes; - - nbytes = outbufptr - outbuf; - if (write(outfd, outbuf, nbytes) != nbytes) - outputerror("cannot write"); - outbufptr = outbuf; -} - -#ifdef BSD_A_OUT -PRIVATE void flushtrel() -{ - unsigned nbytes; - - nbytes = trelbufptr - trelbuf; - if (write(trelfd, trelbuf, nbytes) != nbytes) - outputerror("cannot write"); - trelbufptr = trelbuf; -} -#endif - -PUBLIC void openin(filename) -char *filename; -{ -#if 0 /* XXX - this probably won't work with constructed lib names? */ - if (infd == ERR || strcmp(inputname, filename) != 0) -#endif - { - closein(); - inputname = filename; /* this relies on filename being static */ - if ((infd = open(filename, O_RDONLY)) < 0) - inputerror("cannot open"); - inbufptr = inbufend = inbuf; - } -} - -PUBLIC void openout(filename) -char *filename; -{ - struct stat statbuf; - - outputname = filename; - if ((outfd = creat(filename, CREAT_PERMS)) == ERR) - outputerror("cannot open"); - if (fstat(outfd, &statbuf) != 0) - outputerror("cannot stat"); - outputperms = statbuf.st_mode; - chmod(filename, outputperms & ~EXEC_PERMS); -#ifdef BSD_A_OUT - drelbufptr = drelbuf; -#endif - outbufptr = outbuf; -#ifdef BSD_A_OUT - if ((trelfd = open(filename, O_WRONLY)) == ERR) - outputerror("cannot reopen"); - trelbufptr = trelbuf; -#endif -} - -PRIVATE void outhexdigs(num) -register offset_t num; -{ - if (num >= 0x10) - { - outhexdigs(num / 0x10); - num %= 0x10; - } - putbyte(hexdigit[num]); -} - -PRIVATE void put04x(num) -register unsigned num; -{ - putbyte(hexdigit[num / 0x1000]); - putbyte(hexdigit[(num / 0x100) & 0x0F]); - putbyte(hexdigit[(num / 0x10) & 0x0F]); - putbyte(hexdigit[num & 0x0F]); -} - -#ifdef LONG_OFFSETS - -PUBLIC void put08lx(num) -register offset_t num; -{ - put04x(num / 0x10000); - put04x(num % 0x10000); -} - -#else /* not LONG_OFFSETS */ - -PUBLIC void put08x(num) -register offset_t num; -{ - putstr("0000"); - put04x(num); -} - -#endif /* not LONG_OFFSETS */ - -PUBLIC void putbstr(width, str) -unsigned width; -char *str; -{ - unsigned length; - - for (length = strlen(str); length < width; ++length) - putbyte(' '); - putstr(str); -} - -PUBLIC void putbyte(ch) -int ch; -{ - register char *ebuf; - - ebuf = errbufptr; - if (ebuf >= errbuftop) - { - flusherr(); - ebuf = errbufptr; - } - *ebuf++ = ch; - errbufptr = ebuf; -} - -PUBLIC void putstr(message) -char *message; -{ - while (*message != 0) - putbyte(*message++); -} - -PRIVATE void putstrn(message) -char *message; -{ - putstr(message); - putbyte('\n'); - flusherr(); -} - -PUBLIC int readchar() -{ - int ch; - - register char *ibuf; - int nread; - - ibuf = inbufptr; - if (ibuf >= inbufend) - { - ibuf = inbufptr = inbuf; - nread = read(infd, ibuf, INBUFSIZE); - if (nread <= 0) - { - inbufend = ibuf; - return ERR; - } - inbufend = ibuf + nread; - } - ch = (unsigned char) *ibuf++; - inbufptr = ibuf; - return ch; -} - -PUBLIC void readin(buf, count) -char *buf; -unsigned count; -{ - int ch; - - while (count--) - { - if ((ch = readchar()) < 0) - prematureeof(); - *buf++ = ch; - } -} - -PUBLIC bool_pt readineofok(buf, count) -char *buf; -unsigned count; -{ - int ch; - - while (count--) - { - if ((ch = readchar()) < 0) - return TRUE; - *buf++ = ch; - } - return FALSE; -} - -PUBLIC void seekin(offset) -long offset; -{ - inbufptr = inbufend = inbuf; - if (lseek(infd, offset, SEEK_SET) < 0) - prematureeof(); -} - -PUBLIC void seekout(offset) -long offset; -{ - flushout(); - if (lseek(outfd, offset, SEEK_SET) != offset) - outputerror("cannot seek in"); -} - -#ifdef BSD_A_OUT -PUBLIC void seektrel(offset) -long offset; -{ - flushtrel(); - if (lseek(trelfd, offset, SEEK_SET) != offset) - outputerror("cannot seek in"); -} -#endif - -PUBLIC void writechar(ch) -int ch; -{ - register char *obuf; - - obuf = outbufptr; - if (obuf >= outbuftop) - { - flushout(); - obuf = outbufptr; - } - *obuf++ = ch; - outbufptr = obuf; -} - -#ifdef BSD_A_OUT -PUBLIC void writedrel(buf, count) -register char *buf; -unsigned count; -{ - register char *rbuf; - - rbuf = drelbufptr; - while (count--) - { - if (rbuf >= drelbuftop) - inputerror("data relocation buffer full while processing"); - *rbuf++ = *buf++; - } - drelbufptr = rbuf; -} -#endif - -PUBLIC void writeout(buf, count) -register char *buf; -unsigned count; -{ - register char *obuf; - - obuf = outbufptr; - while (count--) - { - if (obuf >= outbuftop) - { - outbufptr = obuf; - flushout(); - obuf = outbufptr; - } - *obuf++ = *buf++; - } - outbufptr = obuf; -} - -#ifdef BSD_A_OUT -PUBLIC void writetrel(buf, count) -register char *buf; -unsigned count; -{ - register char *rbuf; - - rbuf = trelbufptr; - while (count--) - { - if (rbuf >= trelbuftop) - { - trelbufptr = rbuf; - flushtrel(); - rbuf = trelbufptr; - } - *rbuf++ = *buf++; - } - trelbufptr = rbuf; -} -#endif - -/* error module */ - -PRIVATE void errexit(message) -char *message; -{ - putstrn(message); - exit(2); -} - -PUBLIC void fatalerror(message) -char *message; -{ - refer(); - errexit(message); -} - -PUBLIC void inputerror(message) -char *message; -{ - refer(); - putstr(message); - putstr(" input file "); - errexit(inputname); -} - -PUBLIC void input1error(message) -char *message; -{ - refer(); - putstr(inputname); - errexit(message); -} - -PRIVATE void outputerror(message) -char *message; -{ - refer(); - putstr(message); - putstr(" output file "); - errexit(outputname); -} - -PUBLIC void outofmemory() -{ - inputerror("out of memory while processing"); -} - -PUBLIC void prematureeof() -{ - inputerror("premature end of"); -} - -PUBLIC void redefined(name, message, archentry, deffilename, defarchentry) -char *name; -char *message; -char *archentry; -char *deffilename; -char *defarchentry; -{ - ++warncount; - refer(); - putstr("warning: "); - putstr(name); - putstr(" redefined"); - putstr(message); - putstr(" in file "); - putstr(inputname); - if (archentry != NULL) - { - putbyte('('); - putstr(archentry); - putbyte(')'); - } - putstr("; using definition in "); - putstr(deffilename); - if (defarchentry != NULL) - { - putbyte('('); - putstr(defarchentry); - putbyte(')'); - } - putbyte('\n'); -} - -PRIVATE void refer() -{ - putstr(refname); - putstr(": "); -} - -PUBLIC void reserved(name) -char *name; -{ - ++errcount; - putstr("incorrect use of reserved symbol: "); - putstrn(name); -} - -PUBLIC void size_error(seg, count, size) -char seg; -offset_t count; -offset_t size; -{ - refer(); - putstr("seg "); - outhexdigs((offset_t) seg); - putstr(" has wrong size "); - outhexdigs(count); - putstr(", supposed to be "); - outhexdigs(size); - errexit("\n"); -} - -PUBLIC void undefined(name) -char *name; -{ - ++errcount; - putstr("undefined symbol: "); - putstrn(name); -} - -PUBLIC void usage() -{ - putstr("usage: "); - putstr(refname); -#ifdef BSD_A_OUT - errexit("\ - [-03Mimrstz[-]] [-llib_extension] [-o outfile] [-Ccrtfile]\n\ - [-L libdir] [-Olibfile] [-T textaddr] infile..."); -#else - errexit("\ - [-03Mimstz[-]] [-llib_extension] [-o outfile] [-Ccrtfile]\n\ - [-L libdir] [-Olibfile] [-T textaddr] infile..."); -#endif -} - -PUBLIC void use_error(message) -char *message; -{ - refer(); - putstrn(message); - usage(); -} diff --git a/bin86-0.3/ld/ld.c b/bin86-0.3/ld/ld.c deleted file mode 100644 index 04ffe83..0000000 --- a/bin86-0.3/ld/ld.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * bin86/ld/ld.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* ld.c - linker for Introl format (6809 C) object files 6809/8086/80386 */ - -#ifdef STDC_HEADERS_MISSING -extern int errno; -#else -#include <errno.h> -#endif - -#include "const.h" -#include "byteord.h" -#include "type.h" -#include "globvar.h" - -#define MAX_LIBS (NR_STDLIBS + 5) -#define NR_STDLIBS 1 - -PUBLIC long text_base_address; /* XXX */ - -PRIVATE bool_t flag[128]; -PRIVATE char *libs[MAX_LIBS] = { -#ifdef MC6809 - "/usr/local/lib/m09/", -#else - /* One of the following values will be inserted at run time. */ -# define std386lib "/usr/local/lib/i386/" -# define std86lib "/usr/local/lib/i86/" -#endif - 0 -}; -PRIVATE int lastlib = NR_STDLIBS; - -FORWARD char *buildname P((char *pre, char *mid, char *suf)); -FORWARD char *expandlib P((char *fn)); - -PRIVATE char *buildname(pre, mid, suf) -char *pre; -char *mid; -char *suf; -{ - char *name; - - name = ourmalloc(strlen(pre) + strlen(mid) + strlen(suf) + 1); - strcpy(name, pre); - strcat(name, mid); - strcat(name, suf); - return name; -} - -PRIVATE char *expandlib(fn) -char *fn; -{ - char *path; - int i; - -#ifndef MC6809 - libs[0] = flag['3'] ? std386lib : std86lib; -#endif - - for (i = lastlib - 1; i >= 0; --i) - { - path = ourmalloc(strlen(libs[i]) + strlen(fn) + 1); - strcpy(path, libs[i]); - strcat(path, fn); - if (access(path, R_OK) == 0) - return path; - ourfree(path); - } - return NULL; -} - -PUBLIC int main(argc, argv) -int argc; -char **argv; -{ - register char *arg; - int argn; - static char crtprefix[] = "crt"; - static char crtsuffix[] = ".o"; - char *infilename; - static char libprefix[] = "lib"; - static char libsuffix[] = ".a"; - char *outfilename; - char *tfn; - - ioinit(argv[0]); - objinit(); - syminit(); - typeconv_init(BIG_ENDIAN, LONG_BIG_ENDIAN); -#if 0 - flag['z'] = flag['3'] = sizeof(char *) >= 4; -#else - flag['z'] = 0; - flag['3'] = sizeof(char *) >= 4; -#endif - outfilename = NULL; - for (argn = 1; argn < argc; ++argn) - { - arg = argv[argn]; - if (*arg != '-') - readsyms(arg, flag['t']); - else - switch (arg[1]) - { - case '0': /* use 16-bit libraries */ - case '3': /* use 32-bit libraries */ - case 'M': /* print symbols linked */ - case 'i': /* separate I & D output */ - case 'm': /* print modules linked */ -#ifdef BSD_A_OUT - case 'r': /* relocatable output */ -#endif - case 's': /* strip symbols */ - case 't': /* trace modules linked */ - case 'z': /* unmapped zero page */ - if (arg[2] == 0) - flag[arg[1]] = TRUE; - else if (arg[2] == '-' && arg[3] == 0) - flag[arg[1]] = FALSE; - else - usage(); - if (arg[1] == '0') /* flag 0 is negative logic flag 3 */ - flag['3'] = !flag['0']; - break; - case 'C': /* startfile name */ - tfn = buildname(crtprefix, arg + 2, crtsuffix); - if ((infilename = expandlib(tfn)) == NULL) - fatalerror(tfn); - readsyms(infilename, flag['t']); - break; - case 'L': /* library path */ - if (lastlib < MAX_LIBS) - libs[lastlib++] = arg + 2; - else - fatalerror("too many library paths"); - break; - case 'O': /* library file name */ - if ((infilename = expandlib(arg + 2)) == NULL) - fatalerror(arg); - readsyms(infilename, flag['t']); - break; - case 'T': /* text base address */ - if (arg[2] != 0 || ++argn >= argc) - usage(); - errno = 0; - text_base_address = strtoul(argv[argn], (char **) NULL, 16); - if (errno != 0) - use_error("invalid text address"); - break; - case 'l': /* library name */ - tfn = buildname(libprefix, arg + 2, libsuffix); - if ((infilename = expandlib(tfn)) == NULL) - fatalerror(tfn); - readsyms(infilename, flag['t']); - break; - case 'o': /* output file name */ - if (arg[2] != 0 || ++argn >= argc || outfilename != NULL) - usage(); - outfilename = argv[argn]; - break; - default: - usage(); - } - } - linksyms(flag['r']); - if (outfilename == NULL) - outfilename = "a.out"; - writebin(outfilename, flag['i'], flag['3'], flag['s'], flag['z']); - if (flag['m']) - dumpmods(); - if (flag['M']) - dumpsyms(); - flusherr(); - return errcount ? 1 : 0; -} diff --git a/bin86-0.3/ld/obj.h b/bin86-0.3/ld/obj.h deleted file mode 100644 index d9ba2ba..0000000 --- a/bin86-0.3/ld/obj.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * bin86/ld/obj.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* obj.h - constants for Introl object modules */ - -#define OBJ_H - -#ifdef I80386 -# define LONG_OFFSETS /* others can use this, but wasteful */ -#endif - -#ifndef OMAGIC -# ifdef I80386 -# define OMAGIC 0x86A3 -# endif - -# ifdef I8086 -# define OMAGIC 0x86A0 -# endif - -# ifdef MC6809 -# define OMAGIC 0x5331 -# endif -#endif - -#ifdef LONG_OFFSETS -# define cntooffset cnu4 -# define offtocn u4cn -#else -# define cntooffset cnu2 -# define offtocn u2cn -#endif - -#ifdef MC6809 /* temp don't support alignment at all */ -# define ld_roundup( num, boundary, type ) (num) -#else -# define ld_roundup( num, boundary, type ) \ - (((num) + ((boundary) - 1)) & (type) ~((boundary) - 1)) -#endif - -#define MAX_OFFSET_SIZE 4 -#define NSEG 16 - -/* flag values |SZ|LXXXX|N|E|I|R|A|SEGM|, X not used */ - -#define A_MASK 0x0010 /* absolute */ -#define C_MASK 0x0020 /* common (internal only) */ -#define E_MASK 0x0080 /* exported */ -#define I_MASK 0x0040 /* imported */ -#define N_MASK 0x0100 /* entry point */ -#define R_MASK 0x0020 /* relative (in text only) */ -#define SEGM_MASK 0x000F /* segment (if not absolute) */ -#define SA_MASK 0x2000 /* offset is storage allocation */ -#define SZ_MASK 0xC000 /* size descriptor for value */ -#define SZ_SHIFT 14 diff --git a/bin86-0.3/ld/readobj.c b/bin86-0.3/ld/readobj.c deleted file mode 100644 index 5c4dd72..0000000 --- a/bin86-0.3/ld/readobj.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * bin86/ld/readobj.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* readobj.c - read object file for linker */ - -#include "ar.h" /* maybe local copy of <ar.h> for cross-link */ -#include "const.h" -#include "byteord.h" -#include "obj.h" -#include "type.h" -#include "globvar.h" - -/* - Linking takes 2 passes. The 1st pass reads through all files specified -in the command line, and all libraries. All public symbols are extracted -and stored in a chained hash table. For each module, its file and header -data recorded, and the resulting structures are chained together -(interleaved with the symbols). - - The symbol descriptors are separated from the symbol names, so we must -record all the descriptors of a module before putting the symbols in the -symbol table (poor design). The descriptors are stored in the symbol -table, then moved to the top of the table to make room for the symols. -The symbols referred to in a given module are linked together by a chain -beginning in the module descriptor. -*/ - -PRIVATE char convertsize[NSEG / 4] = {0, 1, 2, 4}; -PRIVATE struct entrylist *entrylast; /* last on list of entry symbols */ -PRIVATE struct redlist *redlast; /* last on list of redefined symbols */ -PRIVATE struct modstruct *modlast; /* data for last module */ - -FORWARD long readarheader P((char **parchentry)); -FORWARD unsigned readfileheader P((void)); -FORWARD void readmodule P((char *filename, char *archentry)); -FORWARD void reedmodheader P((void)); -FORWARD bool_pt redsym P((struct symstruct *symptr, offset_t value)); -FORWARD unsigned checksum P((char *string, unsigned length)); -FORWARD unsigned segbits P((unsigned seg, char *sizedesc)); - -/* initialise object file handler */ - -PUBLIC void objinit() -{ - modfirst = modlast = NULL; - entryfirst = entrylast = NULL; - redfirst = redlast = NULL; -} - -/* read all symbol definitions in an object file */ - -PUBLIC void readsyms(filename, trace) -char *filename; -bool_pt trace; -{ - char *archentry; - long filelength; - char filemagic[SARMAG]; - long filepos; - unsigned modcount; - - if (trace) - errtrace(filename, 0); - openin(filename); /* input is not open, so position is start */ - switch ((unsigned) readsize(2)) - { - case OMAGIC: - seekin(0L); - for (modcount = readfileheader(); modcount-- != 0;) - readmodule(filename, (char *) NULL); - break; - default: - seekin(0L); - readin(filemagic, sizeof filemagic); - if (strncmp(filemagic, ARMAG, sizeof filemagic) != 0) - input1error(" has bad magic number"); - filepos = SARMAG; - while ((filelength = readarheader(&archentry)) > 0) - { - if (trace) - errtrace(archentry, 2); - filepos += sizeof(struct ar_hdr); - for (modcount = readfileheader(); modcount-- != 0;) - { - readmodule(stralloc(filename), archentry); - modlast->textoffset += filepos; - } - seekin(filepos += ld_roundup(filelength, 2, long)); - } - break; - } - closein(); -} - -/* read archive header and return length */ - -PRIVATE long readarheader(parchentry) -char **parchentry; -{ - struct ar_hdr arheader; - char *endptr; - char *nameptr; - - if (readineofok((char *) &arheader, sizeof arheader)) - return 0; - strncpy (*parchentry = nameptr = ourmalloc(sizeof arheader.ar_name + 1), - arheader.ar_name, sizeof arheader.ar_name); - endptr = nameptr + sizeof arheader.ar_name; - do - *endptr = 0; - while (endptr > nameptr && *--endptr == ' '); - return strtoul(arheader.ar_size, (char **) NULL, 0); -} - -/* read and check file header of the object file just opened */ - -PRIVATE unsigned readfileheader() -{ - struct - { - char magic[2]; - char count[2]; /* really an int */ - } - fileheader; - char filechecksum; /* part of fileheader but would unalign */ - - readin((char *) &fileheader, sizeof fileheader); - readin(&filechecksum, sizeof filechecksum); - if (filechecksum != checksum((char *) &fileheader, sizeof fileheader)) - input1error(" is not an object file"); - return c2u2(fileheader.count); -} - -/* read the next module */ - -PRIVATE void readmodule(filename, archentry) -char *filename; -char *archentry; -{ - struct symdstruct /* to save parts of symbol before name known */ - { - offset_t dvalue; - flags_t dflags; - }; - struct symdstruct *endsymdptr; - flags_t flags; - unsigned nsymbol; - struct symdstruct *symdptr; - char *symname; - struct symstruct **symparray; - struct symstruct *symptr; - - reedmodheader(); - modlast->filename = filename; - modlast->archentry = archentry; - nsymbol = readsize(2); - symdptr = (struct symdstruct *) - ourmalloc(nsymbol * sizeof(struct symdstruct)); - for (endsymdptr = symdptr + nsymbol; symdptr < endsymdptr; ++symdptr) - { - readsize(2); /* discard string offset, assume strings seq */ - symdptr->dflags = flags = readsize(2); - symdptr->dvalue = readconvsize((flags & SZ_MASK) >> SZ_SHIFT); - /* NB unsigned flags to give logical shift */ - /* bug in Xenix 2.5 cc causes (int) of the */ - /* argument to turn flags into an int */ - } - symdptr = (struct symdstruct *) - moveup(nsymbol * sizeof(struct symdstruct)); - modlast->symparray = symparray = (struct symstruct **) - ourmalloc((nsymbol + 1) * sizeof(struct symstruct *)); - symname = readstring(); /* module name */ - modlast->modname = stralloc(symname); /* likely OK overlapped copy */ - for (endsymdptr = symdptr + nsymbol; symdptr < endsymdptr; - *symparray++ = symptr, release((char *) ++symdptr)) - { - symname = readstring(); - if ((flags = symdptr->dflags) & (E_MASK | I_MASK) && - (symptr = findsym(symname)) != NULL) - { - /* - weaken segment-checking by letting the maximum segment - (SEGM_MASK) mean any segment - */ - if ((symptr->flags & SEGM_MASK) == SEGM_MASK) - symptr->flags &= ~SEGM_MASK | (flags & SEGM_MASK); - else if ((flags & SEGM_MASK) == SEGM_MASK) - flags &= ~SEGM_MASK | (symptr->flags & SEGM_MASK); - if ((flags ^ symptr->flags) & (N_MASK | A_MASK | SEGM_MASK)) - { - redefined(symname, " with different segment or relocatability", - archentry, symptr->modptr->filename, - symptr->modptr->archentry); - continue; - } - if (symptr->flags & E_MASK) - { - if (flags & E_MASK && redsym(symptr, symdptr->dvalue)) - redefined(symname, "", archentry, symptr->modptr->filename, - symptr->modptr->archentry); - continue; - } - if (flags & I_MASK && symdptr->dvalue <= symptr->value) - continue; - } - else - symptr = addsym(symname); - symptr->modptr = modlast; - symptr->value = symdptr->dvalue; - symptr->flags = flags; - if (flags & N_MASK) - entrysym(symptr); - } - *symparray = NULL; -} - -/* put symbol on entry symbol list if it is not already */ - -PUBLIC void entrysym(symptr) -struct symstruct *symptr; -{ - register struct entrylist *elptr; - - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) - if (symptr == elptr->elsymptr) - return; - elptr = (struct entrylist *) ourmalloc(sizeof(struct entrylist)); - elptr->elnext = NULL; - elptr->elsymptr = symptr; - if (entryfirst == NULL) - entryfirst = elptr; - else - entrylast->elnext = elptr; - entrylast = elptr; -} - -/* read the header of the next module */ - -PRIVATE void reedmodheader() -{ - struct - { - char htextoffset[4]; /* offset to module text in file */ - char htextsize[4]; /* size of text (may be 0 for last mod) */ - char stringssize[2]; /* size of string area */ - char hclass; /* module class */ - char revision; /* module revision */ - } - modheader; - unsigned seg; - unsigned count; - char *cptr; - struct modstruct *modptr; - - readin((char *) &modheader, sizeof modheader); - modptr = (struct modstruct *) ourmalloc(sizeof(struct modstruct)); - modptr->modnext = NULL; - modptr->textoffset = c4u4(modheader.htextoffset); - modptr->class = modheader.hclass; - readin(modptr->segmaxsize, sizeof modptr->segmaxsize); - readin(modptr->segsizedesc, sizeof modptr->segsizedesc); - cptr = modptr->segsize; - for (seg = 0; seg < NSEG; ++seg) - { - if ((count = segsizecount(seg, modptr)) != 0) - { - if (cptr == modptr->segsize) - ourmalloc(count - 1); /* 1st byte reserved in struct */ - else - ourmalloc(count); - readin(cptr, count); - cptr += count; - } - } - if (modfirst == NULL) - modfirst = modptr; - else - modlast->modnext = modptr; - modlast = modptr; -} - -PRIVATE bool_pt redsym(symptr, value) -register struct symstruct *symptr; -offset_t value; -{ - register struct redlist *rlptr; - char class; - - if (symptr->modptr->class != (class = modlast->class)) - for (rlptr = redfirst;; rlptr = rlptr->rlnext) - { - if (rlptr == NULL) - { - rlptr = (struct redlist *) - ourmalloc(sizeof(struct redlist)); - rlptr->rlnext = NULL; - rlptr->rlsymptr = symptr; - if (symptr->modptr->class < class) - /* prefer lower class - put other on redlist */ - { - rlptr->rlmodptr = modlast; - rlptr->rlvalue = value; - } - else - { - rlptr->rlmodptr = symptr->modptr; - symptr->modptr = modlast; - rlptr->rlvalue = symptr->value; - symptr->value = value; - } - if (redfirst == NULL) - redfirst = rlptr; - else - redlast->rlnext = rlptr; - redlast = rlptr; - return FALSE; - } - if (symptr == rlptr->rlsymptr && class == rlptr->rlmodptr->class) - break; - } - return TRUE; -} - -PRIVATE unsigned checksum(string, length) -char *string; -unsigned length; -{ - unsigned char sum; /* this is a 1-byte checksum */ - - for (sum = 0; length-- != 0;) - sum += *string++ & 0xFF; - return sum; -} - -PUBLIC offset_t readconvsize(countindex) -unsigned countindex; -{ - return readsize(convertsize[countindex]); -} - -PUBLIC offset_t readsize(count) -unsigned count; -{ - char buf[MAX_OFFSET_SIZE]; - - if (count == 0) - return 0; - readin(buf, count); - return cntooffset(buf, count); -} - -PRIVATE unsigned segbits(seg, sizedesc) -unsigned seg; -char *sizedesc; -{ - return 3 & ((unsigned) sizedesc[((NSEG - 1) - seg) / 4] >> (2 * (seg % 4))); - /* unsigned to give logical shift */ -} - -PUBLIC unsigned segsizecount(seg, modptr) -unsigned seg; -struct modstruct *modptr; -{ - return convertsize[segbits(seg, modptr->segsizedesc)]; -} diff --git a/bin86-0.3/ld/table.c b/bin86-0.3/ld/table.c deleted file mode 100644 index 557eec6..0000000 --- a/bin86-0.3/ld/table.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * bin86/ld/table.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* table.c - table-handler module for linker */ - -#include "const.h" -#include "align.h" -#include "obj.h" -#include "type.h" -#include "globvar.h" - -#define GOLDEN 157 /* GOLDEN/HASHTABSIZE approx golden ratio */ -#define HASHTABSIZE 256 - -PRIVATE struct symstruct *hashtab[HASHTABSIZE]; /* hash table */ -PRIVATE char *tableptr; /* next free spot in catchall table */ -PRIVATE char *tableend; /* ptr to spot after last in table */ - -FORWARD struct symstruct **gethashptr P((char *name)); - -/* initialise symbol table */ - -PUBLIC void syminit() -{ - unsigned i; - - for (i = sizeof(int) <= 2 ? 0xE000 : (unsigned) 0x38000; - i != 0; i -= 512) - if ((tableptr = malloc(i)) != NULL) - break; - if (tableptr == NULL) - outofmemory(); - tableend = tableptr + i; - for (i = 0; i < HASHTABSIZE; i++) - hashtab[i] = NULL; -} - -/* add named symbol to end of table - initialise only name and next fields */ -/* caller must not duplicate names of externals for findsym() to work */ - -PUBLIC struct symstruct *addsym(name) -char *name; -{ - struct symstruct **hashptr; - struct symstruct *oldsymptr; - struct symstruct *symptr; - - hashptr = gethashptr(name); - symptr = *hashptr; - while (symptr != NULL) - { - oldsymptr = symptr; - symptr = symptr->next; - } - align(tableptr); - symptr = (struct symstruct *) tableptr; - if ((tableptr = symptr->name + (strlen(name) + 1)) > tableend) - outofmemory(); - symptr->modptr = NULL; - symptr->next = NULL; - if (name != symptr->name) - strcpy(symptr->name, name); /* should't happen */ - if (*hashptr == NULL) - *hashptr = symptr; - else - oldsymptr->next = symptr; - return symptr; -} - -/* lookup named symbol */ - -PUBLIC struct symstruct *findsym(name) -char *name; -{ - struct symstruct *symptr; - - symptr = *gethashptr(name); - while (symptr != NULL && (!(symptr->flags & (E_MASK | I_MASK)) || - strcmp(symptr->name, name) != 0)) - symptr = symptr->next; - return symptr; -} - -/* convert name to a hash table ptr */ - -PRIVATE struct symstruct **gethashptr(name) -register char *name; -{ - register unsigned hashval; - - hashval = 0; - while (*name) - hashval = hashval * 2 + *name++; - return hashtab + ((hashval * GOLDEN) & (HASHTABSIZE - 1)); - -/* - -#asm - -GOLDEN EQU 157 -HASHTABSIZE EQU 256 - - CLRB can build value here since HASHTABSIZE <= 256 - LDA ,X - BEQ HASHVAL.EXIT -HASHVAL.LOOP - ADDB ,X+ - LSLB - LDA ,X - BNE HASHVAL.LOOP - RORB - LDA #GOLDEN - MUL -HASHVAL.EXIT -HASHVAL.EXIT - LDX #_hashtab - ABX discard A - same as taking mod HASHTABSIZE - ABX -#endasm - -*/ - -} - -/* move symbol descriptor entries to top of table (no error checking) */ - -PUBLIC char *moveup(nbytes) -unsigned nbytes; -{ - register char *source; - register char *target; - - source = tableptr; - target = tableend; - while (nbytes--) - *--target = *--source; - tableptr = source; - return tableend = target; -} - -/* our version of malloc */ - -PUBLIC char *ourmalloc(nbytes) -unsigned nbytes; -{ - char *allocptr; - - align(tableptr); - allocptr = tableptr; - if ((tableptr += nbytes) > tableend) - outofmemory(); - return allocptr; -} - -/* our version of free (release from bottom of table) */ - -PUBLIC void ourfree(cptr) -char *cptr; -{ - tableptr = cptr; -} - -/* read string from file into table at offset suitable for next symbol */ - -PUBLIC char *readstring() -{ - int c; - char *s; - char *start; - - align(tableptr); - start = s = ((struct symstruct *) tableptr)->name; - while (TRUE) - { - if (s >= tableend) - outofmemory(); - if ((c = readchar()) < 0) - prematureeof(); - if ((*s++ = c) == 0) - return start; - } - /* NOTREACHED */ -} - -/* release from top of table */ - -PUBLIC void release(cptr) -char *cptr; -{ - tableend = cptr; -} - -/* allocate space for string */ - -PUBLIC char *stralloc(s) -char *s; -{ - return strcpy(ourmalloc((unsigned) strlen(s) + 1), s); -} diff --git a/bin86-0.3/ld/type.h b/bin86-0.3/ld/type.h deleted file mode 100644 index d5d9a8d..0000000 --- a/bin86-0.3/ld/type.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * bin86/ld/type.h - * - * Copyright (C) 1992 Bruce Evans - */ - -/* type.h - types for linker */ - -typedef unsigned bool_pt; -typedef unsigned char bool_t; - -typedef unsigned short u2_t; -typedef unsigned u2_pt; -typedef unsigned long u4_t; -typedef unsigned long u4_pt; - -#ifdef OBJ_H /* obj.h is included */ - -/* Prevent the use of offset_t */ -#ifndef offset_t -#define offset_t offset_T -#endif - -typedef unsigned flags_t; /* unsigned makes shifts logical */ - -#ifdef LONG_OFFSETS -typedef unsigned long offset_t; -#else -typedef unsigned offset_t; -#endif - -struct entrylist /* list of entry symbols */ -{ - struct entrylist *elnext; /* next on list */ - struct symstruct *elsymptr; /* entry on list */ -}; - -struct modstruct /* module table entry format */ -{ - char *filename; /* file containing this module */ - char *archentry; /* name of component file for archives */ - char *modname; /* name of module */ - long textoffset; /* offset to module text in file */ - char class; /* class of module */ - char loadflag; /* set if module to be loaded */ - char segmaxsize[NSEG / 4]; /* |SF|SE|..|S0|, 2 bits for seg max size */ - /* 00 = 1, 01 = 2, 10 = 3, 11 = 4 */ - char segsizedesc[NSEG / 4]; /* |SF|SE|..|S0|, 2 bits for #bytes for size */ - /* 00 = 0, 01 = 1, 10 = 2, 11 = 4 */ - struct symstruct **symparray; /* ^array of ptrs to referenced syms */ - struct modstruct *modnext; /* next module in order of initial reading */ - char segsize[1]; /* up to 64 size bytes begin here */ -}; /* careful with sizeof( struct modstruct )!! */ - -struct redlist /* list of redefined (exported) symbols */ -{ - struct redlist *rlnext; /* next on list */ - struct symstruct *rlsymptr; /* to symbol with same name, flags */ - struct modstruct *rlmodptr; /* module for this redefinition */ - offset_t rlvalue; /* value for this redefinition */ -}; - -struct symstruct /* symbol table entry format */ -{ - struct modstruct *modptr; /* module where symbol is defined */ - offset_t value; /* value of symbol */ - flags_t flags; /* see below (unsigned makes shifts logical) */ - struct symstruct *next; /* next symbol with same hash value */ - char name[1]; /* name is any string beginning here */ -}; /* don't use sizeof( struct symstruct )!! */ - -#endif /* obj.h is included */ - -/* prototypes */ - -#if defined(PROTO) || __STDC__ -#define P(x) x -#else -#define P(x) () -#endif - -/* dump.c */ -void dumpmods P((void)); -void dumpsyms P((void)); - -/* io.c */ -void ioinit P((char *progname)); -void closein P((void)); -void closeout P((void)); -void errtrace P((char *name, int level)); -void executable P((void)); -void flusherr P((void)); -void openin P((char *filename)); -void openout P((char *filename)); -void putstr P((char *message)); -#ifdef OBJ_H -void put08x P((offset_t num)); -void put08lx P((offset_t num)); -#endif -void putbstr P((unsigned width, char *str)); -void putbyte P((int ch)); -int readchar P((void)); -void readin P((char *buf, unsigned count)); -bool_pt readineofok P((char *buf, unsigned count)); -void seekin P((long offset)); -void seekout P((long offset)); -void seektrel P((long offset)); -void writechar P((int c)); -void writedrel P((char *buf, unsigned count)); -void writeout P((char *buf, unsigned count)); -void writetrel P((char *buf, unsigned count)); -void fatalerror P((char *message)); -void inputerror P((char *message)); -void input1error P((char *message)); -void outofmemory P((void)); -void prematureeof P((void)); -void redefined P((char *name, char *message, char *archentry, - char *deffilename, char *defarchentry)); -void reserved P((char *name)); -#ifdef OBJ_H -void size_error P((int seg, offset_t count, offset_t size)); -#endif -void undefined P((char *name)); -void usage P((void)); -void use_error P((char *message)); - -/* ld.c */ -int main P((int argc, char **argv)); - -/* readobj.c */ -void objinit P((void)); -void readsyms P((char *filename, bool_pt trace)); -#ifdef OBJ_H -void entrysym P((struct symstruct *symptr)); -offset_t readconvsize P((unsigned countindex)); -offset_t readsize P((unsigned count)); -unsigned segsizecount P((unsigned seg, struct modstruct *modptr)); -#endif - -/* table.c */ -void syminit P((void)); -struct symstruct *addsym P((char *name)); -struct symstruct *findsym P((char *name)); -char *moveup P((unsigned nbytes)); -char *ourmalloc P((unsigned nbytes)); -void ourfree P((char *cptr)); -char *readstring P((void)); -void release P((char *cptr)); -char *stralloc P((char *s)); - -/* typeconvert.c */ -u2_pt c2u2 P((char *buf)); -u4_t c4u4 P((char *buf)); -u2_pt cnu2 P((char *buf, unsigned count)); -u4_t cnu4 P((char *buf, unsigned count)); -void u2c2 P((char *buf, u2_pt offset)); -void u4c4 P((char *buf, u4_t offset)); -void u2cn P((char *buf, u2_pt offset, unsigned count)); -void u4cn P((char *buf, u4_t offset, unsigned count)); -bool_pt typeconv_init P((bool_pt big_endian, bool_pt long_big_endian)); - -/* writebin.c */ -void writebin P((char *outfilename, bool_pt argsepid, bool_pt argbits32, - bool_pt argstripflag, bool_pt arguzp)); -void linksyms P((bool_pt argreloc_output)); - -/* Make offset_t safe for the standard includes */ -#undef offset_t - -/* library - fcntl.h */ -#undef NULL -#include <fcntl.h> -/* -int creat P((const char *_path, int _mode)); -int open P((const char *_path, int _oflag, ...)); -*/ - -/* library - sys/stat.h */ -#include <sys/stat.h> -#ifdef MY_STAT_H -int chmod P((const char *_path, mode_t _mode)); -int fstat P((int _fd, struct stat *_statbuf)); -mode_t umask P((mode_t _oldmask)); - /* it should be mode_t but it's hard to - * decide which systems define it, and where */ -#endif - -/* library - stdlib.h */ -#include <stdlib.h> -/* -void exit P((int _status)); -void *malloc P((unsigned _nbytes)); -unsigned long strtoul P((const char *_nptr, char **_endptr, int _base)); -*/ - -/* library - string.h */ -#include <string.h> -/* -void *memset P((void *_s, int _c, unsigned _nbytes)); -char *strcat P((char *_target, const char *_source)); -char *strchr P((const char *_s, int _ch)); -int strcmp P((const char *_s1, const char *_s2)); -char *strcpy P((char *_target, const char *_source)); -unsigned strlen P((const char *_s)); -char *strncat P((char *_target, const char *_source, unsigned _maxlength)); -int strncmp P((const char *_s1, const char *_s2, unsigned _nbytes)); -char *strncpy P((char *_target, const char *_source, unsigned _maxlength)); -char *strrchr P((const char *_s, int _ch)); -*/ - -/* library - unistd.h */ -#include <unistd.h> -/* -int access P((char *_path, int _amode)); -int close P((int _fd)); -long lseek P((int _fd, long _offset, int _whence)); -int read P((int _fd, char *_buf, unsigned _nbytes)); -int write P((int _fd, char *_buf, unsigned _nbytes)); -*/ - -#ifdef OBJ_H /* obj.h is included */ - -/* Prevent the use of offset_t */ -#ifndef offset_t -#define offset_t offset_T -#endif - -#endif diff --git a/bin86-0.3/ld/typeconv.c b/bin86-0.3/ld/typeconv.c deleted file mode 100644 index 1465106..0000000 --- a/bin86-0.3/ld/typeconv.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * bin86/ld/typeconv.c - * - * Copyright (C) 1992 Bruce Evans - */ - -/* typeconv.c - convert between char arrays and unsigneds */ - -/* - c2u2(): 2 byte array to 2 byte unsigned - c4u4(): 4 byte array to 4 byte unsigned - cnu2(): n byte array to 2 byte unsigned - cnu4(): n byte array to 4 byte unsigned - u2c2(): 2 byte unsigned to 2 byte array - u2cn(): 2 byte unsigned to n byte array - u4c4(): 4 byte unsigned to 4 byte array - u4cn(): 4 byte unsigned to n byte array - typeconv_init: (re)initialise for given byte order. - Default is no swapping, but the initialisation should be done - anyway to provide some validity checks (returns FALSE if error). - - Not provided: - c2u4(), c4u2(), u2c4(), u4c2(). - Each of these is best done by truncating or extending a return value - or argument to the appropiate fixed-count function. - c4u2() has too many cases to do in-line conveniently, and the others - are hardly more efficient when done in-line. - - 4 byte orderings for both char arrays and unsigneds are supported: - 0123 - little-endian - 3210 - big-endian - 2301 - little-endian with long words big-endian (pdp11) - 1032 - big-endian with long words little_endian (who knows?) - - The unsigned's byte order is that of the machine on which these - routines are running. - It is determined at run time initialisation since the compiler/ - preprocessor is too dumb to tell us at compile time. -*/ - -#include "const.h" -#include "type.h" -#include "globvar.h" - -FORWARD u2_pt c2u2_00 P((char *buf)); -FORWARD u4_pt c4u4_00 P((char *buf)); -FORWARD u2_pt c2u2_ss P((char *buf)); -FORWARD u4_pt c4u4_ss P((char *buf)); -FORWARD u4_pt c4u4_s0 P((char *buf)); -FORWARD u4_pt c4u4_0s P((char *buf)); -FORWARD void u2c2_00 P((char *buf, u2_pt offset)); -FORWARD void u4c4_00 P((char *buf, u4_t offset)); -FORWARD void u2c2_ss P((char *buf, u2_pt offset)); -FORWARD void u4c4_ss P((char *buf, u4_t offset)); -FORWARD void u4c4_s0 P((char *buf, u4_t offset)); -FORWARD void u4c4_0s P((char *buf, u4_t offset)); - -PRIVATE u2_pt (*pc2u2) P((char *buf)) = c2u2_00; -PRIVATE u4_pt (*pc4u4) P((char *buf)) = c4u4_00; -PRIVATE void (*pu2c2) P((char *buf, u2_pt offset)) = u2c2_00; -PRIVATE void (*pu4c4) P((char *buf, u4_t offset)) = u4c4_00; - -/* === char arrays to unsigneds === */ - -/* no bytes swapped, longwinded to avoid alignment problems */ - -PRIVATE u2_pt c2u2_00(buf) -register char *buf; -{ - u2_t offset; - - ((char *) &offset)[0] = buf[0]; - ((char *) &offset)[1] = buf[1]; - return offset; -} - -PRIVATE u4_pt c4u4_00(buf) -register char *buf; -{ - u4_t offset; - - ((char *) &offset)[0] = buf[0]; - ((char *) &offset)[1] = buf[1]; - ((char *) &offset)[2] = buf[2]; - ((char *) &offset)[3] = buf[3]; - return offset; -} - -/* straight swapping for little-endian to big-endian and vice versa */ - -PRIVATE u2_pt c2u2_ss(buf) -register char *buf; -{ - u2_t offset; - - ((char *) &offset)[0] = buf[1]; - ((char *) &offset)[1] = buf[0]; - return offset; -} - -PRIVATE u4_pt c4u4_ss(buf) -register char *buf; -{ - u4_t offset; - - ((char *) &offset)[0] = buf[3]; - ((char *) &offset)[1] = buf[2]; - ((char *) &offset)[2] = buf[1]; - ((char *) &offset)[3] = buf[0]; - return offset; -} - -/* wierd swapping for different-endian u2's, same-endian u4's */ - -PRIVATE u4_pt c4u4_s0(buf) -register char *buf; -{ - u4_t offset; - - ((char *) &offset)[0] = buf[1]; - ((char *) &offset)[1] = buf[0]; - ((char *) &offset)[2] = buf[3]; - ((char *) &offset)[3] = buf[2]; - return offset; -} - -/* very wierd swapping for same-endian u2's, different-endian u4's */ - -PRIVATE u4_pt c4u4_0s(buf) -register char *buf; -{ - u4_t offset; - - ((char *) &offset)[0] = buf[2]; - ((char *) &offset)[1] = buf[3]; - ((char *) &offset)[2] = buf[0]; - ((char *) &offset)[3] = buf[1]; - return offset; -} - -/* === entry points === */ - -PUBLIC u2_pt c2u2(buf) -char *buf; -{ - return (*pc2u2) (buf); -} - -PUBLIC u4_t c4u4(buf) -char *buf; -{ - return (*pc4u4) (buf); -} - -PUBLIC u2_pt cnu2(buf, count) -char *buf; -unsigned count; -{ - switch (count) - { - case 1: - return buf[0] & 0xFF; - case 2: - return (*pc2u2) (buf); - case 4: - return (u2_pt) (*pc4u4) (buf); - default: - return 0; - } -} - -PUBLIC u4_t cnu4(buf, count) -char *buf; -unsigned count; -{ - switch (count) - { - case 1: - return buf[0] & 0xFF; - case 2: - return (*pc2u2) (buf); - case 4: - return (*pc4u4) (buf); - default: - return 0; - } -} - -/* === unsigneds to char arrays === */ - -/* no bytes swapped, longwinded to avoid alignment problems */ - -PRIVATE void u2c2_00(buf, offset) -register char *buf; -u2_pt offset; -{ - - buf[0] = ((char *) &offset)[0]; - buf[1] = ((char *) &offset)[1]; -} - -PRIVATE void u4c4_00(buf, offset) -register char *buf; -u4_t offset; -{ - buf[0] = ((char *) &offset)[0]; - buf[1] = ((char *) &offset)[1]; - buf[2] = ((char *) &offset)[2]; - buf[3] = ((char *) &offset)[3]; -} - -/* straight swapping for little-endian to big-endian and vice versa */ - -PRIVATE void u2c2_ss(buf, offset) -register char *buf; -u2_pt offset; -{ - u2_t offset2; - - offset2 = offset; - buf[0] = ((char *) &offset2)[1]; - buf[1] = ((char *) &offset2)[0]; -} - -PRIVATE void u4c4_ss(buf, offset) -register char *buf; -u4_t offset; -{ - buf[0] = ((char *) &offset)[3]; - buf[1] = ((char *) &offset)[2]; - buf[2] = ((char *) &offset)[1]; - buf[3] = ((char *) &offset)[0]; -} - -/* wierd swapping for different-endian u2's, same-endian u4's */ - -PRIVATE void u4c4_s0(buf, offset) -register char *buf; -u4_t offset; -{ - buf[0] = ((char *) &offset)[1]; - buf[1] = ((char *) &offset)[0]; - buf[2] = ((char *) &offset)[3]; - buf[3] = ((char *) &offset)[2]; -} - -/* very wierd swapping for same-endian u2's, different-endian u4's */ - -PRIVATE void u4c4_0s(buf, offset) -register char *buf; -u4_t offset; -{ - buf[0] = ((char *) &offset)[2]; - buf[1] = ((char *) &offset)[3]; - buf[2] = ((char *) &offset)[0]; - buf[3] = ((char *) &offset)[1]; -} - -/* === entry points === */ - -PUBLIC void u2c2(buf, offset) -register char *buf; -u2_pt offset; -{ - (*pu2c2) (buf, offset); -} - -PUBLIC void u4c4(buf, offset) -register char *buf; -u4_t offset; -{ - (*pu4c4) (buf, offset); -} - -PUBLIC void u2cn(buf, offset, count) -register char *buf; -u2_pt offset; -unsigned count; -{ - switch (count) - { - case 1: - buf[0] = (char) offset; - return; - case 2: - (*pu2c2) (buf, offset); - return; - case 4: - (*pu4c4) (buf, (u4_t) offset); - return; - } -} - -PUBLIC void u4cn(buf, offset, count) -register char *buf; -u4_t offset; -unsigned count; -{ - switch (count) - { - case 1: - buf[0] = (char) offset; - return; - case 2: - (*pu2c2) (buf, (u2_pt) (u2_t) offset); - return; - case 4: - (*pu4c4) (buf, offset); - return; - } -} - -/* initialise type conversion, return FALSE if it cannot be handled */ - -PUBLIC bool_pt typeconv_init(big_endian, long_big_endian) -bool_pt big_endian; -bool_pt long_big_endian; -{ - u2_pt conv2; - u4_pt conv4; - char *conv2ptr; - char *conv4ptr; - - if (sizeof(u2_t) != 2 || sizeof(u4_t) != 4) - /* dumb preprocessor's don't accept sizeof in #if expressions */ - return FALSE; - - if (big_endian) - { - conv2ptr = (conv4ptr = "\1\2\3\4") + 2; - if (!long_big_endian) - conv4ptr = "\3\4\1\2"; - } - else - { - conv2ptr = conv4ptr = "\4\3\2\1"; - if (long_big_endian) - conv4ptr = "\2\1\4\3"; - } - conv2 = c2u2_00(conv2ptr); - conv4 = c4u4_00(conv4ptr); - if (conv2 == 0x0304) - { - pc2u2 = c2u2_00; - pc4u4 = c4u4_00; - pu2c2 = u2c2_00; - pu4c4 = u4c4_00; - if (conv4 == 0x03040102L) - { - pc4u4 = c4u4_0s; - pu4c4 = u4c4_0s; - } - else if (conv4 != 0x01020304L) - return FALSE; - } - else if (conv2 == 0x0403) - { - pc2u2 = c2u2_ss; - pc4u4 = c4u4_ss; - pu2c2 = u2c2_ss; - pu4c4 = u4c4_ss; - if (conv4 == 0x02010403L) - { - pc4u4 = c4u4_s0; - pu4c4 = u4c4_s0; - } - else if (conv4 != 0x04030201L) - return FALSE; - } - else - return FALSE; - return TRUE; -} - -#ifdef DEBUG_TYPECONV - -main(int argc,char **argv) -{ - char *source; - char target[4]; - u2_t u2; - u2_t u2a; - u4_t u4; - u4_t u4a; - - printf("%u\n", typeconv_init(FALSE, FALSE)); - printf("%u\n", typeconv_init(FALSE, TRUE)); - printf("%u\n", typeconv_init(TRUE, FALSE)); - printf("%u\n", typeconv_init(TRUE, TRUE)); - - typeconv_init(FALSE, FALSE); - source = "\4\3\2\1"; - - target[0] = 0; - target[1] = 0; - u2 = cnu2(source, 2); - u2cn(target, u2, 2); - if (strncmp(source, target, 2)) - printf("oops9\n"); - - target[0] = 0; - target[1] = 0; - u4a = cnu4(source, 2); - u4cn(target, u4a, 2); - if (strncmp(source, target, 2)) - printf("oops10\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u2a = cnu2(source, 4); - u2cn(target, u2a, 4); - if (strncmp(target, "\4\3\0\0", 4)) - printf("oops11\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u4 = cnu4(source, 4); - u4cn(target, u4, 4); - if (strncmp(source, target, 4)) - printf("oops12\n"); - - printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a); - - typeconv_init(FALSE, TRUE); - source = "\2\1\4\3"; - - target[0] = 0; - target[1] = 0; - u2 = cnu2(source + 2, 2); - u2cn(target, u2, 2); - if (strncmp(source + 2, target, 2)) - printf("oops13\n"); - - target[0] = 0; - target[1] = 0; - u4a = cnu4(source + 2, 2); - u4cn(target, u4a, 2); - if (strncmp(source + 2, target, 2)) - printf("oops14\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u2a = cnu2(source, 4); - u2cn(target, u2a, 4); - if (strncmp(target, "\0\0\4\3", 4)) - printf("oops15\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u4 = cnu4(source, 4); - u4cn(target, u4, 4); - if (strncmp(source, target, 4)) - printf("oops16\n"); - - printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a); - - typeconv_init(TRUE, FALSE); - source = "\3\4\1\2"; - - target[0] = 0; - target[1] = 0; - u2 = cnu2(source, 2); - u2cn(target, u2, 2); - if (strncmp(source, target, 2)) - printf("oops5\n"); - - target[0] = 0; - target[1] = 0; - u4a = cnu4(source, 2); - u4cn(target, u4a, 2); - if (strncmp(source, target, 2)) - printf("oops6\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u2a = cnu2(source, 4); - u2cn(target, u2a, 4); - if (strncmp(target, "\3\4\0\0", 4)) - printf("oops7\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u4 = cnu4(source, 4); - u4cn(target, u4, 4); - if (strncmp(source, target, 4)) - printf("oops8\n"); - - printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a); - - typeconv_init(TRUE, TRUE); - source = "\1\2\3\4"; - - target[0] = 0; - target[1] = 0; - u2 = cnu2(source + 2, 2); - u2cn(target, u2, 2); - if (strncmp(source + 2, target, 2)) - printf("oops1\n"); - - target[0] = 0; - target[1] = 0; - u4a = cnu4(source + 2, 2); - u4cn(target, u4a, 2); - if (strncmp(source + 2, target, 2)) - printf("oops2\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u2a = cnu2(source, 4); - u2cn(target, u2a, 4); - if (strncmp(target, "\0\0\3\4", 4)) - printf("oops3\n"); - - target[0] = 0; - target[1] = 0; - target[2] = 0; - target[3] = 0; - u4 = cnu4(source, 4); - u4cn(target, u4, 4); - if (strncmp(source, target, 4)) - printf("oops4\n"); - - printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a); -} - -#endif /* DEBUG_TYPECONV */ diff --git a/bin86-0.3/ld/writebin.c b/bin86-0.3/ld/writebin.c deleted file mode 100644 index 56b329d..0000000 --- a/bin86-0.3/ld/writebin.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * bin86/ld/writebin.c - * - * Copyright (C) 1992 Bruce Evans - */ - -extern long text_base_address; -#define btextoffset text_base_address -static long bdataoffset; -#define page_size() 4096 - -/* writebin.c - write binary file for linker */ - -#ifdef A_OUT_H -# include A_OUT_H -#else -# ifdef BSD_A_OUT -# include "bsd-a.out.h" -# define A_MINHDR 0 -# define C_EXT N_EXT -# define C_STAT 0 -# define n_was_name n_un.n_name -# define n_was_numaux n_other -# define n_was_other n_numaux -# define n_was_sclass n_type -# define n_was_strx n_un.n_strx -# define n_was_type n_desc -# else /* not BSD_A_OUT */ -# include "a.out.h" /* maybe local copy of <a.out.h> for X-link */ -# define n_was_name n_name -# define n_was_numaux n_numaux -# define n_was_other n_other -# define n_was_sclass n_sclass -# define n_was_strx n_value -# define n_was_type n_type -# endif /* BSD_A_OUT */ -#endif - -#include "const.h" -#include "obj.h" -#include "type.h" -#undef EXTERN -#include "globvar.h" - -#ifdef EDOS -# define FILEHEADERLENGTH 0 -#endif -#ifdef MINIX -# ifdef BSD_A_OUT -# define FILEHEADERLENGTH sizeof (struct exec) -# else -# define FILEHEADERLENGTH A_MINHDR - /* part of header not counted in offsets */ -# endif -#endif -#define DPSEG 2 - -#define CM_MASK 0xC0 -#define MODIFY_MASK 0x3F -#define S_MASK 0x04 -#define OF_MASK 0x03 - -#define CM_SPECIAL 0 -#define CM_ABSOLUTE 0x40 -#define CM_OFFSET_RELOC 0x80 -#define CM_SYMBOL_RELOC 0xC0 - -#define CM_EOT 0 -#define CM_BYTE_SIZE 1 -#define CM_WORD_SIZE 2 -#define CM_LONG_SIZE 3 -#define CM_1_SKIP 17 -#define CM_2_SKIP 18 -#define CM_4_SKIP 19 -#define CM_0_SEG 32 - -#define ABS_TEXT_MAX 64 - -#define offsetof(struc, mem) ((int) &((struc *) 0)->mem) -#define memsizeof(struc, mem) sizeof(((struc *) 0)->mem) - -PRIVATE bool_t bits32; /* nonzero for 32-bit executable */ -PRIVATE offset_t combase[NSEG]; /* bases of common parts of segments */ -PRIVATE offset_t comsz[NSEG]; /* sizes of common parts of segments */ -PRIVATE char curseg; /* current segment, 0 to $F */ -PRIVATE offset_t edataoffset; /* end of data */ -PRIVATE offset_t endoffset; /* end of bss */ -PRIVATE offset_t etextoffset; /* end of text */ -PRIVATE offset_t etextpadoff; /* end of padded text */ -#ifdef BSD_A_OUT -PRIVATE unsigned ndreloc; /* number of data relocations */ -#endif -PRIVATE unsigned nsym; /* number of symbols written */ -#ifdef BSD_A_OUT -PRIVATE unsigned ntreloc; /* number of text relocations */ -PRIVATE bool_t reloc_output; /* nonzero to leave reloc info in output */ -#endif -PRIVATE unsigned relocsize; /* current relocation size 1, 2 or 4 */ -PRIVATE offset_t segadj[NSEG]; /* adjusts (file offset - seg offset) */ - /* depends on zero init */ -PRIVATE offset_t segbase[NSEG]; /* bases of data parts of segments */ -PRIVATE char segboundary[9] = "__seg0DH"; - /* name of seg boundary __seg0DL to __segfCH */ -PRIVATE offset_t segpos[NSEG]; /* segment positions for current module */ -PRIVATE offset_t segsz[NSEG]; /* sizes of data parts of segments */ - /* depends on zero init */ -PRIVATE bool_t sepid; /* nonzero for separate I & D */ -PRIVATE bool_t stripflag; /* nonzero to strip symbols */ -PRIVATE offset_t spos; /* position in current seg */ -PRIVATE bool_t uzp; /* nonzero for unmapped zero page */ - -#ifdef EDOS -FORWARD unsigned binheaderlength P((char *commandname)); -FORWARD char *idconvert P((struct entrylist *elptr, char *commandname)); -#endif -FORWARD void linkmod P((struct modstruct *modptr)); -FORWARD void linkrefs P((struct modstruct *modptr)); -FORWARD void padmod P((struct modstruct *modptr)); -FORWARD void setsym P((char *name, offset_t value)); -FORWARD void symres P((char *name)); -FORWARD void setseg P((unsigned newseg)); -FORWARD void skip P((unsigned countsize)); -#ifdef EDOS -FORWARD void writeheader P((char *commandname)); -#else -FORWARD void writeheader P((void)); -#endif -FORWARD void writenulls P((offset_t count)); - -/* link all symbols connected to entry symbols */ - -PUBLIC void linksyms(argreloc_output) -bool_pt argreloc_output; -{ - char needlink; - struct entrylist *elptr; - struct modstruct *modptr; - struct symstruct *symptr; - -#ifdef BSD_A_OUT - reloc_output = argreloc_output; - if (argreloc_output) - { - if (modfirst->modnext != NULL) - fatalerror("relocatable output only works for one input file"); - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - modptr->loadflag = TRUE; - return; - } -#endif - if ((symptr = findsym("_main")) != NULL) - entrysym(symptr); - do - { - if ((elptr = entryfirst) == NULL) - fatalerror("no start symbol"); - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - modptr->loadflag = FALSE; - for (; elptr != NULL; elptr = elptr->elnext) - linkrefs(elptr->elsymptr->modptr); - if ((symptr = findsym("start")) != NULL || - (symptr = findsym("crtso")) != NULL) - linkrefs(symptr->modptr); - needlink = FALSE; - { - struct redlist *prlptr; - struct redlist *rlptr; - - for (rlptr = redfirst; rlptr != NULL; - rlptr = (prlptr = rlptr)->rlnext) - if (rlptr->rlmodptr->loadflag && - rlptr->rlmodptr->class > rlptr->rlsymptr->modptr->class) - { - rlptr->rlsymptr->modptr = rlptr->rlmodptr; - rlptr->rlsymptr->value = rlptr->rlvalue; - if (rlptr == redfirst) - redfirst = rlptr->rlnext; - else - prlptr->rlnext = rlptr->rlnext; - needlink = TRUE; - } - } - } - while (needlink); -} - -/* write binary file */ - -PUBLIC void writebin(outfilename, argsepid, argbits32, argstripflag, arguzp) -char *outfilename; -bool_pt argsepid; -bool_pt argbits32; -bool_pt argstripflag; -bool_pt arguzp; -{ - char buf4[4]; -#ifdef EDOS - char *commandname; -#endif - char *cptr; - struct nlist extsym; - flags_t flags; - struct modstruct *modptr; - char seg; - unsigned sizecount; - offset_t tempoffset; - struct symstruct *symptr; - - sepid = argsepid; - bits32 = argbits32; - stripflag = argstripflag; -#ifdef BSD_A_OUT - uzp = arguzp && !reloc_output; -#else - uzp = arguzp; -#endif - if (uzp) - { - if (btextoffset == 0) - btextoffset = page_size(); - if (bdataoffset == 0 && sepid) - bdataoffset = page_size(); - } -#ifdef EDOS - commandname = stralloc(outfilename); - if ((cptr = strchr(commandname, ':')) != NULL) - commandname = cptr + 1; - if ((cptr = strrchr(commandname, '.')) != NULL) - *cptr = 0; -#endif - - /* reserve special symbols use curseg to pass parameter to symres() */ - for (curseg = 0; curseg < NSEG; ++curseg) - { - segboundary[5] = hexdigit[curseg]; /* to __segX?H */ - segboundary[6] = 'D'; - symres(segboundary); /* __segXDH */ - segboundary[7] = 'L'; - symres(segboundary); /* __segXDL */ - segboundary[6] = 'C'; - symres(segboundary); /* __segXCL */ - segboundary[7] = 'H'; - symres(segboundary); /* __segXCH */ - } -#ifdef EDOS - curseg = 0; /* data seg, s.b. variable */ -#else - curseg = 3; -#endif - symres("__edata"); - symres("__end"); - curseg = 0; /* text seg, s.b. variable */ - symres("__etext"); - - /* calculate segment and common sizes (sum over loaded modules) */ - /* use zero init of segsz[] */ - /* also relocate symbols relative to starts of their segments */ - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - if (modptr->loadflag) - { - register struct symstruct **symparray; - register struct symstruct *symptr; - - for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) - if (symptr->modptr == modptr && !(symptr->flags & A_MASK)) - { - if (!(symptr->flags & (I_MASK | SA_MASK))) - { - /* relocate by offset of module in segment later */ - /* relocate by offset of segment in memory special */ - /* symbols get relocated improperly */ - symptr->value += segsz[symptr->flags & SEGM_MASK]; - } - else if (symptr->value == 0) - { -#ifdef BSD_A_OUT - if (!reloc_output) -#endif - undefined(symptr->name); - } - else - { -#ifdef BSD_A_OUT -#if 0 - if (!reloc_output) -#else - if (!reloc_output || !(symptr->flags & I_MASK)) -#endif -#endif - { - tempoffset = ld_roundup(symptr->value, 4, offset_t); - /* temp kludge quad alignment for 386 */ - symptr->value = comsz[seg = symptr->flags & SEGM_MASK]; - comsz[seg] += tempoffset; - } - if (!(symptr->flags & SA_MASK)) - symptr->flags |= C_MASK; - } - } - for (seg = 0, cptr = modptr->segsize; seg < NSEG; ++seg) - { - segsz[seg] += cntooffset(cptr, - sizecount = segsizecount((unsigned) seg, modptr)); -#ifndef EDOS - - /* adjust sizes to even to get quad boundaries */ - /* this should be specifiable dynamically */ - segsz[seg] = ld_roundup(segsz[seg], 4, offset_t); - comsz[seg] = ld_roundup(comsz[seg], 4, offset_t); -#endif - cptr += sizecount; - } - } - - /* 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 EDOS - if (btextoffset == 0) - btextoffset = binheaderlength(commandname); -#endif - segpos[0] = segbase[0] = spos = btextoffset; - combase[0] = segbase[0] + segsz[0]; - segadj[1] = segadj[0] = -btextoffset; - etextpadoff = etextoffset = combase[0] + comsz[0]; - if (sepid) - { - etextpadoff = ld_roundup(etextoffset, 0x10, offset_t); - segadj[1] += etextpadoff - bdataoffset; - } - else if (bdataoffset == 0) - bdataoffset = etextpadoff; - segpos[1] = segbase[1] = edataoffset = bdataoffset; - combase[1] = segbase[1] + segsz[1]; - for (seg = 2; seg < NSEG; ++seg) - { - segpos[seg] = segbase[seg] = combase[seg - 1] + comsz[seg - 1]; - if (seg == DPSEG) - { - /* temporarily have fixed DP seg */ - /* adjust if nec so it only spans 1 page */ - tempoffset = segsz[seg] + comsz[seg]; - if (tempoffset > 0x100) - fatalerror("direct page segment too large"); - if ((((segbase[seg] + tempoffset) ^ segbase[seg]) & ~0xFF) != 0) - segpos[seg] = segbase[seg] = (segbase[seg] + 0xFF) & ~0xFF; - } - combase[seg] = segbase[seg] + segsz[seg]; - segadj[seg] = segadj[seg - 1]; - } - - /* relocate symbols by offsets of segments in memory */ - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - if (modptr->loadflag) - { - register struct symstruct **symparray; - register struct symstruct *symptr; - - for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) - if (symptr->modptr == modptr && !(symptr->flags & A_MASK)) - { - if (symptr->flags & (C_MASK | SA_MASK)) - { -#ifdef BSD_A_OUT -#if 0 - if (!reloc_output) -#else - if (!reloc_output || !(symptr->flags & I_MASK)) -#endif -#endif - symptr->value += combase[symptr->flags & SEGM_MASK]; - } - else -#ifdef BSD_A_OUT - if (!reloc_output || !(symptr->flags & I_MASK)) -#endif - symptr->value += segbase[symptr->flags & SEGM_MASK]; - } - } - - /* adjust special symbols */ - for (seg = 0; seg < NSEG; ++seg) - { - if (segsz[seg] != 0) - /* only count data of nonzero length */ - edataoffset = segbase[seg] + segsz[seg]; - segboundary[5] = hexdigit[seg]; /* to __segX?H */ - segboundary[6] = 'D'; - setsym(segboundary, (tempoffset = segbase[seg]) + segsz[seg]); - /* __segXDH */ - segboundary[7] = 'L'; - setsym(segboundary, tempoffset); /* __segXDL */ - segboundary[6] = 'C'; - setsym(segboundary, tempoffset = combase[seg]); - /* __segXCL */ - segboundary[7] = 'H'; - setsym(segboundary, tempoffset + comsz[seg]); - /* __segXCH */ - } - setsym("__etext", etextoffset); - setsym("__edata", edataoffset); - setsym("__end", endoffset = combase[NSEG - 1] + comsz[NSEG - 1]); - - openout(outfilename); -#ifdef BSD_A_OUT - if (reloc_output) - seektrel(FILEHEADERLENGTH - + (long) (etextpadoff - btextoffset) - + (long) (edataoffset - bdataoffset)); -#endif -#ifdef EDOS - writeheader(commandname); -#else - writeheader(); -#endif - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - if (modptr->loadflag) - { - linkmod(modptr); - padmod(modptr); - } - - /* dump symbol table */ -#ifdef MINIX - if (!stripflag) - { -#ifdef BSD_A_OUT - unsigned stringoff; -#endif - - seekout(FILEHEADERLENGTH - + (long) (etextpadoff - btextoffset) - + (long) (edataoffset - bdataoffset) -#ifdef BSD_A_OUT - + ((long) ndreloc + ntreloc) - * (long) sizeof(struct relocation_info) -#endif - ); - extsym.n_was_numaux = extsym.n_was_type = 0; -#ifdef BSD_A_OUT - stringoff = 4; -#endif - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - if (modptr->loadflag) - { - register struct symstruct **symparray; - register struct symstruct *symptr; - - for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) - if (symptr->modptr == modptr) - { -#ifdef BSD_A_OUT - offtocn((char *) &extsym.n_was_strx, - (offset_t) stringoff, 4); -#else - strncpy((char *) &extsym.n_was_name, symptr->name, - sizeof extsym.n_was_name); -#endif - u4cn((char *) &extsym.n_value, (u4_t) symptr->value, - sizeof extsym.n_value); - if ((flags = symptr->flags) & A_MASK) - extsym.n_was_sclass = N_ABS; - else if (flags & (E_MASK | I_MASK)) - extsym.n_was_sclass = C_EXT; - else - extsym.n_was_sclass = C_STAT; - if (!(flags & I_MASK) || -#ifdef BSD_A_OUT - !reloc_output && -#endif - flags & C_MASK) - switch (flags & (A_MASK | SEGM_MASK)) - { - case 0: - extsym.n_was_sclass |= N_TEXT; - case A_MASK: - break; - default: - if (flags & (C_MASK | SA_MASK)) - extsym.n_was_sclass |= N_BSS; - else - extsym.n_was_sclass |= N_DATA; - break; - } - writeout((char *) &extsym, sizeof extsym); - ++nsym; -#ifdef BSD_A_OUT - stringoff += strlen(symptr->name) + 1; -#endif - } - } -#ifdef BSD_A_OUT - offtocn((char *) &extsym.n_was_strx, (offset_t) stringoff, 4); - writeout((char *) &extsym.n_was_strx, 4); - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) - if (modptr->loadflag) - { - register struct symstruct **symparray; - register struct symstruct *symptr; - - for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) - if (symptr->modptr == modptr) - writeout(symptr->name, strlen(symptr->name) + 1); - } -#endif - seekout((long) offsetof(struct exec, a_syms)); - u4cn(buf4, (u4_t) nsym * sizeof extsym, - memsizeof(struct exec, a_syms)); - writeout(buf4, memsizeof(struct exec, a_syms)); -#if defined (BSD_A_OUT) && !defined(__linux__) - seekout((long) offsetof(struct exec, a_trsize)); - u4cn(buf4, (u4_t) ntreloc * sizeof(struct relocation_info), - memsizeof(struct exec, a_trsize)); - writeout(buf4, memsizeof(struct exec, a_trsize)); - seekout((long) offsetof(struct exec, a_drsize)); - u4cn(buf4, (u4_t) ndreloc * sizeof(struct relocation_info), - memsizeof(struct exec, a_drsize)); - writeout(buf4, memsizeof(struct exec, a_drsize)); -#endif - } -#endif /* MINIX */ - closeout(); -#ifdef BSD_A_OUT - if (!reloc_output) -#endif - executable(); -} - -#ifdef EDOS - -PRIVATE unsigned binheaderlength(commandname) -char *commandname; -{ - unsigned count; - char *name; - struct entrylist *elptr; - struct symstruct *startptr; - - count = 2 + 2 + 1; /* len len nul */ - startptr = findsym("start"); - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) - { - name = idconvert(elptr, commandname); - count += strlen(name) + 1 + 2 + 1; /* nul off flg */ - ourfree(name); - if (startptr != NULL) - count += 6; /* LBSR $xxxx and LBRA $xxxx */ - } - return count; -} - -/* convert name of symbol (entry) list element to a Basic identifier */ -/* new name is built in storage obtained from stralloc() */ -/* the special name _main is converted to the command name first */ -/* copy upper case and numerals, convert lower case to upper, ignore rest */ - -PRIVATE char *idconvert(elptr, commandname) -struct entrylist *elptr; -char *commandname; -{ - char *name; - char *newname; - - if (strcmp(name = elptr->elsymptr->name, "_main") == 0) - name = commandname; - newname = stralloc(name); - { - register char *t; - register char *s; - - t = newname; - s = name; - do - { - if (*s >= '0' && *s <= '9' || *s >= 'A' && *s <= 'Z') - *t++ = *s; - if (*s >= 'a' && *s <= 'z') - *t++ = *s + ('A' - 'a'); - } - while (*s++); - *t = 0; - } - if (*newname < 'A') /* numeral or null */ - fatalerror("bad entry name"); - return newname; -} - -#endif /* EDOS */ - -PRIVATE void linkmod(modptr) -struct modstruct *modptr; -{ - char buf[ABS_TEXT_MAX]; - int command; - unsigned char modify; - offset_t offset; - int symbolnum; - struct symstruct **symparray; - struct symstruct *symptr; - - setseg(0); - relocsize = 2; - symparray = modptr->symparray; - openin(modptr->filename); /* does nothing if already open */ - seekin((long) modptr->textoffset); - while (TRUE) - { - if ((command = readchar()) < 0) - prematureeof(); - modify = command & MODIFY_MASK; - switch (command & CM_MASK) - { - case CM_SPECIAL: - switch (modify) - { - case CM_EOT: - segpos[curseg] = spos; - return; - case CM_BYTE_SIZE: - relocsize = 1; - break; - case CM_WORD_SIZE: - relocsize = 2; - break; - case CM_LONG_SIZE: -#ifdef LONG_OFFSETS - relocsize = 4; - break; -#else - fatalerror("relocation by long offsets not implemented"); -#endif - case CM_1_SKIP: - skip(1); - break; - case CM_2_SKIP: - skip(2); - break; - case CM_4_SKIP: - skip(4); - break; - default: - if ((modify -= CM_0_SEG) >= NSEG) - inputerror("bad data in"); - setseg((unsigned) modify); - break; - } - break; - case CM_ABSOLUTE: - if (modify == 0) - modify = ABS_TEXT_MAX; - readin(buf, (unsigned) modify); - writeout(buf, (unsigned) modify); - spos += (int) modify; - break; - case CM_OFFSET_RELOC: - offset = readsize(relocsize); - if (modify & R_MASK) - offset -= (spos + relocsize); - offtocn(buf, segbase[modify & SEGM_MASK] + offset, relocsize); - writeout(buf, relocsize); -#ifdef BSD_A_OUT - if (reloc_output) - { - u4_t bitfield; - - if (curseg == 0) - { - ++ntreloc; - offtocn(buf, spos, 4); - writetrel(buf, 4); - } - else - { - ++ndreloc; - offtocn(buf, spos - segbase[1], 4); - writedrel(buf, 4); - } - if ((modify & SEGM_MASK) == 0) - bitfield = N_TEXT; - else - bitfield = N_DATA; - if (modify & R_MASK) - bitfield |= 1L << 24; - if (relocsize == 2) - bitfield |= 1L << 25; - else if (relocsize == 4) - bitfield |= 1L << 26; - u4cn(buf, bitfield, 4); - if (curseg == 0) - writetrel(buf, 4); - else - writedrel(buf, 4); - } -#endif /* BSD_A_OUT */ - spos += relocsize; - break; - case CM_SYMBOL_RELOC: - symptr = symparray[symbolnum = readconvsize((unsigned) - (modify & S_MASK ? 2 : 1))]; - offset = readconvsize((unsigned) modify & OF_MASK); - if (modify & R_MASK) - offset -= (spos + relocsize); -#ifdef BSD_A_OUT - if (!reloc_output || !(symptr->flags & I_MASK)) -#endif - offset += symptr->value; - offtocn(buf, offset, relocsize); - writeout(buf, relocsize); -#ifdef BSD_A_OUT - if (reloc_output) - { - u4_t bitfield; - - if (curseg == 0) - { - ++ntreloc; - offtocn(buf, spos, 4); - writetrel(buf, 4); - } - else - { - ++ndreloc; - offtocn(buf, spos - segbase[1], 4); - writedrel(buf, 4); - } - if (symptr->flags & I_MASK) - bitfield = (1L << 27) | symbolnum; - else if ((symptr->flags & SEGM_MASK) == 0) - bitfield = N_TEXT; - else if (symptr->flags & (C_MASK | SA_MASK)) - bitfield = N_BSS; - else - bitfield = N_DATA; - if (modify & R_MASK) - bitfield |= 1L << 24; - if (relocsize == 2) - bitfield |= 1L << 25; - else if (relocsize == 4) - bitfield |= 1L << 26; - u4cn(buf, bitfield, 4); - if (curseg == 0) - writetrel(buf, 4); - else - writedrel(buf, 4); - } -#endif /* BSD_A_OUT */ - spos += relocsize; - } - } -} - -PRIVATE void linkrefs(modptr) -struct modstruct *modptr; -{ - register struct symstruct **symparray; - register struct symstruct *symptr; - - modptr->loadflag = TRUE; - for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) - if (symptr->modptr->loadflag == FALSE) - linkrefs(symptr->modptr); -} - -PRIVATE void padmod(modptr) -struct modstruct *modptr; -{ - offset_t count; - char seg; - offset_t size; - unsigned sizecount; - char *sizeptr; - - for (seg = 0, sizeptr = modptr->segsize; seg < NSEG; ++seg) - { - size = cntooffset(sizeptr, - sizecount = segsizecount((unsigned) seg, modptr)); - sizeptr += sizecount; - if ((count = segpos[seg] - segbase[seg]) != size) - size_error(seg, count, size); - - /* pad to quad boundary */ - /* not padding in-between common areas which sometimes get into file */ - if ((size = ld_roundup(segpos[seg], 4, offset_t) - segpos[seg]) != 0) - { - setseg(seg); - writenulls(size); - segpos[seg] = spos; - } - segbase[seg] = segpos[seg]; - } -} - -PRIVATE void setsym(name, value) -char *name; -offset_t value; -{ - struct symstruct *symptr; - -#ifdef BSD_A_OUT - if (!reloc_output) -#endif - if ((symptr = findsym(name)) != NULL) - symptr->value = value; -} - -PRIVATE void symres(name) -register char *name; -{ - register struct symstruct *symptr; - - if ((symptr = findsym(name)) != NULL) - { - if ((symptr->flags & SEGM_MASK) == SEGM_MASK) - symptr->flags &= ~SEGM_MASK | curseg; - if (symptr->flags != (I_MASK | curseg) || symptr->value != 0) - reserved(name); -#ifdef BSD_A_OUT - if (!reloc_output) -#endif - symptr->flags = E_MASK | curseg; /* show defined, not common */ - } -} - -/* set new segment */ - -PRIVATE void setseg(newseg) -unsigned newseg; -{ - if (newseg != curseg) - { - segpos[curseg] = spos; - spos = segpos[curseg = newseg]; - seekout(FILEHEADERLENGTH + (long) spos + (long) segadj[curseg]); - } -} - -PRIVATE void skip(countsize) -unsigned countsize; -{ - writenulls((offset_t) readsize(countsize)); -} - -#ifdef EDOS - -PRIVATE void writeheader(commandname) -char *commandname; -{ - char buf[MAX_OFFSET_SIZE]; - offset_t offset; - unsigned headlength; - char *name; - struct entrylist *elptr; - struct symstruct *startptr; - - headlength = binheaderlength(commandname); - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) - headlength -= 6; - offset = headlength; - startptr = findsym("start"); - offtocn(buf, edataoffset, 2); - writeout(buf, 2); - writechar(0xFF); /* dummy data length 0xFFFF takes everything */ - writechar(0xFF); - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) - { - name = idconvert(elptr, commandname); - writeout(name, (unsigned) strlen(name) + 1); - ourfree(name); - offtocn(buf, startptr == NULL ? elptr->elsymptr->value : offset, 2); - writeout(buf, 2); - writechar(0x82); /* 8 = set flags from here, 2 = cmd line */ - offset += 6; /* LBSR $xxxx and LBRA $xxxx */ - } - writechar(0); - if (startptr != NULL) - { - offset = headlength + 3; /* over 1st LBSR */ - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) - { - writechar(0x17); /* LBSR */ - offtocn(buf, startptr->value - offset, 2); - writeout(buf, 2); - writechar(0x16); /* LBRA */ - offtocn(buf, elptr->elsymptr->value - offset - 3, 2); - writeout(buf, 2); - offset += 6; - } - } -} - -#endif /* EDOS */ - -#ifdef MINIX - -PRIVATE void writeheader() -{ - struct exec header; - - memset(&header, 0, sizeof header); - header.a_magic[0] = A_MAGIC0; - header.a_magic[1] = A_MAGIC1; -#ifdef BSD_A_OUT - if (!reloc_output) -#endif - { - header.a_flags = sepid ? A_SEP : A_EXEC; - if (uzp) - header.a_flags |= A_UZP; - } -#ifdef BSD_A_OUT - header.a_cpu = (bits32 || reloc_output) ? A_I80386 : A_I8086; -#else - header.a_cpu = bits32 ? A_I80386 : A_I8086; -#endif - header.a_hdrlen = FILEHEADERLENGTH; - offtocn((char *) &header.a_text, etextpadoff - btextoffset, - sizeof header.a_text); - offtocn((char *) &header.a_data, edataoffset - bdataoffset, - sizeof header.a_data); - offtocn((char *) &header.a_bss, endoffset - edataoffset, - sizeof header.a_bss); -#ifdef BSD_A_OUT - if (!reloc_output) -#endif - { - if (uzp) - offtocn((char *) &header.a_entry, page_size(), - sizeof header.a_entry); - offtocn((char *) &header.a_total, (offset_t) - (endoffset < 0x00010000L ? 0x00010000L : endoffset + 0x0008000L), - sizeof header.a_total); - } - writeout((char *) &header, FILEHEADERLENGTH); -} - -#endif /* MINIX */ - -PRIVATE void writenulls(count) -offset_t count; -{ - spos += count; - while (count--) - writechar(0); -} diff --git a/dis88/Makefile b/dis88/Makefile new file mode 100644 index 0000000..692326f --- /dev/null +++ b/dis88/Makefile @@ -0,0 +1,51 @@ +# Makefile for dis + +# @(#) Makefile, Ver. 2.1 created 00:00:00 87/09/01 +# Makefile for 8088 symbolic disassembler + +# Copyright (C) 1987 G. M. Harding, all rights reserved. +# Permission to copy and redistribute is hereby granted, +# provided full source code, with all copyright notices, +# accompanies any redistribution. + +# This Makefile automates the process of compiling and linking +# a symbolic object-file disassembler program for the Intel +# 8088 CPU. Relatively machine-independent code is contained in +# the file dismain.c; lookup tables and handler routines, which +# are by their nature machine-specific, are contained in two +# files named distabs.c and dishand.c, respectively. (A third +# machine-specific file, disfp.c, contains handler routines for +# floating-point coprocessor opcodes.) A header file, dis.h, +# attempts to mediate between the machine-specific and machine- +# independent portions of the code. An attempt has been made to +# isolate machine dependencies and to deal with them in fairly +# straightforward ways. Thus, it should be possible to target a +# different CPU by rewriting the handler routines and changing +# the initialization data in the lookup tables. It should not +# be necessary to alter the formats of the tables. + +CC=bcc +CFLAGS=-O +LDFLAGS= + +OBJ = disrel.o dismain.o distabs.o dishand.o disfp.o + +all: dis88 + +dis88: $(OBJ) + $(CC) $(LDFLAGS) -o dis88 $(OBJ) + +install: /usr/bin/dis88 + +/usr/bin/dis88: dis88 + install -cs -o bin dis88 $@ + +disrel.o: disrel.c +dismain.o: dismain.c dis.h +distabs.o: distabs.c dis.h +dishand.o: dishand.c dis.h +disfp.o: disfp.c dis.h + + +clean: + rm -f *.bak *.o core dis88 diff --git a/dis88/README b/dis88/README new file mode 100644 index 0000000..efc5ad9 --- /dev/null +++ b/dis88/README @@ -0,0 +1,90 @@ + dis88 + Beta Release + 87/09/01 + --- + G. M. HARDING + POB 4142 + Santa Clara CA 95054-0142 + + + "Dis88" is a symbolic disassembler for the Intel 8088 CPU, + designed to run under the PC/IX operating system on an IBM XT + or fully-compatible clone. Its output is in the format of, and + is completely compatible with, the PC/IX assembler, "as". The + program is copyrighted by its author, but may be copied and re- + distributed freely provided that complete source code, with all + copyright notices, accompanies any distribution. This provision + also applies to any modifications you may make. You are urged + to comment such changes, giving, as a miminum, your name and + complete address. + + This release of the program is a beta release, which means + that it has been extensively, but not exhaustively, tested. + User comments, recommendations, and bug fixes are welcome. The + principal features of the current release are: + + (a) The ability to disassemble any file in PC/IX object + format, making full use of symbol and relocation information if + it is present, regardless of whether the file is executable or + linkable, and regardless of whether it has continuous or split + I/D space; + + (b) Automatic generation of synthetic labels when no sym- + bol table is available; and + + (c) Optional output of address and object-code informa- + tion as assembler comment text. + + Limitations of the current release are: + + (a) Numeric co-processor (i.e., 8087) mnemonics are not + supported. Instructions for the co-processor are disassembled + as CPU escape sequences, or as interrupts, depending on how + they were assembled in the first place. This limitation will be + addressed in a future release. + + (b) Symbolic references within the object file's data + segment are not supported. Thus, for example, if a data segment + location is initialized to point to a text segment address, no + reference to a text segment symbol will be detected. This limi- + tation is likely to remain in future releases, because object + code does not, in most cases, contain sufficient information to + allow meaningful interpretation of pure data. (Note, however, + that symbolic references to the data segment from within the + text segment are always supported.) + + As a final caveat, be aware that the PC/IX assembler does + not recognize the "esc" mnemonic, even though it refers to a + completely valid CPU operation which is documented in all the + Intel literature. Thus, the corresponding opcodes (0xd8 through + 0xdf) are disassembled as .byte directives. For reference, how- + ever, the syntactically-correct "esc" instruction is output as + a comment. + + To build the disassembler program, transfer all the source + files, together with the Makefile, to a suitable (preferably + empty) PC/IX directory. Then, simply type "make". + + To use dis88, place it in a directory which appears in + your $PATH list. It may then be invoked by name from whatever + directory you happen to be in. As a minimum, the program must + be invoked with one command-line argument: the name of the ob- + ject file to be disassembled. (Dis88 will complain if the file + specified is not an object file.) Optionally, you may specify + an output file; stdout is the default. One command-line switch + is available: "-o", which makes the program display addresses + and object code along with its mnemonic disassembly. + + The "-o" option is useful primarily for verifying the cor- + rectness of the program's output. In particular, it may be used + to check the accuracy of local relative jump opcodes. These + jumps often target local labels, which are lost at assembly + time; thus, the disassembly may contain cryptic instructions + like "jnz .+39". As a user convenience, all relative jump and + call opcodes are output with a comment which identifies the + physical target address. + + By convention, the release level of the program as a whole + is the SID of the file disrel.c, and this SID string appears in + each disassembly. Release 2.1 of the program is the first beta + release to be distributed on Usenet. diff --git a/dis88/a.out.h b/dis88/a.out.h new file mode 120000 index 0000000..ccbf4b5 --- /dev/null +++ b/dis88/a.out.h @@ -0,0 +1 @@ +../libc/include/a.out.h
\ No newline at end of file diff --git a/dis88/ansi.h b/dis88/ansi.h new file mode 100644 index 0000000..825b4a6 --- /dev/null +++ b/dis88/ansi.h @@ -0,0 +1,58 @@ +/* The <ansi.h> header attempts to decide whether the compiler has enough + * conformance to Standard C for Minix to take advantage of. If so, the + * symbol _ANSI is defined (as 31415). Otherwise _ANSI is not defined + * here, but it may be defined by applications that want to bend the rules. + * The magic number in the definition is to inhibit unnecessary bending + * of the rules. (For consistency with the new '#ifdef _ANSI" tests in + * the headers, _ANSI should really be defined as nothing, but that would + * break many library routines that use "#if _ANSI".) + + * If _ANSI ends up being defined, a macro + * + * _PROTOTYPE(function, params) + * + * is defined. This macro expands in different ways, generating either + * ANSI Standard C prototypes or old-style K&R (Kernighan & Ritchie) + * prototypes, as needed. Finally, some programs use _CONST, _VOIDSTAR etc + * in such a way that they are portable over both ANSI and K&R compilers. + * The appropriate macros are defined here. + */ + +#ifndef _ANSI_H +#define _ANSI_H + +#if __STDC__ == 1 +#define _ANSI 31459 /* compiler claims full ANSI conformance */ +#endif + +#ifdef __GNUC__ +#define _ANSI 31459 /* gcc conforms enough even in non-ANSI mode */ +#endif + +#ifdef _ANSI + +/* Keep everything for ANSI prototypes. */ +#define _PROTOTYPE(function, params) function params +#define _ARGS(params) params + +#define _VOIDSTAR void * +#define _VOID void +#define _CONST const +#define _VOLATILE volatile +#define _SIZET size_t + +#else + +/* Throw away the parameters for K&R prototypes. */ +#define _PROTOTYPE(function, params) function() +#define _ARGS(params) () + +#define _VOIDSTAR void * +#define _VOID void +#define _CONST +#define _VOLATILE +#define _SIZET int + +#endif /* _ANSI */ + +#endif /* ANSI_H */ diff --git a/dis88/dis.h b/dis88/dis.h new file mode 100644 index 0000000..7815e06 --- /dev/null +++ b/dis88/dis.h @@ -0,0 +1,170 @@ + /* + ** @(#) dis.h, Ver. 2.1 created 00:00:00 87/09/01 + */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 1987 G. M. Harding, all rights reserved * + * * + * Permission to copy and redistribute is hereby granted, * + * provided full source code, with all copyright notices, * + * accompanies any redistribution. * + * * + * This file contains declarations and definitions used by * + * the 8088 disassembler program. The program was designed * + * for execution on a machine of its own type (i.e., it is * + * not designed as a cross-disassembler); consequently, A * + * SIXTEEN-BIT INTEGER SIZE HAS BEEN ASSUMED. This assump- * + * tion is not particularly important, however, except in * + * the machine-specific portions of the code (i.e., the * + * handler routines and the optab[] array). It should be * + * possible to override this assumption, for execution on * + * 32-bit machines, by use of a pre-processor directive * + * (see below); however, this has not been tested. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include <sys/types.h> +#include <fcntl.h> /* System file-control definitions */ +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> /* System standard I/O definitions */ +#include "a.out.h" /* Object file format definitions */ +#include "ansi.h" + +#define MAXSYM 800 /* Maximum entries in symbol table */ + +extern struct nlist /* Array to hold the symbol table */ + symtab[MAXSYM]; + +extern struct reloc /* Array to hold relocation table */ + relo[MAXSYM]; + +extern int symptr; /* Index into the symtab[] array */ +extern int relptr; /* Index into the relo[] array */ + +struct opcode /* Format for opcode data records */ +{ + char *text; /* Pointer to mnemonic text */ + void (*func)(); /* Pointer to handler routine */ + unsigned min; /* Minimum # of object bytes */ + unsigned max; /* Maximum # of object bytes */ +}; + +extern struct opcode /* Array to hold the opcode table */ + optab[256]; + +extern char *REGS[]; /* Table of register names */ +extern char *REGS0[]; /* Mode 0 register name table */ +extern char *REGS1[]; /* Mode 1 register name table */ + +#define AL REGS[0] /* CPU register manifests */ +#define CL REGS[1] +#define DL REGS[2] +#define BL REGS[3] +#define AH REGS[4] +#define CH REGS[5] +#define DH REGS[6] +#define BH REGS[7] +#define AX REGS[8] +#define CX REGS[9] +#define DX REGS[10] +#define BX REGS[11] +#define SP REGS[12] +#define BP REGS[13] +#define SI REGS[14] +#define DI REGS[15] +#define ES REGS[16] +#define CS REGS[17] +#define SS REGS[18] +#define DS REGS[19] +#define BX_SI REGS0[0] +#define BX_DI REGS0[1] +#define BP_SI REGS0[2] +#define BP_DI REGS0[3] + +extern int symrank[6][6]; /* Symbol type/rank matrix */ +extern unsigned long PC; /* Current program counter */ +extern int segflg; /* Flag: segment override in effect */ +extern int objflg; /* Flag: output object as a comment */ + +#define OBJMAX 8 /* Size of the object code buffer */ + +extern unsigned char /* Internal buffer for object code */ + objbuf[OBJMAX]; + +extern int objptr; /* Index into the objbuf[] array */ + +extern char ADD[], /* Opcode family mnemonic strings */ + OR[], + ADC[], + SBB[], + AND[], + SUB[], + XOR[], + CMP[], + NOT[], + NEG[], + MUL[], + DIV[], + MOV[], + ESC[], + TEST[], + AMBIG[]; + +extern char *OPFAM[]; /* Indexed mnemonic family table */ +extern struct exec HDR; /* Holds the object file's header */ + +#define LOOK_ABS 0 /* Arguments to lookup() function */ +#define LOOK_REL 1 +#define LOOK_LNG 2 + +#define TR_STD 0 /* Arguments to mtrans() function */ +#define TR_SEG 8 + + /* Macro for byte input primitive */ +/* #define FETCH(p) ++PC; p = getchar() & 0xff; objbuf[objptr++] = p */ +static int _F_; +#define FETCH(p) (p)=_F_ = Fetch(); if(_F_<0) {printf("???\n"); return; } + + +/* disfp.c */ +_PROTOTYPE(void eshand, (int j )); +_PROTOTYPE(void fphand, (int j )); +_PROTOTYPE(void inhand, (int j )); + +/* dishand.c */ +_PROTOTYPE(void objini, (int j )); +_PROTOTYPE(void objout, (void)); +_PROTOTYPE(void badseq, (int j, int k )); +_PROTOTYPE(void dfhand, (int j )); +_PROTOTYPE(void sbhand, (int j )); +_PROTOTYPE(void aohand, (int j )); +_PROTOTYPE(void sjhand, (int j )); +_PROTOTYPE(void imhand, (int j )); +_PROTOTYPE(void mvhand, (int j )); +_PROTOTYPE(void mshand, (int j )); +_PROTOTYPE(void pohand, (int j )); +_PROTOTYPE(void cihand, (int j )); +_PROTOTYPE(void mihand, (int j )); +_PROTOTYPE(void mqhand, (int j )); +_PROTOTYPE(void tqhand, (int j )); +_PROTOTYPE(void rehand, (int j )); +_PROTOTYPE(void mmhand, (int j )); +_PROTOTYPE(void srhand, (int j )); +_PROTOTYPE(void aahand, (int j )); +_PROTOTYPE(void iohand, (int j )); +_PROTOTYPE(void ljhand, (int j )); +_PROTOTYPE(void mahand, (int j )); +_PROTOTYPE(void mjhand, (int j )); + +/* dismain.c */ +_PROTOTYPE(void main, (int argc, char **argv )); + +/* distabs.c */ +_PROTOTYPE(char *getnam, (int k )); +_PROTOTYPE(int lookext, (long off, long loc, char *buf )); +_PROTOTYPE(char *lookup, (long addr, int type, int kind, long ext )); +_PROTOTYPE(char *mtrans, (int c, int m, int type )); +_PROTOTYPE(void mtrunc, (char *a )); diff --git a/dis88/dis88.1 b/dis88/dis88.1 new file mode 100644 index 0000000..c991ad7 --- /dev/null +++ b/dis88/dis88.1 @@ -0,0 +1,147 @@ +.TH dis88 1 LOCAL +.SH "NAME" +dis88 \- 8088 symbolic disassembler +.SH "SYNOPSIS" +\fBdis88\fP [ -o ] ifile [ ofile ] +.SH "DESCRIPTION" +Dis88 reads ifile, which must be in PC/IX a.out format. +It interprets the binary opcodes and data locations, and +writes corresponding assembler source code to stdout, or +to ofile if specified. The program's output is in the +format of, and fully compatible with, the PC/IX assembler, +as(1). If a symbol table is present in ifile, labels and +references will be symbolic in the output. If the input +file lacks a symbol table, the fact will be noted, and the +disassembly will proceed, with the disassembler generating +synthetic labels as needed. If the input file has split +I/D space, or if it is executable, the disassembler will +make all necessary adjustments in address-reference calculations. +.PP +If the "-o" option appears, object code will be included +in comments during disassembly of the text segment. This +feature is used primarily for debugging the disassembler +itself, but may provide information of passing interest +to users. +.PP +The program always outputs the current machine address +before disassembling an opcode. If a symbol table is +present, this address is output as an assembler comment; +otherwise, it is incorporated into the synthetic label +which is generated internally. Since relative jumps, +especially short ones, may target unlabelled locations, +the program always outputs the physical target address +as a comment, to assist the user in following the code. +.PP +The text segment of an object file is always padded to +an even machine address. In addition, if the file has +split I/D space, the text segment will be padded to a +paragraph boundary (i.e., an address divisible by 16). +As a result of this padding, the disassembler may produce +a few spurious, but harmless, instructions at the +end of the text segment. +.PP +Disassembly of the data segment is a difficult matter. +The information to which initialized data refers cannot +be inferred from context, except in the special case +of an external data or address reference, which will be +reflected in the relocation table. Internal data and +address references will already be resolved in the object file, +and cannot be recreated. Therefore, the data +segment is disassembled as a byte stream, with long +stretches of null data represented by an appropriate +".zerow" pseudo-op. This limitation notwithstanding, +labels (as opposed to symbolic references) are always +output at appropriate points within the data segment. +.PP +If disassembly of the data segment is difficult, disassembly of the +bss segment is quite easy, because uninitialized data is all +zero by definition. No data +is output in the bss segment, but symbolic labels are +output as appropriate. +.PP +For each opcode which takes an operand, a particular +symbol type (text, data, or bss) is appropriate. This +tidy correspondence is complicated somewhat, however, +by the existence of assembler symbolic constants and +segment override opcodes. Therefore, the disassembler's +symbol lookup routine attempts to apply a certain amount +of intelligence when it is asked to find a symbol. If +it cannot match on a symbol of the preferred type, it +may return a symbol of some other type, depending on +preassigned (and somewhat arbitrary) rankings within +each type. Finally, if all else fails, it returns a +string containing the address sought as a hex constant; +this behavior allows calling routines to use the output +of the lookup function regardless of the success of its +search. +.PP +It is worth noting, at this point, that the symbol lookup +routine operates linearly, and has not been optimized in +any way. Execution time is thus likely to increase +geometrically with input file size. The disassembler is +internally limited to 1500 symbol table entries and 1500 +relocation table entries; while these limits are generous +(/unix, itself, has fewer than 800 symbols), they are not +guaranteed to be adequate in all cases. If the symbol +table or the relocation table overflows, the disassembly +aborts. +.PP +Finally, users should be aware of a bug in the assembler, +which causes it not to parse the "esc" mnemonic, even +though "esc" is a completely legitimate opcode which is +documented in all the Intel literature. To accommodate +this deficiency, the disassembler translates opcodes of +the "esc" family to .byte directives, but notes the +correct mnemonic in a comment for reference. +.PP +In all cases, it should be possible to submit the output +of the disassembler program to the assembler, and assemble +it without error. In most cases, the resulting object +code will be identical to the original; in any event, it +will be functionally equivalent. +.SH "SEE ALSO" +adb(1), as(1), cc(1), ld(1). +.br +"Assembler Reference Manual" in the PC/IX Programmer's +Guide. +.SH "DIAGNOSTICS" +"can't access input file" if the input file cannot be +found, opened, or read. +.sp +"can't open output file" if the output file cannot be +created. +.sp +"warning: host/cpu clash" if the program is run on a +machine with a different CPU. +.sp +"input file not in object format" if the magic number +does not correspond to that of a PC/IX object file. +.sp +"not an 8086/8088 object file" if the CPU ID of the +file header is incorrect. +.sp +"reloc table overflow" if there are more than 1500 +entries in the relocation table. +.sp +"symbol table overflow" if there are more than 1500 +entries in the symbol table. +.sp +"lseek error" if the input file is corrupted (should +never happen). +.sp +"warning: no symbols" if the symbol table is missing. +.sp +"can't reopen input file" if the input file is removed +or altered during program execution (should never happen). +.SH "BUGS" +Numeric co-processor (i.e., 8087) mnemonics are not currently supported. +Instructions for the co-processor are +disassembled as CPU escape sequences, or as interrupts, +depending on how they were assembled in the first place. +.sp +Despite the program's best efforts, a symbol retrieved +from the symbol table may sometimes be different from +the symbol used in the original assembly. +.sp +The disassembler's internal tables are of fixed size, +and the program aborts if they overflow. diff --git a/dis88/disfp.c b/dis88/disfp.c new file mode 100644 index 0000000..c6dc0da --- /dev/null +++ b/dis88/disfp.c @@ -0,0 +1,157 @@ +static char *sccsid = + "@(#) disfp.c, Ver. 2.1 created 00:00:00 87/09/01"; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 1987 G. M. Harding, all rights reserved * + * * + * Permission to copy and redistribute is hereby granted, * + * provided full source code, with all copyright notices, * + * accompanies any redistribution. * + * * + * This file contains handler routines for the numeric op- * + * codes of the 8087 co-processor, as well as a few other * + * opcodes which are related to 8087 emulation. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "dis.h" /* Disassembler declarations */ + +#define FPINT0 0xd8 /* Floating-point interrupts */ +#define FPINT1 0xd9 +#define FPINT2 0xda +#define FPINT3 0xdb +#define FPINT4 0xdc +#define FPINT5 0xdd +#define FPINT6 0xde +#define FPINT7 0xdf + + /* Test for floating opcodes */ +#define ISFLOP(x) \ + (((x) >= FPINT0) && ((x) <= FPINT7)) + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for the escape family of opcodes. * + * These opcodes place the contents of a specified memory * + * location on the system bus, for access by a peripheral * + * or by a co-processor such as the 8087. (The 8087 NDP is * + * accessed only via bus escapes.) Due to a bug in the * + * PC/IX assembler, the "esc" mnemonic is not recognized; * + * consequently, escape opcodes are disassembled as .byte * + * directives, with the appropriate mnemonic and operand * + * included as a comment. FOR NOW, those escape sequences * + * corresponding to 8087 opcodes are treated as simple * + * escapes. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +eshand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF eshand() * * * * * * * * * */ + + register char *a; + register int k; + + objini(j); + + FETCH(k); + + a = mtrans((j & 0xfd),(k & 0xc7),TR_STD); + + mtrunc(a); + + printf("\t.byte\t0x%02.2x\t\t| esc\t%s\n",j,a); + + for (k = 1; k < objptr; ++k) + printf("\t.byte\t0x%02.2x\n",objbuf[k]); + +}/* * * * * * * * * * * END OF eshand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler routine for floating-point opcodes. * + * Since PC/IX must accommodate systems with and without * + * 8087 co-processors, it allows floating-point operations * + * to be initiated in either of two ways: by a software * + * interrput whose type is in the range 0xd8 through 0xdf, * + * or by a CPU escape sequence, which is invoked by an op- * + * code in the same range. In either case, the subsequent * + * byte determines the actual numeric operation to be per- * + * formed. However, depending on the method of access, * + * either one or two code bytes will precede that byte, * + * and the fphand() routine has no way of knowing whether * + * it was invoked by interrupt or by an escape sequence. * + * Therefore, unlike all of the other handler routines ex- * + * cept dfhand(), fphand() does not initialize the object * + * buffer, leaving that chore to the caller. * + * * + * FOR NOW, fphand() does not disassemble floating-point * + * opcodes to floating mnemonics, but simply outputs the * + * object code as .byte directives. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +fphand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF fphand() * * * * * * * * * */ + + register int k; + + segflg = 0; + + FETCH(k); + + printf("\t.byte\t0x%02.2x\t\t| 8087 code sequence\n", + objbuf[0]); + + for (k = 1; k < objptr; ++k) + printf("\t.byte\t0x%02.2x\n",objbuf[k]); + +/* objout(); FOR NOW */ + +}/* * * * * * * * * * * END OF fphand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for variable software interrupt * + * opcodes. It is included in this file because PC/IX im- * + * plements its software floating-point emulation by means * + * of interrupts. Any interrupt in the range 0xd8 through * + * 0xdf is an NDP-emulation interrupt, and is specially * + * handled by the assembler. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +inhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF inhand() * * * * * * * * * */ + + register int k; + + objini(j); + + FETCH(k); + + if (ISFLOP(k)) + { + fphand(k); + return; + } + + printf("%s\t%d\n",optab[j].text,k); + + objout(); + +}/* * * * * * * * * * * END OF inhand() * * * * * * * * * * */ + + diff --git a/dis88/dishand.c b/dis88/dishand.c new file mode 100644 index 0000000..5983972 --- /dev/null +++ b/dis88/dishand.c @@ -0,0 +1,1049 @@ +static char *sccsid = + "@(#) dishand.c, Ver. 2.1 created 00:00:00 87/09/01"; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 1987 G. M. Harding, all rights reserved * + * * + * Permission to copy and redistribute is hereby granted, * + * provided full source code, with all copyright notices, * + * accompanies any redistribution. * + * * + * This file contains the source code for most of the spe- * + * cialized handler routines of the disassembler program. * + * (The file disfp.c contains handler routines specific to * + * the 8087 numeric co-processor.) Each handler routine * + * interprets the opcode byte (and subsequent data bytes, * + * if any) of a particular family of opcodes, and is re- * + * sponsible for generating appropriate output. All of the * + * code in this file is highly MACHINE-SPECIFIC, and would * + * have to be rewritten for a different CPU. The handler * + * routines are accessed only via pointers in the optab[] * + * array, however, so machine dependencies are confined to * + * this file, its sister file "disfp.c", and the data file * + * "distabs.c". * + * * + * All of the code in this file is based on the assumption * + * of sixteen-bit integers. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "dis.h" /* Disassembler declarations */ + +int segflg; /* Segment-override flag */ + +unsigned char objbuf[OBJMAX]; /* Buffer for object code */ + +int objptr; /* Index into objbuf[] */ + +unsigned long PC; /* Current program counter */ + + /* * * * * * MISCELLANEOUS SUPPORTING ROUTINES * * * * * */ + + +void +objini(j) /* Object code init routine */ + + register int j; + +{ + if ((segflg == 1) || (segflg == 2)) + segflg *= 3; + else + segflg = 0; + objptr = 0; + objbuf[objptr++] = (unsigned char)(j); +} + + +void +objout() /* Object-code output routine */ + +{ + register int k; + + if ( ! objflg ) + return; + else + { + printf("\t|"); + if (symptr >= 0) + printf(" %05.5lx:",(PC + 1L - (long)(objptr))); + for (k = 0; k < objptr; ++k) + printf(" %02.2x",objbuf[k]); + putchar('\n'); + } +} + + +void +badseq(j,k) /* Invalid-sequence routine */ + + register int j, k; + +{ + printf("\t.byte\t0x%02.2x\t\t| invalid code sequence\n",j); + printf("\t.byte\t0x%02.2x\n",k); +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This routine is the first of several opcode-specific * + * handlers, each of which is dedicated to a particular * + * opcode family. A pointer to a handler routine is con- * + * tained in the second field of each optab[] entry. The * + * dfhand() routine is the default handler, invoked when * + * no other handler is appropriate (generally, when an in- * + * valid opcode is encountered). * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +dfhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF dfhand() * * * * * * * * * */ + + segflg = 0; + + printf("\t.byte\t0x%02.2x",j); + + if (optab[j].min || optab[j].max) + putchar('\n'); + else + printf("\t\t| unimplemented opcode\n"); + +}/* * * * * * * * * * * END OF dfhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the single-byte handler, invoked whenever a * + * one-byte opcode is encountered. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +sbhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF sbhand() * * * * * * * * * */ + + objini(j); + + if (j == 0x2e) /* seg cs */ + segflg = 1; + + if ((j == 0x26) /* seg es */ + || (j == 0x36) /* seg ss */ + || (j == 0x3e)) /* seg ds */ + segflg = 2; + + printf("%s\n",optab[j].text); + + objout(); + +}/* * * * * * * * * * * END OF sbhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for most of the processor's regular * + * arithmetic operations. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +aohand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF aohand() * * * * * * * * * */ + + register int k; + int m, n; + char b[80]; + + objini(j); + + switch (j & 7) + { + case 0 : + case 1 : + case 2 : + case 3 : + printf("%s\t",optab[j].text); + FETCH(k); + printf("%s\n",mtrans(j,k,TR_STD)); + break; + case 4 : + FETCH(k); + printf("%s\tal,*0x%02.2x\n",optab[j].text,k); + break; + case 5 : + FETCH(m); + FETCH(n); + k = (n << 8) | m; + if (lookext((long)(k),(PC - 1),b)) + printf("%s\tax,#%s\n",optab[j].text,b); + else + printf("%s\tax,#0x%04.4x\n",optab[j].text,k); + break; + default : + dfhand(j); + break; + } + + objout(); + +}/* * * * * * * * * * * END OF aohand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for opcodes which perform short * + * (eight-bit) relative jumps. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +sjhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF sjhand() * * * * * * * * * */ + + register int k; + int m; + + objini(j); + + FETCH(m); + + if (m & 0x80) + k = 0xff00; + else + k = 0; + + k |= m; + + printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text, + lookup((PC + k + 1L),N_TEXT,LOOK_REL,-1L), + (PC + k + 1L)); + + objout(); + +}/* * * * * * * * * * * END OF sjhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for a loosely-knit family of op- * + * codes which perform arithmetic and logical operations, * + * and which take immediate data. The routine's logic is * + * rather complex, so, in an effort to avoid additional * + * complexity, the search for external references in the * + * relocation table has been dispensed with. Eager hackers * + * can try their hand at coding such a search. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +imhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF imhand() * * * * * * * * * */ + + unsigned long pc; + register int k; + int offset, oflag, immed, iflag, mod, opi, w, rm; + int m, n; + static char a[100], b[30]; + + objini(j); + + FETCH(k); + + pc = PC + 1; + + offset = 0; + mod = (k & 0xc0) >> 6; + opi = (k & 0x38) >> 3; + w = j & 1; + rm = k & 7; + + if ((j & 2) + && ((opi == 1) + || (opi == 4) + || (opi == 6))) + { + badseq(j,k); + return; + } + + strcpy(a,OPFAM[opi]); + + if ( ! w ) + strcat(a,"b"); + + if ((oflag = mod) > 2) + oflag = 0; + + if ((mod == 0) && (rm == 6)) + { + FETCH(m); + FETCH(n); + offset = (n << 8) | m; + } + else if (oflag) + if (oflag == 2) + { + FETCH(m); + FETCH(n); + offset = (n << 8) | m; + } + else + { + FETCH(m); + if (m & 0x80) + n = 0xff00; + else + n = 0; + offset = n | m; + } + + switch (j & 3) + { + case 0 : + case 2 : + FETCH(immed); + iflag = 0; + break; + case 1 : + FETCH(m); + FETCH(n); + immed = (n << 8) | m; + iflag = 1; + break; + case 3 : + FETCH(immed); + if (immed & 0x80) + immed &= 0xff00; + iflag = 0; + break; + } + + strcat(a,"\t"); + + switch (mod) + { + case 0 : + if (rm == 6) + strcat(a, + lookup((long)(offset),N_DATA,LOOK_ABS,pc)); + else + { + sprintf(b,"(%s)",REGS0[rm]); + strcat(a,b); + } + break; + case 1 : + case 2 : + if (mod == 1) + strcat(a,"*"); + else + strcat(a,"#"); + sprintf(b,"%d(",offset); + strcat(a,b); + strcat(a,REGS1[rm]); + strcat(a,")"); + break; + case 3 : + strcat(a,REGS[(w << 3) | rm]); + break; + } + + strcat(a,","); + if (iflag) + strcat(a,"#"); + else + strcat(a,"*"); + sprintf(b,"%d",immed); + strcat(a,b); + + printf("%s\n",a); + + objout(); + +}/* * * * * * * * * * * END OF imhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for various "mov"-type opcodes * + * which use the mod, reg, and r/m fields of the second * + * code byte in a standard, straightforward way. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mvhand(j) + + int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mvhand() * * * * * * * * * */ + + register int k, m = j; + + objini(j); + + FETCH(k); + + if ((m == 0x84) || (m == 0x85) /* Kind of kludgey */ + || (m == 0xc4) || (m == 0xc5) + || (m == 0x8d)) + if (m & 0x40) + m |= 0x03; + else + m |= 0x02; + + printf("%s\t%s\n",optab[j].text,mtrans(m,k,TR_STD)); + + objout(); + +}/* * * * * * * * * * * END OF mvhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for segment-register "mov" opcodes. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mshand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mshand() * * * * * * * * * */ + + register int k; + + objini(j); + + FETCH(k); + + if (k & 0x20) + { + badseq(j,k); + return; + } + + printf("%s\t%s\n",optab[j].text,mtrans(j,k,TR_SEG)); + + objout(); + +}/* * * * * * * * * * * END OF mshand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for pops, other than single-byte * + * pops. (The 8088 allows popping into any register, or * + * directly into memory, accessed either immediately or * + * through a register and an index.) * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +pohand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF pohand() * * * * * * * * * */ + + char *a; + register int k; + + objini(j); + + FETCH(k); + + if (k & 0x38) + { + badseq(j,k); + return; + } + + printf("%s\t",optab[j].text); + + a = mtrans((j & 0xfd),k,TR_STD); + + mtrunc(a); + + printf("%s\n",a); + + objout(); + +}/* * * * * * * * * * * END OF pohand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler routine for intersegment calls and * + * jumps. Its output is never symbolic, because the host * + * linker does not allow symbolic intersegment address * + * references except by means of symbolic constants, and * + * any such constants in the symbol table, even if they * + * are of the appropriate value, may be misleading. In * + * compiled code, intersegment references should not be * + * encountered, and even in assembled code, they should * + * occur infrequently. If and when they do occur, however, * + * they will be disassembled in absolute form. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +cihand(j) + + int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF cihand() * * * * * * * * * */ + + register int m, n; + + objini(j); + + printf("%s\t",optab[j].text); + + FETCH(m); + FETCH(n); + + printf("#0x%04.4x,",((n << 8) | m)); + + FETCH(m); + FETCH(n); + + printf("#0x%04.4x\n",((n << 8) | m)); + + objout(); + +}/* * * * * * * * * * * END OF cihand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for "mov" opcodes with immediate * + * data. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mihand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mihand() * * * * * * * * * */ + + register int k; + int m, n; + char b[80]; + + objini(j); + + printf("%s",optab[j].text); + + if (j & 8) + { + FETCH(m); + FETCH(n); + k = ((n << 8) | m); + if (lookext((long)(k),(PC - 1),b)) + printf("#%s\n",b); + else + printf("#%d\n",k); + } + else + { + FETCH(m); + printf("*%d\n",m); + } + + objout(); + +}/* * * * * * * * * * * END OF mihand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for a family of quick-move opcodes. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mqhand(j) + + int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mqhand() * * * * * * * * * */ + + unsigned long pc; + register int m, n; + + objini(j); + + pc = PC + 1; + + FETCH(m); + FETCH(n); + + m = (n << 8) | m; + + printf("%s\t",optab[j].text); + + if (j & 2) + printf("%s,%s\n", + lookup((long)(m),N_DATA,LOOK_ABS,pc), + REGS[(j & 1) << 3]); + else + printf("%s,%s\n", + REGS[(j & 1) << 3], + lookup((long)(m),N_DATA,LOOK_ABS,pc)); + + objout(); + +}/* * * * * * * * * * * END OF mqhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for a family of quick-test opcodes. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +tqhand(j) + + int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF tqhand() * * * * * * * * * */ + + register int m, n; + int k; + char b[80]; + + objini(j); + + printf("%s\t%s,",optab[j].text,REGS[(j & 1) << 3]); + + FETCH(m); + + if (j & 1) + { + FETCH(n); + k = ((n << 8) | m); + if (lookext((long)(k),(PC - 1),b)) + printf("#%s\n",b); + else + printf("#%d\n",k); + } + else + { + if (m & 80) + m |= 0xff00; + printf("*%d\n",m); + } + + objout(); + +}/* * * * * * * * * * * END OF tqhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for multiple-byte "return" opcodes. * + * The 8088 allows returns to take an optional 16-bit ar- * + * gument, which reflects the amount to be added to SP * + * after the pop of the return address. The idea is to * + * facilitate the use of local parameters on the stack. * + * After some rumination, it was decided to disassemble * + * any such arguments as absolute quantities, rather than * + * rummaging through the symbol table for possible corre- * + * sponding constants. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +rehand(j) + + int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF rehand() * * * * * * * * * */ + + register int m, n; + + objini(j); + + FETCH(m); + FETCH(n); + + m = (n << 8) | m; + + printf("%s\t#0x%04.4x\n",optab[j].text,m); + + objout(); + +}/* * * * * * * * * * * END OF rehand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for "mov" opcodes involving memory * + * and immediate data. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mmhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mmhand() * * * * * * * * * */ + + char *a; + register int k; + char b[80]; + + objini(j); + + FETCH(k); + + if (k & 0x38) + { + badseq(j,k); + return; + } + + printf("%s",optab[j].text); + + if ( ! (j & 1) ) + putchar('b'); + + a = mtrans((j & 0xfd),(k & 0xc7),TR_STD); + + mtrunc(a); + + printf("\t%s,",a); + + if (j & 1) + { + FETCH(j); + FETCH(k); + k = (k << 8) | j; + if (lookext((long)(k),(PC - 1),b)) + printf("#%s\n",b); + else + printf("#%d\n",k); + } + else + { + FETCH(k); + printf("*%d\n",k); + } + + objout(); + +}/* * * * * * * * * * * END OF mmhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for the 8088 family of shift and * + * rotate instructions. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +srhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF srhand() * * * * * * * * * */ + + char *a; + register int k; + + objini(j); + + FETCH(k); + + if ((k & 0x38) == 0x30) + { + badseq(j,k); + return; + } + + printf("%s",OPFAM[((k & 0x38) >> 3) + 16]); + + if ( ! (j & 1) ) + putchar('b'); + + a = mtrans((j & 0xfd),(k & 0xc7),TR_STD); + + mtrunc(a); + + printf("\t%s",a); + + if (j & 2) + printf(",cl\n"); + else + printf(",*1\n"); + + objout(); + +}/* * * * * * * * * * * END OF srhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for the ASCII-adjust opcodes. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +aahand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF aahand() * * * * * * * * * */ + + register int k; + + objini(j); + + FETCH(k); + + if (k != 0x0a) + { + badseq(j,k); + return; + } + + printf("%s\n",optab[j].text); + + objout(); + +}/* * * * * * * * * * * END OF aahand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for port I/O opcodes which specify * + * the port address as an immediate operand. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +iohand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF iohand() * * * * * * * * * */ + + register int k; + + objini(j); + + FETCH(k); + + printf("%s\t0x%02.2x\n",optab[j].text,k); + + objout(); + +}/* * * * * * * * * * * END OF iohand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for opcodes which perform long * + * (sixteen-bit) relative jumps and calls. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +ljhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF ljhand() * * * * * * * * * */ + + register int k; + int m, n; + + objini(j); + + FETCH(m); + FETCH(n); + + k = (n << 8) | m; + + printf("%s\t%s\t\t| loc %05.5lx\n",optab[j].text, + lookup((PC + k + 1L),N_TEXT,LOOK_LNG,(PC - 1L)), + (PC + k + 1L)); + + objout(); + +}/* * * * * * * * * * * END OF ljhand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for a pair of oddball opcodes (0xf6 * + * and 0xf7) which perform miscellaneous arithmetic opera- * + * tions not dealt with elsewhere. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mahand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mahand() * * * * * * * * * */ + + char *a; + register int k; + char b[80]; + + objini(j); + + FETCH(k); + + a = mtrans((j & 0xfd),(k & 0xc7),TR_STD); + + mtrunc(a); + + switch (((k = objbuf[1]) & 0x38) >> 3) + { + case 0 : + printf("\ttest"); + break; + case 1 : + badseq(j,k); + return; + case 2 : + printf("\tnot"); + break; + case 3 : + printf("\tneg"); + break; + case 4 : + printf("\tmul"); + break; + case 5 : + printf("\timul"); + break; + case 6 : + printf("\tdiv"); + break; + case 7 : + printf("\tidiv"); + break; + } + + if ( ! (j & 1) ) + putchar('b'); + + printf("\t%s",a); + + if (k & 0x38) + putchar('\n'); + else + if (j & 1) + { + FETCH(j); + FETCH(k); + k = (k << 8) | j; + if (lookext((long)(k),(PC - 1),b)) + printf(",#%s\n",b); + else + printf(",#%d\n",k); + } + else + { + FETCH(k); + printf(",*%d\n",k); + } + + objout(); + +}/* * * * * * * * * * * END OF mahand() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the handler for miscellaneous jump, call, push, * + * and increment/decrement opcodes (0xfe and 0xff) which * + * are not dealt with elsewhere. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mjhand(j) + + register int j; /* Pointer to optab[] entry */ + +{/* * * * * * * * * * START OF mjhand() * * * * * * * * * */ + + char *a; + register int k; + + objini(j); + + FETCH(k); + + a = mtrans((j & 0xfd),(k & 0xc7),TR_STD); + + mtrunc(a); + + switch (((k = objbuf[1]) & 0x38) >> 3) + { + case 0 : + printf("\tinc"); + if ( ! (j & 1) ) + putchar('b'); + putchar('\t'); + break; + case 1 : + printf("\tdec"); + if ( ! (j & 1) ) + putchar('b'); + putchar('\t'); + break; + case 2 : + if (j & 1) + printf("\tcall\t@"); + else + goto BAD; + break; + case 3 : + if (j & 1) + printf("\tcalli\t@"); + else + goto BAD; + break; + case 4 : + if (j & 1) + printf("\tjmp\t@"); + else + goto BAD; + break; + case 5 : + if (j & 1) + printf("\tjmpi\t@"); + else + goto BAD; + break; + case 6 : + if (j & 1) + printf("\tpush\t"); + else + goto BAD; + break; + case 7 : + BAD : + badseq(j,k); + return; + } + + printf("%s\n",a); + + objout(); + +}/* * * * * * * * * * * END OF mjhand() * * * * * * * * * * */ + + diff --git a/dis88/dismain.c b/dis88/dismain.c new file mode 100644 index 0000000..f9ec6c5 --- /dev/null +++ b/dis88/dismain.c @@ -0,0 +1,650 @@ +static char *sccsid = "@(#) dismain.c, Ver. 2.1 created 00:00:00 87/09/01"; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 1987 G. M. Harding, all rights reserved * + * * + * Permission to copy and redistribute is hereby granted, * + * provided full source code, with all copyright notices, * + * accompanies any redistribution. * + * * + * This file contains the source code for the machine- * + * independent portions of a disassembler program to run * + * in a Unix (System III) environment. It expects, as its * + * input, a file in standard a.out format, optionally con- * + * taining symbol table information. If a symbol table is * + * present, it will be used in the disassembly; otherwise, * + * all address references will be literal (absolute). * + * * + * The disassembler program was originally written for an * + * Intel 8088 CPU. However, all details of the actual CPU * + * architecture are hidden in three machine-specific files * + * named distabs.c, dishand.c, and disfp.c (the latter * + * file is specific to the 8087 numeric co-processor). The * + * code in this file is generic, and should require mini- * + * mal revision if a different CPU is to be targeted. If a * + * different version of Unix is to be targeted, changes to * + * this file may be necessary, and if a completely differ- * + * ent OS is to be targeted, all bets are off. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "dis.h" /* Disassembler declarations */ + +extern char *release; /* Contains release string */ +static char *IFILE = NULL; /* Points to input file name */ +static char *OFILE = NULL; /* Points to output file name */ +static char *PRG; /* Name of invoking program */ +static unsigned long zcount; /* Consecutive "0" byte count */ +int objflg = 0; /* Flag: output object bytes */ + +#define unix 1 +#define i8086 1 +#define ibmpc 1 + +#if unix && i8086 && ibmpc /* Set the CPU identifier */ +static int cpuid = 1; +#else +static int cpuid = 0; +#endif + +_PROTOTYPE(static void usage, (char *s )); +_PROTOTYPE(static void fatal, (char *s, char *t )); +_PROTOTYPE(static void zdump, (unsigned long beg )); +_PROTOTYPE(static void prolog, (void)); +_PROTOTYPE(static void distext, (void)); +_PROTOTYPE(static void disdata, (void)); +_PROTOTYPE(static void disbss, (void)); + +_PROTOTYPE(static char *invoker, (char *s)); +_PROTOTYPE(static int objdump, (char *c)); +_PROTOTYPE(static char *getlab, (int type)); +_PROTOTYPE(static void prolog, (void)); + + /* * * * * * * MISCELLANEOUS UTILITY FUNCTIONS * * * * * * */ + +static void +usage(s) + register char *s; +{ + fprintf(stderr,"Usage: %s [-o] ifile [ofile]\n",s); + exit(-1); +} + +static void +fatal(s,t) + register char *s, *t; +{ + fprintf(stderr,"%s: %s\n",s,t); + exit(-1); +} + +static void +zdump(beg) + unsigned long beg; +{ + beg = PC - beg; + if (beg > 1L) + printf("\t.zerow\t%ld\n",(beg >> 1)); + if (beg & 1L) + printf("\t.byte\t0\n"); +} + +static char * +invoker(s) + register char *s; +{ + register int k; + + k = strlen(s); + + while (k--) + if (s[k] == '/') + { + s += k; + ++s; + break; + } + + return (s); +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This rather tricky routine supports the disdata() func- * + * tion. Its job is to output the code for a sequence of * + * data bytes whenever the object buffer is full, or when * + * a symbolic label is to be output. However, it must also * + * keep track of consecutive zero words so that lengthy * + * stretches of null data can be compressed by the use of * + * an appropriate assembler pseudo-op. It does this by * + * setting and testing a file-wide flag which counts suc- * + * cessive full buffers of null data. The function returns * + * a logical TRUE value if it outputs anything, logical * + * FALSE otherwise. (This enables disdata() to determine * + * whether to output a new synthetic label when there is * + * no symbol table.) * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static int +objdump(c) + + register char *c; + +{/* * * * * * * * * * START OF objdump() * * * * * * * * * */ + + register int k; + int retval = 0; + + if (objptr == OBJMAX) + { + for (k = 0; k < OBJMAX; ++k) + if (objbuf[k]) + break; + if (k == OBJMAX) + { + zcount += k; + objptr = 0; + if (c == NULL) + return (retval); + } + } + + if (zcount) + { + printf("\t.zerow\t%ld\n",(zcount >> 1)); + ++retval; + zcount = 0L; + } + + if (objptr) + { + printf("\t.byte\t"); + ++retval; + } + else + return (retval); + + for (k = 0; k < objptr; ++k) + { + printf("0x%02.2x",objbuf[k]); + if (k < (objptr - 1)) + putchar(','); + else + putchar('\n'); + } + + objptr = 0; + + return (retval); + +}/* * * * * * * * * * END OF objdump() * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This routine, called at the beginning of the input * + * cycle for each object byte, and before any interpreta- * + * tion is attempted, searches the symbol table for any * + * symbolic name with a value corresponding to the cur- * + * rent PC and a type corresponding to the segment type * + * (i.e., text, data, or bss) specified by the function's * + * argument. If any such name is found, a pointer to it is * + * returned; otherwise, a NULL pointer is returned. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static char * +getlab(type) +register int type; +{/* * * * * * * * * * START OF getlab() * * * * * * * * * */ + + register int k; + static char b[48], c[32]; + + if (symptr < 0) + if ((type == N_TEXT) + || ((type == N_DATA) && ( ! objptr ) && ( ! zcount ))) + { + if (type == N_TEXT) + sprintf(b,"T%05.5lx:",PC); + else + sprintf(b,"D%05.5lx:",PC); + return (b); + } + else + return (NULL); + + for (k = 0; k <= symptr; ++k) + if ((symtab[k].n_value == PC) + && ((symtab[k].n_sclass & N_SECT) == type)) + { + sprintf(b,"%s:\n",getnam(k)); + if (objflg && (type != N_TEXT)) + sprintf(c,"| %05.5lx\n",PC); + strcat(b,c); + return (b); + } + + return (NULL); + +}/* * * * * * * * * * * END OF getlab() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This routine performs a preliminary scan of the symbol * + * table, before disassembly begins, and outputs declara- * + * tions of globals and constants. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static void +prolog() + +{/* * * * * * * * * * START OF prolog() * * * * * * * * * */ + + register int j, flag; + + fflush(stdout); + + if (symptr < 0) + return; + + for (j = flag = 0; j <= symptr; ++j) + if ((symtab[j].n_sclass & N_CLASS) == C_EXT) + if (((symtab[j].n_sclass & N_SECT) > N_UNDF) + && ((symtab[j].n_sclass & N_SECT) < N_COMM)) + { + char *c = getnam(j); + printf("\t.globl\t%s",c); + if (++flag == 1) + { + putchar('\t'); + if (strlen(c) < 8) + putchar('\t'); + printf("| Internal global\n"); + } + else + putchar('\n'); + } + else + if (symtab[j].n_value) + { + char *c = getnam(j); + printf("\t.comm\t%s,0x%08.8lx",c, + symtab[j].n_value); + if (++flag == 1) + printf("\t| Internal global\n"); + else + putchar('\n'); + } + + if (flag) + putchar('\n'); + fflush(stdout); + + for (j = flag = 0; j <= relptr; ++j) + if (relo[j].r_symndx < S_BSS) + { + char *c = getnam(relo[j].r_symndx); + ++flag; + printf("\t.globl\t%s",c); + putchar('\t'); + if (strlen(c) < 8) + putchar('\t'); + printf("| Undef: %05.5lx\n",relo[j].r_vaddr); + } + + if (flag) + putchar('\n'); + fflush(stdout); + + for (j = flag = 0; j <= symptr; ++j) + if ((symtab[j].n_sclass & N_SECT) == N_ABS) + { + char *c = getnam(j); + printf("%s=0x%08.8lx",c,symtab[j].n_value); + if (++flag == 1) + { + printf("\t\t"); + if (strlen(c) < 5) + putchar('\t'); + printf("| Literal\n"); + } + else + putchar('\n'); + } + + if (flag) + putchar('\n'); + fflush(stdout); + +}/* * * * * * * * * * * END OF prolog() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function is responsible for disassembly of the * + * object file's text segment. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static void +distext() + +{/* * * * * * * * * * START OF distext() * * * * * * * * * */ + + char *c; + register int j; + register void (*f)(); + + for (j = 0; j < (int)(HDR.a_hdrlen); ++j) + getchar(); + + printf("| %s, %s\n\n",PRG,release); + + printf("| @("); + + printf("#)\tDisassembly of %s",IFILE); + + if (symptr < 0) + printf(" (no symbols)\n\n"); + else + printf("\n\n"); + + if (HDR.a_flags & A_EXEC) + printf("| File is executable\n\n"); + + if (HDR.a_flags & A_SEP) + { + printf("| File has split I/D space, and may have\n"); + printf("| extraneous instructions in text segment\n\n"); + } + + prolog(); + + printf("\t.text\t\t\t| loc = %05.5lx, size = %05.5lx\n\n", + PC,HDR.a_text); + fflush(stdout); + + segflg = 0; + + for (PC = 0L; PC < HDR.a_text; ++PC) + { + j = getchar() & 0xff; + if ((j == 0) && ((PC + 1L) == HDR.a_text)) + { + ++PC; + break; + } + if ((c = getlab(N_TEXT)) != NULL) + printf("%s",c); + f = optab[j].func; + (*f)(j); + fflush(stdout); + } + +}/* * * * * * * * * * END OF distext() * * * * * * * * * */ + +Fetch() +{ + int p; + ++PC; + if( symptr>=0 && getlab(N_TEXT) != NULL ) { --PC; return -1; } + +/* #define FETCH(p) ++PC; p = getchar() & 0xff; objbuf[objptr++] = p */ + p = getchar() & 0xff; + objbuf[objptr++] = p; + return p; +} + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function handles the object file's data segment. * + * There is no good way to disassemble a data segment, be- * + * cause it is impossible to tell, from the object code * + * alone, what each data byte refers to. If it refers to * + * an external symbol, the reference can be resolved from * + * the relocation table, if there is one. However, if it * + * refers to a static symbol, it cannot be distinguished * + * from numeric, character, or other pointer data. In some * + * cases, one might make a semi-educated guess as to the * + * nature of the data, but such guesses are inherently * + * haphazard, and they are bound to be wrong a good por- * + * tion of the time. Consequently, the data segment is * + * disassembled as a byte stream, which will satisfy no * + * one but which, at least, will never mislead anyone. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static void +disdata() + +{/* * * * * * * * * * START OF disdata() * * * * * * * * * */ + + register char *c; + register int j; + unsigned long end; + + putchar('\n'); + + if (HDR.a_flags & A_SEP) + { + PC = 0L; + end = HDR.a_data; + } + else + end = HDR.a_text + HDR.a_data; + + printf("\t.data\t\t\t| loc = %05.5lx, size = %05.5lx\n\n", + PC,HDR.a_data); + + segflg = 0; + + for (objptr = 0, zcount = 0L; PC < end; ++PC) + { + if ((c = getlab(N_DATA)) != NULL) + { + objdump(c); + printf("%s",c); + } + if (objptr >= OBJMAX) + if (objdump(NULL) && (symptr < 0)) + printf("D%05.5lx:",PC); + j = getchar() & 0xff; + objbuf[objptr++] = j; + } + + objdump(""); + +}/* * * * * * * * * * END OF disdata() * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function handles the object file's bss segment. * + * Disassembly of the bss segment is easy, because every- * + * thing in it is zero by definition. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static void disbss() + +{/* * * * * * * * * * START OF disbss() * * * * * * * * * */ + + register int j; + register char *c; + unsigned long beg, end; + + putchar('\n'); + + if (HDR.a_flags & A_SEP) + end = HDR.a_data + HDR.a_bss; + else + end = HDR.a_text + HDR.a_data + HDR.a_bss; + + printf("\t.bss\t\t\t| loc = %05.5lx, size = %05.5lx\n\n", + PC,HDR.a_bss); + + segflg = 0; + + for (beg = PC; PC < end; ++PC) + if ((c = getlab(N_BSS)) != NULL) + { + if (PC > beg) + { + zdump(beg); + beg = PC; + } + printf("%s",c); + } + + if (PC > beg) + zdump(beg); + +}/* * * * * * * * * * * END OF disbss() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This is the program entry point. The command line is * + * searched for an input file name, which must be present. * + * An optional output file name is also permitted; if none * + * is found, standard output is the default. One command- * + * line option is available: "-o", which causes the pro- * + * gram to include object code in comments along with its * + * mnemonic output. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +main(argc,argv) + + int argc; /* Command-line args from OS */ + register char **argv; + +{/* * * * * * * * * * * START OF main() * * * * * * * * * * */ + + char a[1024]; + register int fd; + long taboff, tabnum; + long reloff, relnum; + + PRG = invoker(*argv); + + while (*++argv != NULL) /* Process command-line args */ + if (**argv == '-') + switch (*++*argv) + { + case 'o' : + if (*++*argv) + usage(PRG); + else + ++objflg; + break; + default : + usage(PRG); + } + else + if (IFILE == NULL) + IFILE = *argv; + else if (OFILE == NULL) + OFILE = *argv; + else + usage(PRG); + + if (IFILE == NULL) + usage(PRG); + else + if ((fd = open(IFILE,0)) < 0) + { + sprintf(a,"can't access input file %s",IFILE); + fatal(PRG,a); + } + + if (OFILE != NULL) + if (freopen(OFILE,"w",stdout) == NULL) + { + sprintf(a,"can't open output file %s",OFILE); + fatal(PRG,a); + } + + if ( ! cpuid ) + fprintf(stderr,"%s: warning: host/cpu clash\n",PRG); + + read(fd, (char *) &HDR,sizeof(struct exec)); + + if (BADMAG(HDR)) + { + sprintf(a,"input file %s not in object format",IFILE); + fatal(PRG,a); + } + + if (HDR.a_cpu != A_I8086) + { + sprintf(a,"%s is not an 8086/8088 object file",IFILE); + fatal(PRG,a); + } + + if (HDR.a_hdrlen <= A_MINHDR) + HDR.a_trsize = HDR.a_drsize = 0L; + HDR.a_tbase = HDR.a_dbase = 0L; +/* AST emergency patch + HDR.a_lnums = HDR.a_toffs = 0L; +*/ + + reloff = HDR.a_text /* Compute reloc data offset */ + + HDR.a_data + + (long)(HDR.a_hdrlen); + + relnum = + (HDR.a_trsize + HDR.a_drsize) / sizeof(struct reloc); + + taboff = reloff /* Compute name table offset */ + + HDR.a_trsize + + HDR.a_drsize; + + tabnum = HDR.a_syms / sizeof(struct nlist); + + if (relnum > MAXSYM) + fatal(PRG,"reloc table overflow"); + + if (tabnum > MAXSYM) + fatal(PRG,"symbol table overflow"); + + if (relnum) /* Get reloc data */ + if (lseek(fd,reloff,0) != reloff) + fatal(PRG,"lseek error"); + else + { + for (relptr = 0; relptr < relnum; ++relptr) + read(fd, (char *) &relo[relptr],sizeof(struct reloc)); + relptr--; + } + + if (tabnum) /* Read in symtab */ + if (lseek(fd,taboff,0) != taboff) + fatal(PRG,"lseek error"); + else + { + for (symptr = 0; symptr < tabnum; ++symptr) + read(fd, (char *) &symtab[symptr],sizeof(struct nlist)); + symptr--; + } + else + fprintf(stderr,"%s: warning: no symbols\n",PRG); + + close(fd); + + if (freopen(IFILE,"r",stdin) == NULL) + { + sprintf(a,"can't reopen input file %s",IFILE); + fatal(PRG,a); + } + + distext(); + + disdata(); + + disbss(); + + exit(0); + +}/* * * * * * * * * * * END OF main() * * * * * * * * * * */ diff --git a/dis88/disrel.c b/dis88/disrel.c new file mode 100644 index 0000000..37f3221 --- /dev/null +++ b/dis88/disrel.c @@ -0,0 +1,30 @@ +static char *copyright = + "@(#) Copyright (C) 1987 G. M. Harding, all rights reserved"; + +static char *sccsid = + "@(#) disrel.c, Ver. 2.1 created 00:00:00 87/09/01"; + +char *release = + "release 2.1 (MINIX)"; + + /* + ** + ** This file documents the major revisions to the 8088 sym- + ** bolic disassembler. It also contains the release string + ** which is output at the head of each disassembly, and the + ** copyright string which must be incorporated in any code + ** distribution. + ** + ** Permission to copy and redistribute is hereby granted, + ** provided full source code, with all copyright notices, + ** accompanies any redistribution. + ** + ** REVISION HISTORY: + ** + ** SEP 87: + ** After internal shakeout, released on Usenet. + ** + ** JUN 88: + ** Ported to MINIX + */ + diff --git a/dis88/distabs.c b/dis88/distabs.c new file mode 100644 index 0000000..283fe42 --- /dev/null +++ b/dis88/distabs.c @@ -0,0 +1,708 @@ +static char *sccsid = + "@(#) distabs.c, Ver. 2.1 created 00:00:00 87/09/01"; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * Copyright (C) 1987 G. M. Harding, all rights reserved * + * * + * Permission to copy and redistribute is hereby granted, * + * provided full source code, with all copyright notices, * + * accompanies any redistribution. * + * * + * This file contains the lookup tables and other data * + * structures for the Intel 8088 symbolic disassembler. It * + * also contains a few global routines which facilitate * + * access to the tables, for use primarily by the handler * + * functions. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "dis.h" /* Disassembler declarations */ + +struct exec HDR; /* Used to hold header info */ + +struct nlist symtab[MAXSYM]; /* Array of symbol table info */ + +struct reloc relo[MAXSYM]; /* Array of relocation info */ + +int symptr = -1, /* Index into symtab[] */ + relptr = -1; /* Index into relo[] */ + +char *REGS[] = /* Table of register names */ + { + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", + "es", "cs", "ss", "ds" + }; + +char *REGS0[] = /* Mode 0 register name table */ + { + "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "", "bx" + }; + +char *REGS1[] = /* Mode 1 register name table */ + { + "bx_si", "bx_di", "bp_si", "bp_di", "si", "di", "bp", "bx" + }; + +int symrank[6][6] = /* Symbol type/rank matrix */ + { + /* UND ABS TXT DAT BSS COM */ + /* UND */ 5, 4, 1, 2, 3, 0, + /* ABS */ 1, 5, 4, 3, 2, 0, + /* TXT */ 4, 1, 5, 3, 2, 0, + /* DAT */ 3, 1, 2, 5, 4, 0, + /* BSS */ 3, 1, 2, 4, 5, 0, + /* COM */ 2, 0, 1, 3, 4, 5 + }; + + /* * * * * * * * * * * * OPCODE DATA * * * * * * * * * * * */ + +char ADD[] = "\tadd", /* Mnemonics by family */ + OR[] = "\tor", + ADC[] = "\tadc", + SBB[] = "\tsbb", + AND[] = "\tand", + SUB[] = "\tsub", + XOR[] = "\txor", + CMP[] = "\tcmp", + NOT[] = "\tnot", + NEG[] = "\tneg", + MUL[] = "\tmul", + DIV[] = "\tdiv", + MOV[] = "\tmov", + ESC[] = "\tesc", + TEST[] = "\ttest", + AMBIG[] = "", + ROL[] = "\trol", + ROR[] = "\tror", + RCL[] = "\trcl", + RCR[] = "\trcr", + SAL[] = "\tsal", + SHR[] = "\tshr", + SHL[] = "\tshl", + SAR[] = "\tsar"; + +char *OPFAM[] = /* Family lookup table */ + { + ADD, OR, ADC, SBB, AND, SUB, XOR, CMP, + NOT, NEG, MUL, DIV, MOV, ESC, TEST, AMBIG, + ROL, ROR, RCL, RCR, SAL, SHR, SHL, SAR + }; + +struct opcode optab[] = /* Table of opcode data */ + { + ADD, aohand, 2, 4, /* 0x00 */ + ADD, aohand, 2, 4, /* 0x01 */ + ADD, aohand, 2, 4, /* 0x02 */ + ADD, aohand, 2, 4, /* 0x03 */ + ADD, aohand, 2, 2, /* 0x04 */ + ADD, aohand, 3, 3, /* 0x05 */ + "\tpush\tes", sbhand, 1, 1, /* 0x06 */ + "\tpop\tes", sbhand, 1, 1, /* 0x07 */ + OR, aohand, 2, 4, /* 0x08 */ + OR, aohand, 2, 4, /* 0x09 */ + OR, aohand, 2, 4, /* 0x0a */ + OR, aohand, 2, 4, /* 0x0b */ + OR, aohand, 2, 2, /* 0x0c */ + OR, aohand, 3, 3, /* 0x0d */ + "\tpush\tcs", sbhand, 1, 1, /* 0x0e */ + NULL, dfhand, 0, 0, /* 0x0f */ + ADC, aohand, 2, 4, /* 0x10 */ + ADC, aohand, 2, 4, /* 0x11 */ + ADC, aohand, 2, 4, /* 0x12 */ + ADC, aohand, 2, 4, /* 0x13 */ + ADC, aohand, 2, 2, /* 0x14 */ + ADC, aohand, 3, 3, /* 0x15 */ + "\tpush\tss", sbhand, 1, 1, /* 0x16 */ + "\tpop\tss", sbhand, 1, 1, /* 0x17 */ + SBB, aohand, 2, 4, /* 0x18 */ + SBB, aohand, 2, 4, /* 0x19 */ + SBB, aohand, 2, 4, /* 0x1a */ + SBB, aohand, 2, 4, /* 0x1b */ + SBB, aohand, 2, 2, /* 0x1c */ + SBB, aohand, 3, 3, /* 0x1d */ + "\tpush\tds", sbhand, 1, 1, /* 0x1e */ + "\tpop\tds", sbhand, 1, 1, /* 0x1f */ + AND, aohand, 2, 4, /* 0x20 */ + AND, aohand, 2, 4, /* 0x21 */ + AND, aohand, 2, 4, /* 0x22 */ + AND, aohand, 2, 4, /* 0x23 */ + AND, aohand, 2, 2, /* 0x24 */ + AND, aohand, 3, 3, /* 0x25 */ + "\tseg\tes", sbhand, 1, 1, /* 0x26 */ + "\tdaa", sbhand, 1, 1, /* 0x27 */ + SUB, aohand, 2, 4, /* 0x28 */ + SUB, aohand, 2, 4, /* 0x29 */ + SUB, aohand, 2, 4, /* 0x2a */ + SUB, aohand, 2, 4, /* 0x2b */ + SUB, aohand, 2, 2, /* 0x2c */ + SUB, aohand, 3, 3, /* 0x2d */ + "\tseg\tcs", sbhand, 1, 1, /* 0x2e */ + "\tdas", sbhand, 1, 1, /* 0x2f */ + XOR, aohand, 2, 4, /* 0x30 */ + XOR, aohand, 2, 4, /* 0x31 */ + XOR, aohand, 2, 4, /* 0x32 */ + XOR, aohand, 2, 4, /* 0x33 */ + XOR, aohand, 2, 2, /* 0x34 */ + XOR, aohand, 3, 3, /* 0x35 */ + "\tseg\tss", sbhand, 1, 1, /* 0x36 */ + "\taaa", sbhand, 1, 1, /* 0x37 */ + CMP, aohand, 2, 4, /* 0x38 */ + CMP, aohand, 2, 4, /* 0x39 */ + CMP, aohand, 2, 4, /* 0x3a */ + CMP, aohand, 2, 4, /* 0x3b */ + CMP, aohand, 2, 2, /* 0x3c */ + CMP, aohand, 3, 3, /* 0x3d */ + "\tseg\tds", sbhand, 1, 1, /* 0x3e */ + "\taas", sbhand, 1, 1, /* 0x3f */ + "\tinc\tax", sbhand, 1, 1, /* 0x40 */ + "\tinc\tcx", sbhand, 1, 1, /* 0x41 */ + "\tinc\tdx", sbhand, 1, 1, /* 0x42 */ + "\tinc\tbx", sbhand, 1, 1, /* 0x43 */ + "\tinc\tsp", sbhand, 1, 1, /* 0x44 */ + "\tinc\tbp", sbhand, 1, 1, /* 0x45 */ + "\tinc\tsi", sbhand, 1, 1, /* 0x46 */ + "\tinc\tdi", sbhand, 1, 1, /* 0x47 */ + "\tdec\tax", sbhand, 1, 1, /* 0x48 */ + "\tdec\tcx", sbhand, 1, 1, /* 0x49 */ + "\tdec\tdx", sbhand, 1, 1, /* 0x4a */ + "\tdec\tbx", sbhand, 1, 1, /* 0x4b */ + "\tdec\tsp", sbhand, 1, 1, /* 0x4c */ + "\tdec\tbp", sbhand, 1, 1, /* 0x4d */ + "\tdec\tsi", sbhand, 1, 1, /* 0x4e */ + "\tdec\tdi", sbhand, 1, 1, /* 0x4f */ + "\tpush\tax", sbhand, 1, 1, /* 0x50 */ + "\tpush\tcx", sbhand, 1, 1, /* 0x51 */ + "\tpush\tdx", sbhand, 1, 1, /* 0x52 */ + "\tpush\tbx", sbhand, 1, 1, /* 0x53 */ + "\tpush\tsp", sbhand, 1, 1, /* 0x54 */ + "\tpush\tbp", sbhand, 1, 1, /* 0x55 */ + "\tpush\tsi", sbhand, 1, 1, /* 0x56 */ + "\tpush\tdi", sbhand, 1, 1, /* 0x57 */ + "\tpop\tax", sbhand, 1, 1, /* 0x58 */ + "\tpop\tcx", sbhand, 1, 1, /* 0x59 */ + "\tpop\tdx", sbhand, 1, 1, /* 0x5a */ + "\tpop\tbx", sbhand, 1, 1, /* 0x5b */ + "\tpop\tsp", sbhand, 1, 1, /* 0x5c */ + "\tpop\tbp", sbhand, 1, 1, /* 0x5d */ + "\tpop\tsi", sbhand, 1, 1, /* 0x5e */ + "\tpop\tdi", sbhand, 1, 1, /* 0x5f */ + NULL, dfhand, 0, 0, /* 0x60 */ + NULL, dfhand, 0, 0, /* 0x61 */ + NULL, dfhand, 0, 0, /* 0x62 */ + NULL, dfhand, 0, 0, /* 0x63 */ + NULL, dfhand, 0, 0, /* 0x64 */ + NULL, dfhand, 0, 0, /* 0x65 */ + NULL, dfhand, 0, 0, /* 0x66 */ + NULL, dfhand, 0, 0, /* 0x67 */ + NULL, dfhand, 0, 0, /* 0x68 */ + NULL, dfhand, 0, 0, /* 0x69 */ + NULL, dfhand, 0, 0, /* 0x6a */ + NULL, dfhand, 0, 0, /* 0x6b */ + NULL, dfhand, 0, 0, /* 0x6c */ + NULL, dfhand, 0, 0, /* 0x6d */ + NULL, dfhand, 0, 0, /* 0x6e */ + NULL, dfhand, 0, 0, /* 0x6f */ + "\tjo", sjhand, 2, 2, /* 0x70 */ + "\tjno", sjhand, 2, 2, /* 0x71 */ + "\tjc", sjhand, 2, 2, /* 0x72 */ + "\tjnc", sjhand, 2, 2, /* 0x73 */ + "\tjz", sjhand, 2, 2, /* 0x74 */ + "\tjnz", sjhand, 2, 2, /* 0x75 */ + "\tjna", sjhand, 2, 2, /* 0x76 */ + "\tja", sjhand, 2, 2, /* 0x77 */ + "\tjs", sjhand, 2, 2, /* 0x78 */ + "\tjns", sjhand, 2, 2, /* 0x79 */ + "\tjp", sjhand, 2, 2, /* 0x7a */ + "\tjnp", sjhand, 2, 2, /* 0x7b */ + "\tjl", sjhand, 2, 2, /* 0x7c */ + "\tjnl", sjhand, 2, 2, /* 0x7d */ + "\tjng", sjhand, 2, 2, /* 0x7e */ + "\tjg", sjhand, 2, 2, /* 0x7f */ + AMBIG, imhand, 3, 5, /* 0x80 */ + AMBIG, imhand, 4, 6, /* 0x81 */ + AMBIG, imhand, 3, 5, /* 0x82 */ + AMBIG, imhand, 3, 5, /* 0x83 */ + TEST, mvhand, 2, 4, /* 0x84 */ + TEST, mvhand, 2, 4, /* 0x85 */ + "\txchg", mvhand, 2, 4, /* 0x86 */ + "\txchg", mvhand, 2, 4, /* 0x87 */ + MOV, mvhand, 2, 4, /* 0x88 */ + MOV, mvhand, 2, 4, /* 0x89 */ + MOV, mvhand, 2, 4, /* 0x8a */ + MOV, mvhand, 2, 4, /* 0x8b */ + MOV, mshand, 2, 4, /* 0x8c */ + "\tlea", mvhand, 2, 4, /* 0x8d */ + MOV, mshand, 2, 4, /* 0x8e */ + "\tpop", pohand, 2, 4, /* 0x8f */ + "\tnop", sbhand, 1, 1, /* 0x90 */ + "\txchg\tax,cx", sbhand, 1, 1, /* 0x91 */ + "\txchg\tax,dx", sbhand, 1, 1, /* 0x92 */ + "\txchg\tax,bx", sbhand, 1, 1, /* 0x93 */ + "\txchg\tax,sp", sbhand, 1, 1, /* 0x94 */ + "\txchg\tax,bp", sbhand, 1, 1, /* 0x95 */ + "\txchg\tax,si", sbhand, 1, 1, /* 0x96 */ + "\txchg\tax,di", sbhand, 1, 1, /* 0x97 */ + "\tcbw", sbhand, 1, 1, /* 0x98 */ + "\tcwd", sbhand, 1, 1, /* 0x99 */ + "\tcalli", cihand, 5, 5, /* 0x9a */ + "\twait", sbhand, 1, 1, /* 0x9b */ + "\tpushf", sbhand, 1, 1, /* 0x9c */ + "\tpopf", sbhand, 1, 1, /* 0x9d */ + "\tsahf", sbhand, 1, 1, /* 0x9e */ + "\tlahf", sbhand, 1, 1, /* 0x9f */ + MOV, mqhand, 3, 3, /* 0xa0 */ + MOV, mqhand, 3, 3, /* 0xa1 */ + MOV, mqhand, 3, 3, /* 0xa2 */ + MOV, mqhand, 3, 3, /* 0xa3 */ + "\tmovb", sbhand, 1, 1, /* 0xa4 */ + "\tmovw", sbhand, 1, 1, /* 0xa5 */ + "\tcmpb", sbhand, 1, 1, /* 0xa6 */ + "\tcmpw", sbhand, 1, 1, /* 0xa7 */ + TEST, tqhand, 2, 2, /* 0xa8 */ + TEST, tqhand, 3, 3, /* 0xa9 */ + "\tstob", sbhand, 1, 1, /* 0xaa */ + "\tstow", sbhand, 1, 1, /* 0xab */ + "\tlodb", sbhand, 1, 1, /* 0xac */ + "\tlodw", sbhand, 1, 1, /* 0xad */ + "\tscab", sbhand, 1, 1, /* 0xae */ + "\tscaw", sbhand, 1, 1, /* 0xaf */ + "\tmov\tal,", mihand, 2, 2, /* 0xb0 */ + "\tmov\tcl,", mihand, 2, 2, /* 0xb1 */ + "\tmov\tdl,", mihand, 2, 2, /* 0xb2 */ + "\tmov\tbl,", mihand, 2, 2, /* 0xb3 */ + "\tmov\tah,", mihand, 2, 2, /* 0xb4 */ + "\tmov\tch,", mihand, 2, 2, /* 0xb5 */ + "\tmov\tdh,", mihand, 2, 2, /* 0xb6 */ + "\tmov\tbh,", mihand, 2, 2, /* 0xb7 */ + "\tmov\tax,", mihand, 3, 3, /* 0xb8 */ + "\tmov\tcx,", mihand, 3, 3, /* 0xb9 */ + "\tmov\tdx,", mihand, 3, 3, /* 0xba */ + "\tmov\tbx,", mihand, 3, 3, /* 0xbb */ + "\tmov\tsp,", mihand, 3, 3, /* 0xbc */ + "\tmov\tbp,", mihand, 3, 3, /* 0xbd */ + "\tmov\tsi,", mihand, 3, 3, /* 0xbe */ + "\tmov\tdi,", mihand, 3, 3, /* 0xbf */ + NULL, dfhand, 0, 0, /* 0xc0 */ + NULL, dfhand, 0, 0, /* 0xc1 */ + "\tret", rehand, 3, 3, /* 0xc2 */ + "\tret", sbhand, 1, 1, /* 0xc3 */ + "\tles", mvhand, 2, 4, /* 0xc4 */ + "\tlds", mvhand, 2, 4, /* 0xc5 */ + MOV, mmhand, 3, 5, /* 0xc6 */ + MOV, mmhand, 4, 6, /* 0xc7 */ + NULL, dfhand, 0, 0, /* 0xc8 */ + NULL, dfhand, 0, 0, /* 0xc9 */ + "\treti", rehand, 3, 3, /* 0xca */ + "\treti", sbhand, 1, 1, /* 0xcb */ + "\tint", sbhand, 1, 1, /* 0xcc */ + "\tint", inhand, 2, 2, /* 0xcd */ + "\tinto", sbhand, 1, 1, /* 0xce */ + "\tiret", sbhand, 1, 1, /* 0xcf */ + AMBIG, srhand, 2, 4, /* 0xd0 */ + AMBIG, srhand, 2, 4, /* 0xd1 */ + AMBIG, srhand, 2, 4, /* 0xd2 */ + AMBIG, srhand, 2, 4, /* 0xd3 */ + "\taam", aahand, 2, 2, /* 0xd4 */ + "\taad", aahand, 2, 2, /* 0xd5 */ + NULL, dfhand, 0, 0, /* 0xd6 */ + "\txlat", sbhand, 1, 1, /* 0xd7 */ + ESC, eshand, 2, 2, /* 0xd8 */ + ESC, eshand, 2, 2, /* 0xd9 */ + ESC, eshand, 2, 2, /* 0xda */ + ESC, eshand, 2, 2, /* 0xdb */ + ESC, eshand, 2, 2, /* 0xdc */ + ESC, eshand, 2, 2, /* 0xdd */ + ESC, eshand, 2, 2, /* 0xde */ + ESC, eshand, 2, 2, /* 0xdf */ + "\tloopne", sjhand, 2, 2, /* 0xe0 */ + "\tloope", sjhand, 2, 2, /* 0xe1 */ + "\tloop", sjhand, 2, 2, /* 0xe2 */ + "\tjcxz", sjhand, 2, 2, /* 0xe3 */ + "\tin", iohand, 2, 2, /* 0xe4 */ + "\tinw", iohand, 2, 2, /* 0xe5 */ + "\tout", iohand, 2, 2, /* 0xe6 */ + "\toutw", iohand, 2, 2, /* 0xe7 */ + "\tcall", ljhand, 3, 3, /* 0xe8 */ + "\tjmp", ljhand, 3, 3, /* 0xe9 */ + "\tjmpi", cihand, 5, 5, /* 0xea */ + "\tj", sjhand, 2, 2, /* 0xeb */ + "\tin", sbhand, 1, 1, /* 0xec */ + "\tinw", sbhand, 1, 1, /* 0xed */ + "\tout", sbhand, 1, 1, /* 0xee */ + "\toutw", sbhand, 1, 1, /* 0xef */ + "\tlock", sbhand, 1, 1, /* 0xf0 */ + NULL, dfhand, 0, 0, /* 0xf1 */ + "\trepnz", sbhand, 1, 1, /* 0xf2 */ + "\trepz", sbhand, 1, 1, /* 0xf3 */ + "\thlt", sbhand, 1, 1, /* 0xf4 */ + "\tcmc", sbhand, 1, 1, /* 0xf5 */ + AMBIG, mahand, 2, 5, /* 0xf6 */ + AMBIG, mahand, 2, 6, /* 0xf7 */ + "\tclc", sbhand, 1, 1, /* 0xf8 */ + "\tstc", sbhand, 1, 1, /* 0xf9 */ + "\tcli", sbhand, 1, 1, /* 0xfa */ + "\tsti", sbhand, 1, 1, /* 0xfb */ + "\tcld", sbhand, 1, 1, /* 0xfc */ + "\tstd", sbhand, 1, 1, /* 0xfd */ + AMBIG, mjhand, 2, 4, /* 0xfe */ + AMBIG, mjhand, 2, 4 /* 0xff */ + }; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This simple routine returns the name field of a symbol * + * table entry as a printable string. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char * +getnam(k) + + register int k; + +{/* * * * * * * * * * START OF getnam() * * * * * * * * * */ + + register int j; + static char a[sizeof(symtab->n_name)+1]; + + for (j = 0; j < sizeof(symtab[k].n_name); ++j) + if ( ! symtab[k].n_name[j] ) + break; + else + a[j] = symtab[k].n_name[j]; + + a[j] = '\0'; + + return (a); + +}/* * * * * * * * * * * END OF getnam() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function is responsible for mucking through the * + * relocation table in search of externally referenced * + * symbols to be output as operands. It accepts two long * + * arguments: the code-segment location at which an extern * + * reference is expected, and the offset value which is * + * embedded in the object code and used at link time to * + * bias the external value. In the most typical case, the * + * function will be called by lookup(), which always makes * + * a check for external names before searching the symbol * + * table proper. However, it may also be called directly * + * by any function (such as the move-immediate handler) * + * which wants to make an independent check for externals. * + * The caller is expected to supply, as the third argument * + * to the function, a pointer to a character buffer large * + * enough to hold any possible output string. Lookext() * + * will fill this buffer and return a logical TRUE if it * + * finds an extern reference; otherwise, it will return a * + * logical FALSE, leaving the buffer undisturbed. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int +lookext(off,loc,buf) + + long off, loc; + char *buf; + +{/* * * * * * * * * * START OF lookext() * * * * * * * * * */ + + register int k; + char c[32]; + + if ((loc != -1L) && (relptr >= 0)) + for (k = 0; k <= relptr; ++k) + if ((relo[k].r_vaddr == loc) + && (relo[k].r_symndx < S_BSS)) + { + strcpy(buf,getnam(relo[k].r_symndx)); + if (off) + { + if (off < 0) + sprintf(c,"%ld",off); + else + sprintf(c,"+%ld",off); + strcat(buf,c); + } + return (1); + } + + return (0); + +}/* * * * * * * * * * END OF lookext() * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function finds an entry in the symbol table by * + * value. Its input is a (long) machine address, and its * + * output is a pointer to a string containing the corre- * + * sponding symbolic name. The function first searches the * + * relocation table for a possible external reference; if * + * none is found, a linear search of the symbol table is * + * undertaken. If no matching symbol has been found at the * + * end of these searches, the function returns a pointer * + * to a string containing the ASCII equivalent of the ad- * + * dress which was to be located, so that, regardless of * + * the success of the search, the function's return value * + * is suitable for use as a memory-reference operand. The * + * caller specifies the type of symbol to be found (text, * + * data, bss, undefined, absolute, or common) by means of * + * the function's second parameter. The third parameter * + * specifies the format to be used in the event of a nu- * + * meric output: zero for absolute format, one for short * + * relative format, two for long relative format. The * + * fourth parameter is the address which would appear in * + * the relocation table for the reference in question, or * + * -1 if the relocation table is not to be searched. The * + * function attempts to apply a certain amount of intelli- * + * gence in its selection of symbols, so it is possible * + * that, in the absence of a type match, a symbol of the * + * correct value but different type will be returned. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char * +lookup(addr,type,kind,ext) + + long addr; /* Machine address to be located */ + + int type, /* Type of symbol to be matched */ + kind; /* Addressing output mode to use */ + + long ext; /* Value for extern ref, if any */ + +{/* * * * * * * * * * START OF lookup() * * * * * * * * * */ + + register int j, k; + static char b[80]; + + struct + { + int i; + int t; + } + best; + + if (lookext(addr,ext,b)) + return (b); + + if (segflg) + if (segflg & 1) + type = N_TEXT; + else + type = N_DATA; + + for (k = 0, best.i = -1; k <= symptr; ++k) + if (symtab[k].n_value == addr) + if ((j = symtab[k].n_sclass & N_SECT) == type) + { + best.t = j; + best.i = k; + break; + } + else if (segflg || (HDR.a_flags & A_SEP)) + continue; + else if (best.i < 0) + best.t = j, best.i = k; + else if (symrank[type][j] > symrank[type][best.t]) + best.t = j, best.i = k; + + if (best.i >= 0) + return (getnam(best.i)); + + if (kind == LOOK_ABS) + sprintf(b,"0x%05.5x",addr); + else + { + long x = addr - (PC - kind); + if (x < 0) + sprintf(b,".%ld",x); + else + sprintf(b,".+%ld",x); + } + + return (b); + +}/* * * * * * * * * * * END OF lookup() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This function translates an 8088 addressing mode byte * + * to an equivalent assembler string, returning a pointer * + * thereto. If necessary, it performs successive inputs * + * of bytes from the object file in order to obtain offset * + * data, adjusting PC accordingly. (The addressing mode * + * byte appears in several 8088 opcodes; it is used to * + * specify source and destination operand locations.) The * + * third argument to the function is zero if the standard * + * registers are to be used, or eight if the segment reg- * + * isters are to be used; these constants are defined sym- * + * bolically in dis.h. NOTE: The mtrans() function must * + * NEVER be called except immediately after fetching the * + * mode byte. If any additional object bytes are fetched * + * after the fetch of the mode byte, mtrans() will not * + * produce correct output! * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +char * +mtrans(c,m,type) + + register int c; /* Primary instruction byte */ + register int m; /* Addressing mode byte */ + + int type; /* Type code: standard or seg */ + +{/* * * * * * * * * * START OF mtrans() * * * * * * * * * */ + + unsigned long pc; + int offset, oflag, dir, w, mod, reg, rm; + static char a[100]; + static char b[30]; + + offset = 0; + dir = c & 2; + w = c & 1; + mod = (m & 0xc0) >> 6; + reg = (m & 0x38) >> 3; + rm = m & 7; + pc = PC + 1; + + if (type) + w = 1; + + if ((oflag = mod) > 2) + oflag = 0; + + if (oflag) + { + int j, k; + if (oflag == 2) + { + FETCH(j); + FETCH(k); + offset = (k << 8) | j; + } + else + { + FETCH(j); + if (j & 0x80) + k = 0xff00; + else + k = 0; + offset = k | j; + } + } + + if (dir) + { + strcpy(a,REGS[type + ((w << 3) | reg)]); + strcat(a,","); + switch (mod) + { + case 0 : + if (rm == 6) + { + int j, k; + FETCH(j); + FETCH(k); + offset = (k << 8) | j; + strcat(a, + lookup((long)(offset),N_DATA,LOOK_ABS,pc)); + } + else + { + sprintf(b,"(%s)",REGS0[rm]); + strcat(a,b); + } + break; + case 1 : + case 2 : + if (mod == 1) + strcat(a,"*"); + else + strcat(a,"#"); + sprintf(b,"%d(",offset); + strcat(a,b); + strcat(a,REGS1[rm]); + strcat(a,")"); + break; + case 3 : + strcat(a,REGS[(w << 3) | rm]); + break; + } + } + else + { + switch (mod) + { + case 0 : + if (rm == 6) + { + int j, k; + FETCH(j); + FETCH(k); + offset = (k << 8) | j; + strcpy(a, + lookup((long)(offset),N_DATA,LOOK_ABS,pc)); + } + else + { + sprintf(b,"(%s)",REGS0[rm]); + strcpy(a,b); + } + break; + case 1 : + case 2 : + if (mod == 1) + strcpy(a,"*"); + else + strcpy(a,"#"); + sprintf(b,"%d(",offset); + strcat(a,b); + strcat(a,REGS1[rm]); + strcat(a,")"); + break; + case 3 : + strcpy(a,REGS[(w << 3) | rm]); + break; + } + strcat(a,","); + strcat(a,REGS[type + ((w << 3) | reg)]); + } + + return (a); + +}/* * * * * * * * * * * END OF mtrans() * * * * * * * * * * */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This simple routine truncates a string returned by the * + * mtrans() function, removing its source operand. This is * + * useful in handlers which ignore the "reg" field of the * + * mode byte. * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void +mtrunc(a) + + register char *a; /* Ptr. to string to truncate */ + +{/* * * * * * * * * * START OF mtrunc() * * * * * * * * * */ + + register int k; + + for (k = strlen(a) - 1; k >= 0; --k) + if (a[k] == ',') + { + a[k] = '\0'; + break; + } + +}/* * * * * * * * * * * END OF mtrunc() * * * * * * * * * * */ + + diff --git a/dis88/old_a.out.h b/dis88/old_a.out.h new file mode 100644 index 0000000..1a36dfb --- /dev/null +++ b/dis88/old_a.out.h @@ -0,0 +1,117 @@ +/* The <a.out> header file describes the format of executable files. */ + +#ifndef _AOUT_H +#define _AOUT_H + +struct exec { /* a.out header */ + unsigned char a_magic[2]; /* magic number */ + unsigned char a_flags; /* flags, see below */ + unsigned char a_cpu; /* cpu id */ + unsigned char a_hdrlen; /* length of header */ + unsigned char a_unused; /* reserved for future use */ + unsigned short a_version; /* version stamp (not used at present) */ + 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 */ + long a_entry; /* entry point */ + long a_total; /* total memory allocated */ + long a_syms; /* size of symbol table */ + + /* SHORT FORM ENDS HERE */ + long a_trsize; /* text relocation size */ + long a_drsize; /* data relocation size */ + long a_tbase; /* text relocation base */ + long a_dbase; /* data relocation base */ +}; + +#define A_MAGIC0 (unsigned char) 0x01 +#define A_MAGIC1 (unsigned char) 0x03 +#define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 ||(X).a_magic[1] != A_MAGIC1) + +/* CPU Id of TARGET machine (byte order coded in low order two bits) */ +#define A_NONE 0x00 /* unknown */ +#define A_I8086 0x04 /* intel i8086/8088 */ +#define A_M68K 0x0B /* motorola m68000 */ +#define A_NS16K 0x0C /* national semiconductor 16032 */ +#define A_I80386 0x10 /* intel i80386 */ +#define A_SPARC 0x17 /* Sun SPARC */ + +#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */ +#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ + +/* Flags. */ +#define A_UZP 0x01 /* unmapped zero page (pages) */ +#define A_PAL 0x02 /* page aligned executable */ +#define A_NSYM 0x04 /* new style symbol table */ +#define A_EXEC 0x10 /* executable */ +#define A_SEP 0x20 /* separate I/D */ +#define A_PURE 0x40 /* pure text */ /* not used */ +#define A_TOVLY 0x80 /* text overlay */ /* not used */ + +/* Offsets of various things. */ +#define A_MINHDR 32 +#define A_TEXTPOS(X) ((long)(X).a_hdrlen) +#define A_DATAPOS(X) (A_TEXTPOS(X) + (X).a_text) +#define A_HASRELS(X) ((X).a_hdrlen > (unsigned char) A_MINHDR) +#define A_HASEXT(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 8)) +#define A_HASLNS(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16)) +#define A_HASTOFF(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24)) +#define A_TRELPOS(X) (A_DATAPOS(X) + (X).a_data) +#define A_DRELPOS(X) (A_TRELPOS(X) + (X).a_trsize) +#define A_SYMPOS(X) (A_TRELPOS(X) + (A_HASRELS(X) ? \ + ((X).a_trsize + (X).a_drsize) : 0)) + +struct reloc { + long r_vaddr; /* virtual address of reference */ + unsigned short r_symndx; /* internal segnum or extern symbol num */ + unsigned short r_type; /* relocation type */ +}; + +/* r_tyep values: */ +#define R_ABBS 0 +#define R_RELLBYTE 2 +#define R_PCRBYTE 3 +#define R_RELWORD 4 +#define R_PCRWORD 5 +#define R_RELLONG 6 +#define R_PCRLONG 7 +#define R_REL3BYTE 8 +#define R_KBRANCHE 9 + +/* r_symndx for internal segments */ +#define S_ABS ((unsigned short)-1) +#define S_TEXT ((unsigned short)-2) +#define S_DATA ((unsigned short)-3) +#define S_BSS ((unsigned short)-4) + +struct nlist { /* symbol table entry */ + char n_name[8]; /* symbol name */ + long n_value; /* value */ + unsigned char n_sclass; /* storage class */ + unsigned char n_numaux; /* number of auxiliary entries (not used) */ + unsigned short n_type; /* language base and derived type (not used) */ +}; + +/* Low bits of storage class (section). */ +#define N_SECT 07 /* section mask */ +#define N_UNDF 00 /* undefined */ +#define N_ABS 01 /* absolute */ +#define N_TEXT 02 /* text */ +#define N_DATA 03 /* data */ +#define N_BSS 04 /* bss */ +#define N_COMM 05 /* (common) */ + +/* High bits of storage class. */ +#define N_CLASS 0370 /* storage class mask */ +#define C_NULL +#define C_EXT 0020 /* external symbol */ +#define C_STAT 0030 /* static */ + +/* Function prototypes. */ +#ifndef _ANSI_H +#include "ansi.h" +#endif + +_PROTOTYPE( int nlist, (char *_file, struct nlist *_nl) ); + +#endif /* _AOUT_H */ diff --git a/elksemu/Kernel_patch b/elksemu/Kernel_patch new file mode 100644 index 0000000..451455f --- /dev/null +++ b/elksemu/Kernel_patch @@ -0,0 +1,19 @@ + +This kernel patch allows you to run Linux-8086 executables transparently +on a Linux-i386 system. It requires V0.0.2 of elksemu in "/lib/elksemu". + +--- orig-13/fs/exec.c Sun Sep 24 13:22:37 1995 ++++ linux/fs/exec.c Sun Feb 11 20:11:47 1996 +@@ -615,6 +615,12 @@ + set_fs(old_fs); + if (retval < 0) + goto exec_error2; ++#ifndef NO_ELKSEMU ++ /* What a horrible hack! :-) */ ++ if ((bprm.buf[0] == 1) && (bprm.buf[1] == 3) && ++ (bprm.buf[2] == 0x20) && (bprm.buf[3] == 4)) ++ memcpy(bprm.buf, "#!/lib/elksemu\n", 16); ++#endif + if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) { + /* + * This section does the #! interpretation. diff --git a/elksemu/Makefile b/elksemu/Makefile new file mode 100644 index 0000000..cee13ac --- /dev/null +++ b/elksemu/Makefile @@ -0,0 +1,29 @@ +# +# Makefile for elksemu. +# + +CFLAGS=-O2 -fno-strength-reduce -Wall +# If you need an a.out exe. NB The program _does_ now work as ELF +# CFLAGS=-O2 -fno-strength-reduce -b i486-linuxaout -N -s -static + +OBJ=elks.o elks_sys.o elks_signal.o + +elksemu: $(OBJ) + $(CC) $(CFLAGS) -o elksemu $(OBJ) + +$(OBJ): elks.h +elks_sys.o: call_tab.v + +call_tab.v: dummy + -cp -p ../libc/syscall/call_tab.v . 2>/dev/null + -cp -p ../libc/syscall/defn_tab.v . 2>/dev/null + +dummy: + +# The kernel patch _requires_ this location. +install: elksemu + install -s -m 755 elksemu /lib/elksemu + tar cvf V-files.tar call_tab.v defn_tab.v + +clean: + rm -f $(OBJ) elksemu call_tab.v defn_tab.v diff --git a/elksemu/V-files.tar b/elksemu/V-files.tar Binary files differnew file mode 100644 index 0000000..c5e6082 --- /dev/null +++ b/elksemu/V-files.tar diff --git a/elksemu/Version b/elksemu/Version new file mode 100644 index 0000000..38a680f --- /dev/null +++ b/elksemu/Version @@ -0,0 +1 @@ +Version elksemu-0.0.4 diff --git a/elksemu/elks.c b/elksemu/elks.c new file mode 100644 index 0000000..f84c994 --- /dev/null +++ b/elksemu/elks.c @@ -0,0 +1,258 @@ +/* + * ELKSEMU An emulator for Linux8086 binaries. + * + * VM86 is used to process all the 8086 mode code. + * We trap up to 386 mode for system call emulation and naughties. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <unistd.h> +#include <stdarg.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/stat.h> +#include <sys/vm86.h> +#include <sys/mman.h> +#include "elks.h" + +volatile struct vm86_struct elks_cpu; +unsigned char *elks_base; /* Paragraph aligned */ + +#define dbprintf(x) db_printf x +/**/ + +static void elks_init() +{ + elks_cpu.screen_bitmap=0; + elks_cpu.cpu_type = CPU_286; + /* + * All INT xx calls are trapped. + */ + memset((void *)&elks_cpu.int_revectored,0xFF, sizeof(elks_cpu.int_revectored)); +} + +static void elks_take_interrupt(int arg) +{ + if(arg!=0x80) + { + dbprintf(("Took an int %d\n", arg)); + fflush(stderr); + kill(getpid(), SIGILL); + return; + } + + dbprintf(("syscall AX=%X BX=%X CX=%X DX=%x\n", + (unsigned short)elks_cpu.regs.eax, + (unsigned short)elks_cpu.regs.ebx, + (unsigned short)elks_cpu.regs.ecx, + (unsigned short)elks_cpu.regs.edx)); + + elks_cpu.regs.eax = elks_syscall(); + dbprintf(("elks syscall returned %d\n", elks_cpu.regs.eax)); + /* Finally return to vm86 state */ +} + + +static int load_elks(int fd) +{ + /* Load the elks binary image and set it up in a suitable VM86 segment. Load CS and DS/SS + according to image type. chmem is ignored we always use 64K segments */ + struct elks_exec_hdr mh; + unsigned char *dsp; + if(read(fd, &mh,sizeof(mh))!=sizeof(mh)) + return -ENOEXEC; + if(mh.hlen!=EXEC_HEADER_SIZE) + return -ENOEXEC; + if(mh.type!=ELKS_COMBID&&mh.type!=ELKS_SPLITID) + return -ENOEXEC; +#if 0 + fprintf(stderr,"Linux-86 binary - %lX. tseg=%ld dseg=%ld bss=%ld\n", + mh.type,mh.tseg,mh.dseg,mh.bseg); +#endif + if(read(fd,elks_base,mh.tseg)!=mh.tseg) + return -ENOEXEC; + if(mh.type==ELKS_COMBID) + dsp=elks_base+mh.tseg; + else + dsp=elks_base+65536; + if(read(fd,dsp,mh.dseg)!=mh.dseg) + return -ENOEXEC; + memset(dsp+mh.dseg,0, mh.bseg); + /* + * Load the VM86 registers + */ + +/* if(mh.type==ELKS_COMBID) + dsp=elks_base;*/ + elks_cpu.regs.ds=PARAGRAPH(dsp); + elks_cpu.regs.es=PARAGRAPH(dsp); + elks_cpu.regs.ss=PARAGRAPH(dsp); + elks_cpu.regs.esp=65536; /* Args stacked later */ + elks_cpu.regs.cs=PARAGRAPH(elks_base); + elks_cpu.regs.eip=0; /* Run from 0 */ + + /* + * Loaded, check for sanity. + */ + if( dsp != ELKS_PTR(unsigned char, 0) ) + { + printf("Error VM86 problem %lx!=%lx (Is DS > 16 bits ?)\n", + (long)dsp, (long)ELKS_PTR(char, 0)); + exit(0); + } + + return 0; +} + + +void run_elks() +{ + /* + * Execute 8086 code for a while. + */ + int err=vm86((struct vm86_struct*)&elks_cpu); + switch(VM86_TYPE(err)) + { + /* + * Signals are just re-starts of emulation (yes the + * handler might alter elks_cpu) + */ + case VM86_SIGNAL: + break; + case VM86_UNKNOWN: + fprintf(stderr, "VM86_UNKNOWN returned\n"); + exit(1); + case VM86_INTx: + elks_take_interrupt(VM86_ARG(err)); + break; + case VM86_STI: + fprintf(stderr, "VM86_STI returned\n"); + break; /* Shouldnt be seen */ + } +} + +void build_stack(char ** argv, char ** envp) +{ + char **p; + int argv_len=0, argv_count=0; + int envp_len=0, envp_count=0; + int stack_bytes; + unsigned short * pip; + unsigned short pcp; + + /* How much space for argv */ + for(p=argv; *p; p++) + { + argv_count++; argv_len += strlen(*p)+1; + } + + /* How much space for envp */ + for(p=envp; *p; p++) + { + envp_count++; envp_len += strlen(*p)+1; + } + + /* tot it all up */ + stack_bytes = 2 /* argc */ + + argv_count * 2 + 2 /* argv */ + + argv_len + + envp_count * 2 + 2 /* envp */ + + envp_len; + + /* Allocate it */ + elks_cpu.regs.esp -= stack_bytes; + +/* Sanity check + printf("Argv = (%d,%d), Envp=(%d,%d), stack=%d\n", + argv_count, argv_len, envp_count, envp_len, stack_bytes); +*/ + + /* Now copy in the strings */ + pip=ELKS_PTR(unsigned short, elks_cpu.regs.esp); + pcp=elks_cpu.regs.esp+2*(1+argv_count+1+envp_count+1); + + *pip++ = argv_count; + for(p=argv; *p; p++) + { + *pip++ = pcp; + strcpy(ELKS_PTR(char, pcp), *p); + pcp += strlen(*p)+1; + } + *pip++ = 0; + + for(p=envp; *p; p++) + { + *pip++ = pcp; + strcpy(ELKS_PTR(char, pcp), *p); + pcp += strlen(*p)+1; + } + *pip++ = 0; +} + +void main(int argc, char *argv[], char *envp[]) +{ + int fd; + dbprintf(("ELKSEMU 0.01 Alpha\n")); + if(argc==1) + { + fprintf(stderr,"elksemu cmd args.....\n"); + exit(1); + } + elks_init(); + + /* The Linux vm will deal with not allocating the unused pages */ +#if __AOUT__ + /* GNU malloc will align to 4k with large chunks */ + elks_base = malloc(0x20000); +#else + /* For ELF first 128M is unmapped, it needs to be mapped manually */ + elks_base = mmap((void*)0x10000, 0x20000, + PROT_EXEC|PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE|MAP_FIXED, + 0, 0); +#endif + if( (long)elks_base < 0 || (long)elks_base >= 0xE0000 ) + { + fprintf(stderr, "Elks memory is at an illegal address\n"); + exit(255); + } + fd=open(argv[1], O_RDONLY); + if(fd==-1) + { + perror(argv[1]); + exit(1); + } + + if(load_elks(fd) < 0) + { + fprintf(stderr,"Not a elks binary.\n"); + exit(1); + } + + close(fd); + + build_stack(argv+1, envp); + + while(1) + run_elks(); +} + +void db_printf(const char * fmt, ...) +{ +static FILE * db_fd = 0; + va_list ptr; + int rv; + if( db_fd == 0 ) + { + db_fd = fopen("/tmp/ELKS_log", "a"); + if( db_fd == 0 ) db_fd = stderr; + setbuf(db_fd, 0); + } + fprintf(db_fd, "%d: ", getpid()); + va_start(ptr, fmt); + rv = vfprintf(db_fd,fmt,ptr); + va_end(ptr); +} diff --git a/elksemu/elks.h b/elksemu/elks.h new file mode 100644 index 0000000..6d52470 --- /dev/null +++ b/elksemu/elks.h @@ -0,0 +1,96 @@ +/* + * Definitions for emulating ELKS + */ + +#define ELKS_CS_OFFSET 0 +#define ELKS_DS_OFFSET 0 /* For split I/D */ + +#define HZ 100 + +#define ELKS_SIG_IGN (-1) +#define ELKS_SIG_DFL 0 + +#define WRITE_USPACE 0 +#define READ_USPACE 1 + +#if !__ELF__ +#define __AOUT__ 1 +#endif + +/* + * Minix view of stat(). We have to squash a bit here and give + * wrong values with inode >65535 etc + */ + +struct elks_stat +{ + unsigned short st_dev; + unsigned short st_inode; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + int st_size; + int st_atime; + int st_mtime; + int st_ctime; +}; + + +/* + * Minix ioctl list + */ + +#define ELKS_TIOCGETP (('t'<<8)|8) +#define ELKS_TIOCSETP (('t'<<8)|9) +#define ELKS_TIOCGETC (('t'<<8)|18) +#define ELKS_TIOCSETC (('t'<<8)|17) +#define ELKS_TIOCFLUSH (('t'<<8)|16) + +/* + * fcntl list + */ + +#define ELKS_F_DUPFD 0 +#define ELKS_F_GETFD 1 +#define ELKS_F_SETFD 2 +#define ELKS_F_GETFL 3 +#define ELKS_F_SETFL 4 +#define ELKS_F_GETLK 5 +#define ELKS_F_SETLK 6 +#define ELKS_F_SETLKW 7 + +/* + * Elks binary formats + */ + +#define EXEC_HEADER_SIZE 32 + +struct elks_exec_hdr +{ + unsigned long type; +#define ELKS_COMBID 0x04100301L +#define ELKS_SPLITID 0x04200301L + unsigned long hlen; + unsigned long tseg; + unsigned long dseg; + unsigned long bseg; + unsigned long unused; + unsigned long chmem; + unsigned long unused2; +}; + +#define PARAGRAPH(x) (((unsigned long)(x))>>4) +#define ELKS_DSEG(x) ((unsigned char *)(((x)&0xFFFF)+(elks_cpu.regs.ds<<4))) + +#define ELKS_PTR(_t,x) ((_t *) ((elks_cpu.regs.ds<<4)+((x)&0xFFFF)) ) +#define ELKS_PEEK(_t,x) (*((_t *) ((elks_cpu.regs.ds<<4)+((x)&0xFFFF)) )) +#define ELKS_POKE(_t,x,_v) \ + (*((_t *) ((elks_cpu.regs.ds<<4)+((x)&0xFFFF)) ) = (_v)) + +extern unsigned char * elks_base; +extern volatile struct vm86_struct elks_cpu; + +void db_printf(const char *, ...); +int elks_syscall(void); diff --git a/elksemu/elks_signal.c b/elksemu/elks_signal.c new file mode 100644 index 0000000..2bf1e55 --- /dev/null +++ b/elksemu/elks_signal.c @@ -0,0 +1,36 @@ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/stat.h> +#include <sys/vm86.h> +#include "elks.h" + +static int elks_sigtrap= -1; + +void sig_trap(int signo) +{ + elks_cpu.regs.esp -= 2; + ELKS_POKE(unsigned short, elks_cpu.regs.esp, signo); + elks_cpu.regs.esp -= 2; + ELKS_POKE(unsigned short, elks_cpu.regs.esp, elks_cpu.regs.eip); + elks_cpu.regs.eip = elks_sigtrap; +} + +int elks_signal(int bx,int cx,int dx,int di,int si) +{ + int rv; + if( bx < 0 || bx >= NSIG ) { errno = EINVAL; return -1; } + if( cx == 0 ) rv = (signal(bx, SIG_DFL) == SIG_ERR); + else if( cx == 1 ) rv = (signal(bx, SIG_IGN) == SIG_ERR); + else + { + elks_sigtrap = cx; + rv = (signal(bx, sig_trap) == SIG_ERR); + } + + return -rv; +} diff --git a/elksemu/elks_sys.c b/elksemu/elks_sys.c new file mode 100644 index 0000000..7ca946c --- /dev/null +++ b/elksemu/elks_sys.c @@ -0,0 +1,723 @@ +/* + * System calls are mostly pretty easy as the emulator is tightly bound to + * the elks task. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/vm86.h> +#include <sys/times.h> +#include <utime.h> +#include <termios.h> +#include <time.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <sys/ioctl.h> +#include <dirent.h> +#include "elks.h" + +#define dbprintf(x) db_printf x + +#define sys_signal elks_signal +extern int elks_signal(int bx,int cx,int dx,int di,int si); + +/* Forward refs */ +static int elks_termios(int bx,int cx,int dx,int di,int si); +static int elks_enosys(int bx,int cx,int dx,int di,int si); + +#define DIRCOUNT 20 +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_closedir(int bx); + +/* + * Compress a host stat into a elks one. Lose upper bits with wild + * abandon. For SYS5.3 this isn't a problem, but machines with 32 + * bit inodes (BSD, SYS5 with veritas, newest SCO) you lose the top + * bits which can confuse a few programs which use inode numbers + * (eg gnu tar). + */ + +static void squash_stat(struct stat *s, int bx) +{ +#if 1 /* Can't use elks_stat, shot in the foot by alignment */ + + ELKS_POKE(short, bx+0, s->st_dev); + ELKS_POKE(short, bx+2, s->st_ino ^ (s->st_ino>>16)); + ELKS_POKE(short, bx+4, s->st_mode); + ELKS_POKE(short, bx+6, s->st_nlink); + ELKS_POKE(short, bx+8, s->st_uid); + ELKS_POKE(short, bx+10, s->st_gid); + ELKS_POKE(short, bx+12, s->st_rdev); + ELKS_POKE(long, bx+14, s->st_size); + ELKS_POKE(long, bx+18, s->st_atime); + ELKS_POKE(long, bx+22, s->st_mtime); + ELKS_POKE(long, bx+26, s->st_ctime); +#else + struct elks_stat * ms = ELKS_PTR(struct elks_stat, bx); + ms->st_dev=s->st_dev; + ms->st_inode=(unsigned short)s->st_ino; /* Bits lost */ + ms->st_mode=s->st_mode; + ms->st_nlink=s->st_nlink; + ms->st_uid=s->st_uid; + ms->st_gid=s->st_gid; + ms->st_rdev=s->st_rdev; + ms->st_size=s->st_size; + ms->st_atime=s->st_atime; + ms->st_mtime=s->st_mtime; + ms->st_ctime=s->st_ctime; +#endif +} + +/* + * Implementation of ELKS syscalls. + */ + + +#define sys_exit elks_exit +static int elks_exit(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("exit(%d)\n",bx)); + exit(bx); +} + +#define sys_vfork elks_fork +#define sys_fork elks_fork +static int elks_fork(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("fork()\n")); + /* This is fun 8) - fork the emulator (its easier that way) */ + return fork(); +} + +#define sys_read elks_read +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 read(bx, ELKS_PTR(void, cx), dx); +} + +#define sys_write elks_write +static int elks_write(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("write(%d, %d, %d)\n",bx,cx,dx)); + return write(bx,ELKS_PTR(void, cx),dx); +} + +#define sys_open elks_open +static int elks_open(int bx,int cx,int dx,int di,int si) +{ + struct stat s; + + /* Assumes _all_ flags are the same */ + char *dp=ELKS_PTR(char, bx); + dbprintf(("open(%s, %d, %d)\n", + dp,cx,dx)); + + if( cx == O_RDONLY ) + { + if(stat(dp,&s)==-1) + return -1; + if( S_ISDIR(s.st_mode) ) + return elks_opendir(dp); + } + + return open(dp,cx,dx); +} + +#define sys_close elks_close +static int elks_close(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("close(%d)\n",bx)); + if( bx >= 10000 && bx < 10000+DIRCOUNT) + return elks_closedir(bx); + return close(bx); +} + +#define sys_wait4 elks_wait4 +static int elks_wait4(int bx,int cx,int dx,int di,int si) +{ + int status; + unsigned short *tp=ELKS_PTR(unsigned short, cx); + int r; + struct rusage use; + + dbprintf(("wait4(%d, %d, %d, %d)\n", bx, cx, dx, di)); + r=wait4((int)(short)bx, &status, dx, &use ); + + *tp=status; + if( di ) memcpy(ELKS_PTR(void, di), &use, sizeof(use)); + return r; +} + +#define sys_link elks_link +static int elks_link(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("link(%s,%s)\n", ELKS_PTR(char, bx), ELKS_PTR(char, cx))); + return link(ELKS_PTR(char, bx),ELKS_PTR(char, cx)); +} + +#define sys_unlink elks_unlink +static int elks_unlink(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("unlink(%s)\n",ELKS_PTR(char, bx))); + return unlink(ELKS_PTR(char, bx)); +} + +#define sys_chdir elks_chdir +static int elks_chdir(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("chdir(%s)\n",ELKS_PTR(char, bx))); + return chdir(ELKS_PTR(char, bx)); +} + +#define sys_mknod elks_mknod +static int elks_mknod(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("mknod(%s,%d,%d)\n", ELKS_PTR(char, bx),cx,dx)); + return mknod(ELKS_PTR(char, bx),cx,dx); +} + +#define sys_chmod elks_chmod +static int elks_chmod(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("chmod(%s,%d)\n", ELKS_PTR(char, bx),cx)); + return chmod(ELKS_PTR(char, bx), cx); +} + +#define sys_chown elks_chown +static int elks_chown(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("chown(%s,%d,%d)\n", ELKS_PTR(char, bx),cx,dx)); + return chown(ELKS_PTR(char, bx),cx,dx); +} + +#define sys_brk elks_brk +static int elks_brk(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("brk(%d)\n",bx)); + if(bx>=elks_cpu.regs.esp) + { + errno= 1; /* Really return -1 */ + return -1; + } + return 0; /* Can't return bx, 0xBAD1 is an error */ +} + +#define sys_stat elks_stat +static int elks_stat(int bx,int cx,int dx,int di,int si) +{ + struct stat s; + dbprintf(("stat(%s,%d)\n", ELKS_PTR(char, bx), cx)); + if(stat(ELKS_PTR(char, bx),&s)==-1) + return -1; + squash_stat(&s,cx); + return 0; +} + +#define sys_lstat elks_lstat +static int elks_lstat(int bx,int cx,int dx,int di,int si) +{ + struct stat s; + dbprintf(("lstat(%s,%d)\n", ELKS_PTR(char, bx), cx)); + if(lstat(ELKS_PTR(char, bx),&s)==-1) + return -1; + squash_stat(&s,cx); + return 0; +} + +#define sys_lseek elks_lseek +static int elks_lseek(int bx,int cx,int dx,int di,int si) +{ + long l=ELKS_PEEK(long, cx); + + dbprintf(("lseek(%d,%ld,%d)\n",bx,l,dx)); + l = lseek(bx,l,dx); + if( l < 0 ) return -1; + ELKS_POKE(long, cx, l); + return 0; +} + +#define sys_getpid elks_getpid +static int elks_getpid(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("getpid/getppid()\n")); + ELKS_POKE(unsigned short, bx, getppid()); + return getpid(); +} + +#define sys_setuid elks_setuid +static int elks_setuid(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("setuid(%d)\n",bx)); + return setuid(bx); +} + +#define sys_getuid elks_getuid +static int elks_getuid(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("get[e]uid()\n")); + ELKS_POKE(unsigned short, bx, geteuid()); + return getuid(); +} + +#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); +} + +#define sys_fstat elks_fstat +static int elks_fstat(int bx,int cx,int dx,int di,int si) +{ + struct stat s; + int err; + dbprintf(("fstat(%d,%d)\n",bx,cx)); + err=fstat(bx,&s); + squash_stat(&s,cx); + return err; +} + +#define sys_pause elks_pause +static int elks_pause(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("pause()\n")); + return pause(); +} + +#define sys_utime elks_utime +static int elks_utime(int bx,int cx,int dx,int di,int si) +{ + unsigned long *up=ELKS_PTR(long, cx); + struct utimbuf u; + u.actime=*up++; + u.modtime=*up; + return utime(ELKS_PTR(char, bx), &u); +} + +#define sys_access elks_access +static int elks_access(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("access(%s,%d)\n",ELKS_PTR(char, bx),cx)); + return access(ELKS_PTR(char, bx),cx); +} + +#define sys_sync elks_sync +static int elks_sync(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("sync()\n")); + sync(); + return 0; +} + +#define sys_kill elks_kill +static int elks_kill(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("kill(%d,%d)\n",bx,cx)); + return kill(bx,cx); +} + +#define sys_pipe elks_pipe +static int elks_pipe(int bx,int cx,int dx,int di,int si) +{ + unsigned short *dp=ELKS_PTR(unsigned short, bx); + int p[2]; + int err=pipe(p); + if(err==-1) + return err; + *dp++=p[0]; + *dp=p[1]; + return 0; +} + +#define sys_times elks_times +static int elks_times(int bx,int cx,int dx,int di,int si) +{ + struct tms t; + long clock_ticks=times(&t); + long *tp=ELKS_PTR(long, bx); + *tp++=t.tms_utime; + *tp++=t.tms_stime; + *tp++=t.tms_cutime; + *tp=t.tms_cstime; + return 0; /* Should be clock_ticks */ +} + +#define sys_setgid elks_setgid +static int elks_setgid(int bx,int cx,int dx,int di,int si) +{ + return setgid(bx); +} + +#define sys_getgid elks_getgid +static int elks_getgid(int bx,int cx,int dx,int di,int si) +{ + ELKS_POKE(unsigned short, bx, getegid()); + return getgid(); +} + +/* + * Exec is fun. The Minix user library builds a complete elks stack image. + * Great except that we need to unpack it all again and do a real exec. If + * its another elks image then our kernel side binary loader will load + * elksemu again and we'll take the Unix args and turn them back into a + * elks stack image. + * + * For now we run elksemu ourselves and do token attempts at binary checking. + * + * 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) +{ + int fd; + int arg_ct,env_ct; + int ct; + char **argp, **envp; + unsigned short *bp; + unsigned char *base; + unsigned short *tmp; + struct elks_exec_hdr mh; + int is_elks = 1; + + dbprintf(("exec(%s,%d,%d)\n",ELKS_PTR(char, bx), cx, dx)); + + base=ELKS_PTR(unsigned char, cx); + bp=ELKS_PTR(unsigned short, cx+2); + tmp=bp; + + fd=open(ELKS_PTR(char, bx),O_RDONLY); + if(fd==-1) + { errno = ENOENT; return -1; } + if(read(fd, &mh, sizeof(mh))!=sizeof(mh)) + { + close(fd); + errno = ENOEXEC; + return -1; + } + close(fd); + if(mh.hlen!=EXEC_HEADER_SIZE + || (mh.type!=ELKS_COMBID && mh.type!=ELKS_SPLITID)) + is_elks = 0; + + arg_ct = env_ct = 0; + while(*tmp++) + arg_ct++; + while(*tmp++) + env_ct++; + arg_ct+=2; /* elksemu-path progname arg0...argn */ + argp=malloc(sizeof(char *)*(arg_ct+1)); + envp=malloc(sizeof(char *)*(env_ct+1)); + if(!argp||!envp) { errno = ENOMEM; return -1; } + ct=0; + if( is_elks ) + { + argp[0]="/lib/elksemu"; + argp[1]=ELKS_PTR(char, bx); + ct=2; + } + while(*bp) + argp[ct++]=ELKS_PTR(char, cx+ *bp++); + argp[ct]=0; + bp++; + ct=0; + while(*bp) + envp[ct++]=ELKS_PTR(char, cx+ *bp++); + envp[ct]=0; + if( is_elks ) + execve(argp[0],argp,envp); + else + execve(ELKS_PTR(char, bx),argp,envp); + if( errno == ENOEXEC || errno == EACCES ) return -1; + perror("elksemu"); + exit(1); +} + +#define sys_umask elks_umask +static int elks_umask(int bx,int cx,int dx,int di,int si) +{ + return umask(bx); +} + +#define sys_chroot elks_chroot +static int elks_chroot(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("chroot(%s)\n", ELKS_PTR(char, bx))); + return chroot(ELKS_PTR(char, bx)); +} + + +#define sys_fcntl elks_fcntl +static int elks_fcntl(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("fcntl(%d,%d,%d)\n", bx,cx,dx)); + switch(cx) + { + case ELKS_F_GETFD: + return fcntl(bx,F_GETFD,0); + case ELKS_F_GETFL: + return fcntl(bx,F_GETFL,0); + case ELKS_F_DUPFD: + return fcntl(bx,F_DUPFD,dx); + case ELKS_F_SETFD: + return fcntl(bx,F_SETFD,dx); + case ELKS_F_SETFL: + return fcntl(bx,F_SETFL,dx); + /* + * Fixme: Unpack and process elks file locks + */ + case ELKS_F_GETLK: + case ELKS_F_SETLK: + case ELKS_F_SETLKW: + errno = EINVAL; + return -1; + } + errno = EINVAL; + return -1; +} + +#define sys_rename elks_rename +static int elks_rename(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("rename(%s,%s)\n", ELKS_PTR(char, bx), ELKS_PTR(char, cx))); + return rename(ELKS_PTR(char, bx), ELKS_PTR(char, cx)); +} + +#define sys_mkdir elks_mkdir +static int elks_mkdir(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("mkdir(%s,%d)\n", ELKS_PTR(char, bx),cx)); + return mkdir(ELKS_PTR(char, bx),cx); +} + +#define sys_rmdir elks_rmdir +static int elks_rmdir(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("rmdir(%s)\n", ELKS_PTR(char, bx))); + return rmdir(ELKS_PTR(char, bx)); +} + +#define sys_gettimeofday elks_gettimeofday +static int elks_gettimeofday(int bx,int cx,int dx,int di,int si) +{ + struct timeval tv; + struct timezone tz; + int ax; + dbprintf(("gettimeofday(%d,%d)\n",bx,cx)); + + ax = gettimeofday(&tv, &tz); + + if( ax == 0 && bx ) + { + ELKS_POKE(long, bx, tv.tv_sec); + ELKS_POKE(long, bx+4, tv.tv_usec); + } + if( ax == 0 && cx ) + { + ELKS_POKE(short, cx, tz.tz_minuteswest); + ELKS_POKE(short, cx+2, tz.tz_dsttime); + } + return ax?-1:0; +} + +#define sys_settimeofday elks_settimeofday +static int elks_settimeofday(int bx,int cx,int dx,int di,int si) +{ + struct timeval tv, *pv = 0; + struct timezone tz, *pz = 0; + int ax; + dbprintf(("settimeofday(%d,%d)\n",bx,cx)); + + if( bx ) + { + pv = &tv; + tv.tv_sec = ELKS_PEEK(long, bx); + tv.tv_usec = ELKS_PEEK(long, bx+4); + } + if( cx ) + { + pz = &tz; + tz.tz_minuteswest = ELKS_PEEK(short, cx); + tz.tz_dsttime = ELKS_PEEK(short, cx+2); + } + + ax = settimeofday(pv, pz); + return ax?-1:0; +} + +#define sys_nice elks_nice +static int elks_nice(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("nice(%d)\n",bx)); + return nice(bx); +} + +#define sys_symlink elks_symlink +static int elks_symlink(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("symlink(%s,%s)\n", ELKS_PTR(char, bx), ELKS_PTR(char, cx))); + return symlink(ELKS_PTR(char, bx), ELKS_PTR(char, cx)); +} + +#define sys_readlink elks_readlink +static int elks_readlink(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("readlink(%s,%s,%d)\n", + ELKS_PTR(char, bx), + ELKS_PTR(char, cx), + dx)); + return readlink(ELKS_PTR(char, bx), ELKS_PTR(char, cx), dx); +} + +#define sys_ioctl elks_ioctl +static int elks_ioctl(int bx,int cx,int dx,int di,int si) +{ + dbprintf(("ioctl(%d,0x%04x,0x%04x)\n", bx,cx,dx)); + switch((cx>>8)&0xFF) + { + case 'T': return elks_termios(bx,cx,dx,di,si); + default: return elks_enosys(bx,cx,dx,di,si); + } +} + +#define sys_reboot elks_reboot +static int elks_reboot(int bx,int cx,int dx,int di,int si) +{ + errno = EINVAL; + if( bx != 0xfee1 || cx != 0xdead ) return -1; + + switch(dx) + { + /* graceful shutdown, C-A-D off, kill -? 1 */ + case 0: return reboot(0xfee1dead, 672274793, 0); + /* Enable C-A-D */ + case 0xCAD: return reboot(0xfee1dead, 672274793, 0x89abcdef); + /* Time to die! */ + case 0xD1E: return reboot(0xfee1dead, 672274793, 0x1234567); + } + return -1; +} + +/****************************************************************************/ + +static int +elks_opendir(char * dname) +{ + DIR * d; + int rv; + for(rv=0; rv<DIRCOUNT; rv++) + if( dirtab[rv] == 0 ) + break; + if( rv >= DIRCOUNT ) { errno=ENOMEM; return -1; } + d = opendir(dname); + if( d == 0 ) return -1; + dirtab[rv] = d; + return 10000+rv; +} + +static int +elks_readdir(int bx, int cx, int dx) +{ + struct dirent * ent; + + /* Only read _ONE_ _WHOLE_ dirent at a time */ + if( dx != 266 ) + { + errno=EINVAL; return -1; + } + errno = 0; + ent = readdir(dirtab[bx-10000]); + if( ent == 0 ) { if( errno ) { return -1; } else return 0; } + + memcpy(ELKS_PTR(char, cx+10), ent->d_name, ent->d_reclen+1); + ELKS_POKE(long, cx, ent->d_ino); + ELKS_POKE(short, cx+8, ent->d_reclen); + return dx; +} + +static int +elks_closedir(int bx) +{ + bx-=10000; + if( dirtab[bx] ) closedir(dirtab[bx]); + dirtab[bx] = 0; + return 0; +} + +/****************************************************************************/ + +static int elks_termios(int bx,int cx,int dx,int di,int si) +{ + int rv = 0; + switch(cx&0xFF) + { + case 0x01: rv = ioctl(bx, TCGETS, ELKS_PTR(void, dx)); break; + case 0x02: rv = ioctl(bx, TCSETS, ELKS_PTR(void, dx)); break; + case 0x03: rv = ioctl(bx, TCSETSW, ELKS_PTR(void, dx)); break; + case 0x04: rv = ioctl(bx, TCSETSF, ELKS_PTR(void, dx)); break; + + case 0x09: rv = ioctl(bx, TCSBRK, dx); break; + case 0x0A: rv = ioctl(bx, TCXONC, dx); break; + case 0x0B: rv = ioctl(bx, TCFLSH, dx); break; + + default: rv = -1; errno = EINVAL; break; + } + return rv; +} + +/****************************************************************************/ +/* */ +/****************************************************************************/ +#define sys_enosys elks_enosys +static int elks_enosys(int bx,int cx,int dx,int di,int si) +{ + fprintf(stderr, "Function number %d called (%d,%d,%d)\n", + (int)(0xFFFF&elks_cpu.regs.eax), + bx, cx, dx); + errno = ENOSYS; + return -1; +} + +#include "defn_tab.v" +/* * */ + +typedef int (*funcp)(int, int, int, int, int); + +static funcp jump_tbl[] = { +#include "call_tab.v" + elks_enosys +}; + +int elks_syscall(void) +{ + int r, n; + int bx=elks_cpu.regs.ebx&0xFFFF; + int cx=elks_cpu.regs.ecx&0xFFFF; + int dx=elks_cpu.regs.edx&0xFFFF; + int di=elks_cpu.regs.edi&0xFFFF; + int si=elks_cpu.regs.esi&0xFFFF; + + errno=0; + n = (elks_cpu.regs.eax&0xFFFF); + if( n>= 0 && n< sizeof(jump_tbl)/sizeof(funcp) ) + r = (*(jump_tbl[n]))(bx, cx, dx, di, si); + else + return -ENOSYS; + + if(r>=0) + return r; + else + return -errno; +} diff --git a/ld/Makefile b/ld/Makefile index 756a25c..d93579a 100644 --- a/ld/Makefile +++ b/ld/Makefile @@ -1,13 +1,24 @@ -CFLAGS =-O -DBSD_A_OUT -DSTANDARD_GNU_A_OUT -LDFLAGS =-N -s + +ifneq ($(TOPDIR),) +include $(TOPDIR)/Make.defs +else +CC=bcc +LDFLAGS=-s +endif OBJS =dumps.o io.o ld.o readobj.o table.o typeconv.o writebin.o -ld: $(OBJS) +all: ld86 + +ld86: $(OBJS) $(CC) $(LDFLAGS) $(OBJS) -o $@ +install: ld86 + install -d $(LIBDIR) + install -m 755 ld86 $(LIBDIR) + clean: - rm -f $(OBJS) ld + rm -f $(OBJS) ld86 dumps.o: dumps.c const.h config.h obj.h type.h globvar.h io.o: io.c const.h config.h obj.h type.h globvar.h diff --git a/ld/Makefile.minix b/ld/Makefile.minix deleted file mode 100644 index 7f819fa..0000000 --- a/ld/Makefile.minix +++ /dev/null @@ -1,20 +0,0 @@ -CFLAGS =-O -DBSD_A_OUT -LDFLAGS = - -OBJS =dumps.o io.o ld.o readobj.o table.o typeconv.o writebin.o - -ld: $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) -o $@ - chmem =232000 $@ - -clean: - rm -f $(OBJS) ld - -dumps.o: dumps.c const.h config.h obj.h type.h globvar.h -io.o: io.c const.h config.h obj.h type.h globvar.h -ld.o: ld.c const.h config.h byteord.h type.h globvar.h -readobj.o: readobj.c ar.h const.h config.h byteord.h obj.h type.h globvar.h -table.o: table.c const.h config.h align.h obj.h type.h globvar.h -typeconv.o: typeconv.c const.h config.h type.h globvar.h -writebin.o: writebin.c bsd-a.out.h a.out.gnu.h const.h config.h obj.h type.h \ - globvar.h diff --git a/ld/a.out.h b/ld/a.out.h new file mode 100644 index 0000000..f6a7b94 --- /dev/null +++ b/ld/a.out.h @@ -0,0 +1,115 @@ +/* Copyright (C) 1990-1996 + * This file is part of the ld86 command for Linux-86 + * It is distributed under the GNU Library General Public License. + * + * - This may actually be BSD or Minix code, can someone clarify please. -RDB + */ + +#ifndef __AOUT_H +#define __AOUT_H + +struct exec { /* a.out header */ + unsigned char a_magic[2]; /* magic number */ + unsigned char a_flags; /* flags, see below */ + unsigned char a_cpu; /* cpu id */ + unsigned char a_hdrlen; /* length of header */ + unsigned char a_unused; /* reserved for future use */ + unsigned short a_version; /* version stamp (not used at present) */ + 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 */ + long a_entry; /* entry point */ + long a_total; /* total memory allocated */ + long a_syms; /* size of symbol table */ + + /* SHORT FORM ENDS HERE */ + long a_trsize; /* text relocation size */ + long a_drsize; /* data relocation size */ + long a_tbase; /* text relocation base */ + long a_dbase; /* data relocation base */ +}; + +#define A_MAGIC0 (unsigned char) 0x01 +#define A_MAGIC1 (unsigned char) 0x03 +#define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 ||(X).a_magic[1] != A_MAGIC1) + +/* CPU Id of TARGET machine (byte order coded in low order two bits) */ +#define A_NONE 0x00 /* unknown */ +#define A_I8086 0x04 /* intel i8086/8088 */ +#define A_M68K 0x0B /* motorola m68000 */ +#define A_NS16K 0x0C /* national semiconductor 16032 */ +#define A_I80386 0x10 /* intel i80386 */ +#define A_SPARC 0x17 /* Sun SPARC */ + +#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */ +#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ + +/* Flags. */ +#define A_UZP 0x01 /* unmapped zero page (pages) */ +#define A_PAL 0x02 /* page aligned executable */ +#define A_NSYM 0x04 /* new style symbol table */ +#define A_EXEC 0x10 /* executable */ +#define A_SEP 0x20 /* separate I/D */ +#define A_PURE 0x40 /* pure text */ +#define A_TOVLY 0x80 /* text overlay */ + +/* Offsets of various things. */ +#define A_MINHDR 32 +#define A_TEXTPOS(X) ((long)(X).a_hdrlen) +#define A_DATAPOS(X) (A_TEXTPOS(X) + (X).a_text) +#define A_HASRELS(X) ((X).a_hdrlen > (unsigned char) A_MINHDR) +#define A_HASEXT(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 8)) +#define A_HASLNS(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16)) +#define A_HASTOFF(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24)) +#define A_TRELPOS(X) (A_DATAPOS(X) + (X).a_data) +#define A_DRELPOS(X) (A_TRELPOS(X) + (X).a_trsize) +#define A_SYMPOS(X) (A_TRELPOS(X) + (A_HASRELS(X) ? \ + ((X).a_trsize + (X).a_drsize) : 0)) + +struct reloc { + long r_vaddr; /* virtual address of reference */ + unsigned short r_symndx; /* internal segnum or extern symbol num */ + unsigned short r_type; /* relocation type */ +}; + +/* r_tyep values: */ +#define R_ABBS 0 +#define R_RELLBYTE 2 +#define R_PCRBYTE 3 +#define R_RELWORD 4 +#define R_PCRWORD 5 +#define R_RELLONG 6 +#define R_PCRLONG 7 +#define R_REL3BYTE 8 +#define R_KBRANCHE 9 + +/* r_symndx for internal segments */ +#define S_ABS ((unsigned short)-1) +#define S_TEXT ((unsigned short)-2) +#define S_DATA ((unsigned short)-3) +#define S_BSS ((unsigned short)-4) + +struct nlist { /* symbol table entry */ + char n_name[24]; /* symbol name */ + long n_value; /* value */ + unsigned char n_sclass; /* storage class */ + unsigned char n_numaux; /* number of auxiliary entries (not used) */ + unsigned short n_type; /* language base and derived type (not used) */ +}; + +/* Low bits of storage class (section). */ +#define N_SECT 07 /* section mask */ +#define N_UNDF 00 /* undefined */ +#define N_ABS 01 /* absolute */ +#define N_TEXT 02 /* text */ +#define N_DATA 03 /* data */ +#define N_BSS 04 /* bss */ +#define N_COMM 05 /* (common) */ + +/* High bits of storage class. */ +#define N_CLASS 0370 /* storage class mask */ +#define C_NULL +#define C_EXT 0020 /* external symbol */ +#define C_STAT 0030 /* static */ + +#endif /* _AOUT_H */ @@ -3,7 +3,7 @@ /* Copyright (C) 1994 Bruce Evans */ #define FALSE 0 -#define NULL 0 +#define NUL_PTR ((void*)0) #define TRUE 1 #define EXTERN extern @@ -13,7 +13,7 @@ PUBLIC void dumpmods() { struct modstruct *modptr; - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) { putstr(modptr->loadflag ? "L " : " "); putbstr(20, modptr->modname); @@ -31,11 +31,11 @@ PUBLIC void dumpsyms() struct symstruct *symptr; char uflag; - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) + (symptr = *symparray) != NUL_PTR; ++symparray) if (symptr->modptr == modptr) { uflag = FALSE; diff --git a/ld/include/fcntl.h b/ld/include/fcntl.h new file mode 100644 index 0000000..8c1ec8b --- /dev/null +++ b/ld/include/fcntl.h @@ -0,0 +1,2 @@ +#define O_RDONLY 0 +#define O_WRONLY 1 @@ -6,20 +6,19 @@ #include "obj.h" /* needed for LONG_OFFSETS and offset_t */ #include "type.h" #include "globvar.h" +#include <fcntl.h> #ifdef STDC_HEADERS_MISSING void exit P((int status)); void *malloc P((unsigned size)); #else -#undef NULL #include <stdlib.h> #endif #ifdef POSIX_HEADERS_MISSING -#define O_RDONLY 0 -#define O_WRONLY 1 #define SEEK_SET 0 #define STDOUT_FILENO 0 +#include <sys/types.h> #include <sys/stat.h> #define mode_t unsigned short #define off_t long @@ -33,7 +32,6 @@ int read P((int fd, void *buf, unsigned nbytes)); mode_t umask P((int oldmask)); int write P((int fd, const void *buf, unsigned nbytes)); #else -#undef NULL #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -46,6 +44,9 @@ int write P((int fd, const void *buf, unsigned nbytes)); #define INBUFSIZE 1024 #define OUTBUFSIZE 2048 #define TRELBUFSIZE 1024 +#ifndef O_BINARY +#define O_BINARY 0 +#endif #ifdef BSD_A_OUT PRIVATE char *drelbuf; /* extra output buffer for data relocations */ @@ -197,7 +198,7 @@ char *filename; { closein(); inputname = filename; /* this relies on filename being static */ - if ((infd = open(filename, O_RDONLY)) < 0) + if ((infd = open(filename, O_BINARY|O_RDONLY)) < 0) inputerror("cannot open"); inbufptr = inbufend = inbuf; } @@ -209,7 +210,7 @@ char *filename; struct stat statbuf; outputname = filename; - if ((outfd = creat(filename, CREAT_PERMS)) == ERR) + if ((outfd = open(filename, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, CREAT_PERMS)) == ERR) outputerror("cannot open"); if (fstat(outfd, &statbuf) != 0) outputerror("cannot stat"); @@ -220,7 +221,7 @@ char *filename; #endif outbufptr = outbuf; #ifdef BSD_A_OUT - if ((trelfd = open(filename, O_WRONLY)) == ERR) + if ((trelfd = open(filename, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, CREAT_PERMS)) == ERR) outputerror("cannot reopen"); trelbufptr = trelbuf; #endif @@ -528,7 +529,7 @@ char *defarchentry; putstr(message); putstr(" in file "); putstr(inputname); - if (archentry != NULL) + if (archentry != NUL_PTR) { putbyte('('); putstr(archentry); @@ -536,7 +537,7 @@ char *defarchentry; } putstr("; using definition in "); putstr(deffilename); - if (defarchentry != NULL) + if (defarchentry != NUL_PTR) { putbyte('('); putstr(defarchentry); @@ -560,7 +561,7 @@ char *name; } PUBLIC void size_error(seg, count, size) -char seg; +int seg; offset_t count; offset_t size; { @@ -12,7 +12,6 @@ extern int errno; char *strcat P((char *dest, const char *src)); unsigned long strtoul P((const char *s, char **endptr, int base)); #else -#undef NULL #include <errno.h> #include <stdlib.h> #include <string.h> @@ -22,23 +21,23 @@ unsigned long strtoul P((const char *s, char **endptr, int base)); #define R_OK 0 int access P((const char *path, int amode)); #else -#undef NULL #include <unistd.h> #endif #define MAX_LIBS (NR_STDLIBS + 5) +#ifdef MC6809 #define NR_STDLIBS 1 +#else +#define NR_STDLIBS 0 +#endif PUBLIC long text_base_address; /* XXX */ +PUBLIC int doscomfile = 0; PRIVATE bool_t flag[128]; PRIVATE char *libs[MAX_LIBS] = { #ifdef MC6809 "/usr/local/lib/m09/", -#else - /* One of the following values will be inserted at run time. */ -# define std386lib "/usr/local/lib/i386/" -# define std86lib "/usr/local/lib/i86/" #endif 0 }; @@ -67,10 +66,6 @@ char *fn; char *path; int i; -#ifndef MC6809 - libs[0] = flag['3'] ? std386lib : std86lib; -#endif - for (i = lastlib - 1; i >= 0; --i) { path = ourmalloc(strlen(libs[i]) + strlen(fn) + 1); @@ -80,7 +75,7 @@ char *fn; return path; ourfree(path); } - return NULL; + return NUL_PTR; } PUBLIC int main(argc, argv) @@ -104,7 +99,7 @@ char **argv; #ifndef MC6809 flag['z'] = flag['3'] = sizeof(char *) >= 4; #endif - outfilename = NULL; + outfilename = NUL_PTR; for (argn = 1; argn < argc; ++argn) { arg = argv[argn]; @@ -133,9 +128,17 @@ char **argv; if (arg[1] == '0') /* flag 0 is negative logic flag 3 */ flag['3'] = !flag['0']; break; + case 'd': /* Make DOS com file */ + flag['3'] = FALSE; + flag['z'] = FALSE; + flag['0'] = TRUE; + flag['s'] = TRUE; + flag['d'] = TRUE; + text_base_address = 0x100; + break; case 'C': /* startfile name */ tfn = buildname(crtprefix, arg + 2, crtsuffix); - if ((infilename = expandlib(tfn)) == NULL) + if ((infilename = expandlib(tfn)) == NUL_PTR) fatalerror(tfn); /* XXX - need to describe failure */ readsyms(infilename, flag['t']); break; @@ -146,7 +149,7 @@ char **argv; fatalerror("too many library paths"); break; case 'O': /* library file name */ - if ((infilename = expandlib(arg + 2)) == NULL) + if ((infilename = expandlib(arg + 2)) == NUL_PTR) fatalerror(arg); /* XXX */ readsyms(infilename, flag['t']); break; @@ -154,18 +157,18 @@ char **argv; if (arg[2] != 0 || ++argn >= argc) usage(); errno = 0; - text_base_address = strtoul(argv[argn], (char **) NULL, 16); + text_base_address = strtoul(argv[argn], (char **) NUL_PTR, 16); if (errno != 0) use_error("invalid text address"); break; case 'l': /* library name */ tfn = buildname(libprefix, arg + 2, libsuffix); - if ((infilename = expandlib(tfn)) == NULL) + if ((infilename = expandlib(tfn)) == NUL_PTR) fatalerror(tfn); /* XXX */ readsyms(infilename, flag['t']); break; case 'o': /* output file name */ - if (arg[2] != 0 || ++argn >= argc || outfilename != NULL) + if (arg[2] != 0 || ++argn >= argc || outfilename != NUL_PTR) usage(); outfilename = argv[argn]; break; @@ -173,8 +176,9 @@ char **argv; usage(); } } + doscomfile = flag['d']; linksyms(flag['r']); - if (outfilename == NULL) + if (outfilename == NUL_PTR) outfilename = "a.out"; writebin(outfilename, flag['i'], flag['3'], flag['s'], flag['z'] & flag['3']); diff --git a/ld/readobj.c b/ld/readobj.c index 791436f..bb6a6b5 100644 --- a/ld/readobj.c +++ b/ld/readobj.c @@ -14,7 +14,6 @@ int strncmp P((const char *s1, const char *s2, unsigned n)); char *strncpy P((char *dest, const char *src, unsigned n)); unsigned long strtoul P((const char *s, char **endptr, int base)); #else -#undef NULL #include <stdlib.h> #include <string.h> #endif @@ -51,9 +50,9 @@ FORWARD unsigned segbits P((unsigned seg, char *sizedesc)); PUBLIC void objinit() { - modfirst = modlast = NULL; - entryfirst = entrylast = NULL; - redfirst = redlast = NULL; + modfirst = modlast = NUL_PTR; + entryfirst = entrylast = NUL_PTR; + redfirst = redlast = NUL_PTR; } /* read all symbol definitions in an object file */ @@ -76,7 +75,7 @@ bool_pt trace; case OMAGIC: seekin((unsigned long) 0); for (modcount = readfileheader(); modcount-- != 0;) - readmodule(filename, (char *) NULL); + readmodule(filename, (char *) NUL_PTR); break; default: seekin((unsigned long) 0); @@ -118,7 +117,7 @@ char **parchentry; do *endptr = 0; while (endptr > nameptr && *--endptr == ' '); - return strtoul(arheader.ar_size, (char **) NULL, 0); + return strtoul(arheader.ar_size, (char **) NUL_PTR, 0); } /* read and check file header of the object file just opened */ @@ -185,7 +184,7 @@ char *archentry; { symname = readstring(); if ((flags = symdptr->dflags) & (E_MASK | I_MASK) && - (symptr = findsym(symname)) != NULL) + (symptr = findsym(symname)) != NUL_PTR) { /* weaken segment-checking by letting the maximum segment @@ -220,7 +219,7 @@ char *archentry; if (flags & N_MASK) entrysym(symptr); } - *symparray = NULL; + *symparray = NUL_PTR; } /* put symbol on entry symbol list if it is not already */ @@ -230,13 +229,13 @@ struct symstruct *symptr; { register struct entrylist *elptr; - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) + for (elptr = entryfirst; elptr != NUL_PTR; elptr = elptr->elnext) if (symptr == elptr->elsymptr) return; elptr = (struct entrylist *) ourmalloc(sizeof(struct entrylist)); - elptr->elnext = NULL; + elptr->elnext = NUL_PTR; elptr->elsymptr = symptr; - if (entryfirst == NULL) + if (entryfirst == NUL_PTR) entryfirst = elptr; else entrylast->elnext = elptr; @@ -263,7 +262,7 @@ PRIVATE void reedmodheader() readin((char *) &modheader, sizeof modheader); modptr = (struct modstruct *) ourmalloc(sizeof(struct modstruct)); - modptr->modnext = NULL; + modptr->modnext = NUL_PTR; modptr->textoffset = c4u4(modheader.htextoffset); modptr->class = modheader.hclass; readin(modptr->segmaxsize, sizeof modptr->segmaxsize); @@ -281,7 +280,7 @@ PRIVATE void reedmodheader() cptr += count; } } - if (modfirst == NULL) + if (modfirst == NUL_PTR) modfirst = modptr; else modlast->modnext = modptr; @@ -298,11 +297,11 @@ offset_t value; if (symptr->modptr->class != (class = modlast->class)) for (rlptr = redfirst;; rlptr = rlptr->rlnext) { - if (rlptr == NULL) + if (rlptr == NUL_PTR) { rlptr = (struct redlist *) ourmalloc(sizeof(struct redlist)); - rlptr->rlnext = NULL; + rlptr->rlnext = NUL_PTR; rlptr->rlsymptr = symptr; if (symptr->modptr->class < class) /* prefer lower class - put other on redlist */ @@ -317,7 +316,7 @@ offset_t value; rlptr->rlvalue = symptr->value; symptr->value = value; } - if (redfirst == NULL) + if (redfirst == NUL_PTR) redfirst = rlptr; else redlast->rlnext = rlptr; @@ -10,9 +10,10 @@ #ifdef STDC_HEADERS_MISSING void *malloc P((unsigned size)); +char * strcpy P((char* dest, char* src)); #else -#undef NULL #include <stdlib.h> +#include <string.h> #endif #define GOLDEN 157 /* GOLDEN/HASHTABSIZE approx golden ratio */ @@ -32,13 +33,13 @@ PUBLIC void syminit() for (i = sizeof(int) <= 2 ? 0xE000 : (unsigned) 0x38000; i != 0; i -= 512) - if ((tableptr = malloc(i)) != NULL) + if ((tableptr = malloc(i)) != NUL_PTR) break; - if (tableptr == NULL) + if (tableptr == NUL_PTR) outofmemory(); tableend = tableptr + i; for (i = 0; i < HASHTABSIZE; i++) - hashtab[i] = NULL; + hashtab[i] = NUL_PTR; } /* add named symbol to end of table - initialise only name and next fields */ @@ -48,12 +49,12 @@ PUBLIC struct symstruct *addsym(name) char *name; { struct symstruct **hashptr; - struct symstruct *oldsymptr; + struct symstruct *oldsymptr = 0; struct symstruct *symptr; hashptr = gethashptr(name); symptr = *hashptr; - while (symptr != NULL) + while (symptr != NUL_PTR) { oldsymptr = symptr; symptr = symptr->next; @@ -62,11 +63,11 @@ char *name; symptr = (struct symstruct *) tableptr; if ((tableptr = symptr->name + (strlen(name) + 1)) > tableend) outofmemory(); - symptr->modptr = NULL; - symptr->next = NULL; + symptr->modptr = NUL_PTR; + symptr->next = NUL_PTR; if (name != symptr->name) strcpy(symptr->name, name); /* should't happen */ - if (*hashptr == NULL) + if (*hashptr == NUL_PTR) *hashptr = symptr; else oldsymptr->next = symptr; @@ -81,7 +82,7 @@ char *name; struct symstruct *symptr; symptr = *gethashptr(name); - while (symptr != NULL && (!(symptr->flags & (E_MASK | I_MASK)) || + while (symptr != NUL_PTR && (!(symptr->flags & (E_MASK | I_MASK)) || strcmp(symptr->name, name) != 0)) symptr = symptr->next; return symptr; diff --git a/ld/writebin.c b/ld/writebin.c index a95280c..3e7602d 100644 --- a/ld/writebin.c +++ b/ld/writebin.c @@ -27,7 +27,11 @@ static long bdataoffset; # define n_was_strx n_un.n_strx # define n_was_type n_desc # else /* not BSD_A_OUT */ -# include "a.out.h" /* maybe local copy of <a.out.h> for X-link */ +# ifdef MSDOS +# include "a_out.h" +# else +# include "a.out.h" /* maybe local copy of <a.out.h> for X-link */ +# endif # define n_was_name n_name # define n_was_numaux n_numaux # define n_was_other n_other @@ -46,7 +50,6 @@ static long bdataoffset; #ifdef STDC_HEADERS_MISSING void *memset P((void *s, int c, unsigned n)); #else -#undef NULL #include <string.h> #endif @@ -58,10 +61,10 @@ void *memset P((void *s, int c, unsigned n)); # ifdef STANDARD_GNU_A_OUT # define FILEHEADERLENGTH 32 # else -# define FILEHEADERLENGTH 48 +# define FILEHEADERLENGTH (doscomfile?0:48) # endif # else -# define FILEHEADERLENGTH A_MINHDR +# define FILEHEADERLENGTH (doscomfile?0:A_MINHDR) /* part of header not counted in offsets */ # endif #endif @@ -139,6 +142,8 @@ FORWARD void writeheader P((void)); #endif FORWARD void writenulls P((offset_t count)); +extern int doscomfile; + /* link all symbols connected to entry symbols */ PUBLIC void linksyms(argreloc_output) @@ -153,31 +158,31 @@ bool_pt argreloc_output; reloc_output = argreloc_output; if (argreloc_output) { - if (modfirst->modnext != NULL) + if (modfirst->modnext != NUL_PTR) fatalerror("relocatable output only works for one input file"); - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) modptr->loadflag = TRUE; return; } #endif - if ((symptr = findsym("_main")) != NULL) + if ((symptr = findsym("_main")) != NUL_PTR) entrysym(symptr); do { - if ((elptr = entryfirst) == NULL) + if ((elptr = entryfirst) == NUL_PTR) fatalerror("no start symbol"); - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) modptr->loadflag = FALSE; - for (; elptr != NULL; elptr = elptr->elnext) + for (; elptr != NUL_PTR; elptr = elptr->elnext) linkrefs(elptr->elsymptr->modptr); - if ((symptr = findsym("start")) != NULL) + if ((symptr = findsym("start")) != NUL_PTR) linkrefs(symptr->modptr); needlink = FALSE; { - struct redlist *prlptr; + struct redlist *prlptr = 0; struct redlist *rlptr; - for (rlptr = redfirst; rlptr != NULL; + for (rlptr = redfirst; rlptr != NUL_PTR; rlptr = (prlptr = rlptr)->rlnext) if (rlptr->rlmodptr->loadflag && rlptr->rlmodptr->class > rlptr->rlsymptr->modptr->class) @@ -233,9 +238,9 @@ bool_pt arguzp; } #ifdef EDOS commandname = stralloc(outfilename); - if ((cptr = strchr(commandname, ':')) != NULL) + if ((cptr = strchr(commandname, ':')) != NUL_PTR) commandname = cptr + 1; - if ((cptr = strrchr(commandname, '.')) != NULL) + if ((cptr = strrchr(commandname, '.')) != NUL_PTR) *cptr = 0; #endif @@ -261,18 +266,19 @@ bool_pt arguzp; symres("__end"); curseg = 0; /* text seg, s.b. variable */ symres("__etext"); + symres("__segoff"); /* calculate segment and common sizes (sum over loaded modules) */ /* use zero init of segsz[] */ /* also relocate symbols relative to starts of their segments */ - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { register struct symstruct **symparray; register struct symstruct *symptr; for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) + (symptr = *symparray) != NUL_PTR; ++symparray) if (symptr->modptr == modptr && !(symptr->flags & A_MASK)) { if (!(symptr->flags & (I_MASK | SA_MASK))) @@ -363,14 +369,14 @@ bool_pt arguzp; } /* relocate symbols by offsets of segments in memory */ - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { register struct symstruct **symparray; register struct symstruct *symptr; for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) + (symptr = *symparray) != NUL_PTR; ++symparray) if (symptr->modptr == modptr && !(symptr->flags & A_MASK)) { if (symptr->flags & (C_MASK | SA_MASK)) @@ -414,6 +420,7 @@ bool_pt arguzp; setsym("__etext", etextoffset); setsym("__edata", edataoffset); setsym("__end", endoffset = combase[NSEG - 1] + comsz[NSEG - 1]); + setsym("__segoff", (offset_t)(segadj[1]-segadj[0])/0x10); openout(outfilename); #ifdef BSD_A_OUT @@ -427,7 +434,7 @@ bool_pt arguzp; #else writeheader(); #endif - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { linkmod(modptr); @@ -453,21 +460,21 @@ bool_pt arguzp; #ifdef BSD_A_OUT stringoff = 4; #endif - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { register struct symstruct **symparray; register struct symstruct *symptr; for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) + (symptr = *symparray) != NUL_PTR; ++symparray) if (symptr->modptr == modptr) { #ifdef BSD_A_OUT offtocn((char *) &extsym.n_was_strx, (offset_t) stringoff, 4); #else - strncpy((char *) &extsym.n_was_name, symptr->name, + strncpy((char *) extsym.n_was_name, symptr->name, sizeof extsym.n_was_name); #endif u4cn((char *) &extsym.n_value, (u4_t) symptr->value, @@ -506,14 +513,14 @@ bool_pt arguzp; #ifdef BSD_A_OUT offtocn((char *) &extsym.n_was_strx, (offset_t) stringoff, 4); writeout((char *) &extsym.n_was_strx, 4); - for (modptr = modfirst; modptr != NULL; modptr = modptr->modnext) + for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { register struct symstruct **symparray; register struct symstruct *symptr; for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) + (symptr = *symparray) != NUL_PTR; ++symparray) if (symptr->modptr == modptr) writeout(symptr->name, strlen(symptr->name) + 1); } @@ -553,12 +560,12 @@ char *commandname; count = 2 + 2 + 1; /* len len nul */ startptr = findsym("start"); - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) + for (elptr = entryfirst; elptr != NUL_PTR; elptr = elptr->elnext) { name = idconvert(elptr, commandname); count += strlen(name) + 1 + 2 + 1; /* nul off flg */ ourfree(name); - if (startptr != NULL) + if (startptr != NUL_PTR) count += 6; /* LBSR $xxxx and LBRA $xxxx */ } return count; @@ -772,7 +779,7 @@ struct modstruct *modptr; modptr->loadflag = TRUE; for (symparray = modptr->symparray; - (symptr = *symparray) != NULL; ++symparray) + (symptr = *symparray) != NUL_PTR; ++symparray) if (symptr->modptr->loadflag == FALSE) linkrefs(symptr->modptr); } @@ -815,7 +822,7 @@ offset_t value; #ifdef BSD_A_OUT if (!reloc_output) #endif - if ((symptr = findsym(name)) != NULL) + if ((symptr = findsym(name)) != NUL_PTR) symptr->value = value; } @@ -824,7 +831,7 @@ register char *name; { register struct symstruct *symptr; - if ((symptr = findsym(name)) != NULL) + if ((symptr = findsym(name)) != NUL_PTR) { if ((symptr->flags & SEGM_MASK) == SEGM_MASK) symptr->flags &= ~SEGM_MASK | curseg; @@ -870,7 +877,7 @@ char *commandname; struct symstruct *startptr; headlength = binheaderlength(commandname); - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) + for (elptr = entryfirst; elptr != NUL_PTR; elptr = elptr->elnext) headlength -= 6; offset = headlength; startptr = findsym("start"); @@ -878,21 +885,21 @@ char *commandname; writeout(buf, 2); writechar(0xFF); /* dummy data length 0xFFFF takes everything */ writechar(0xFF); - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) + for (elptr = entryfirst; elptr != NUL_PTR; elptr = elptr->elnext) { name = idconvert(elptr, commandname); writeout(name, (unsigned) strlen(name) + 1); ourfree(name); - offtocn(buf, startptr == NULL ? elptr->elsymptr->value : offset, 2); + offtocn(buf, startptr == NUL_PTR ? elptr->elsymptr->value : offset, 2); writeout(buf, 2); writechar(0x82); /* 8 = set flags from here, 2 = cmd line */ offset += 6; /* LBSR $xxxx and LBRA $xxxx */ } writechar(0); - if (startptr != NULL) + if (startptr != NUL_PTR) { offset = headlength + 3; /* over 1st LBSR */ - for (elptr = entryfirst; elptr != NULL; elptr = elptr->elnext) + for (elptr = entryfirst; elptr != NUL_PTR; elptr = elptr->elnext) { writechar(0x17); /* LBSR */ offtocn(buf, startptr->value - offset, 2); @@ -975,7 +982,8 @@ PRIVATE void writeheader() sizeof header.a_total); #endif } - writeout((char *) &header, FILEHEADERLENGTH); + if( FILEHEADERLENGTH ) + writeout((char *) &header, FILEHEADERLENGTH); } #endif /* MINIX */ diff --git a/libc-0.0.4/COPYING b/libc-0.0.4/COPYING new file mode 100644 index 0000000..eb685a5 --- /dev/null +++ b/libc-0.0.4/COPYING @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/libc-0.0.4/Changes b/libc-0.0.4/Changes new file mode 100644 index 0000000..8cd0a84 --- /dev/null +++ b/libc-0.0.4/Changes @@ -0,0 +1,127 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library which is distributed +# under the GNU Library General Public License. + +If you make any changes please put a little note here. -RDB + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +----- Mar 18 '96 - RDB +Re-written to wetware storage "Robert must remember to fill in changes!" +Ok, there's now some makefiles in the directory above for creating an +environment with cleanup of bcc/as/ld makefiles and new home for bcc files. +My version of a standard I/O package has been added, I've split the +output libs for Linux-86 and MSDOS. +(Now need small mod to bcc to accept '-d' as '-d -D__MSDOS__ -ldos') +A couple of functions (including reboot) added to elksemu. +----- Mar 3 '96 - RDB +open/close in doselks +----- Feb 25 '96 - RDB +iota.c - oops -ve numbers give infinite loop +altered a.out.h changed size of n_name from 8 to 24, ld needs recompile, +dis88 bombed (bad malloc), nm etc will need to know. +added popen, pclose, system +----- Feb 24 '96 - RDB +Problem with __lseek syscall, was trying to return a long - no way jose +Little change to malloc1/* if you #define __MINI_MALLOC__ (used in LIB) +a _much_ smaller but more limited version of malloc is used. +Added assert.h - no __assert() in lib yet. +Added in printf c/o Steven Huang <sthuang@hns.com>. +ELKSemu; added -Wall, cleaned up mess. +----- Feb 23 '96 - RDB +Release 0.0.3, bump version to 0.0.4 +----- Feb 18 '96 - RDB +ELKSemu signals now seem to be working. +ELKSemu; Added symlinks +ELKSemu; Added opendir support +ELKSemu; now runs as ELF executable +Added exec* functions except exec*p ones +Small cleanup of doselks. +Start final checks for 0.0.3 +----- Feb 16 '96 - RDB +I do _NOT_ believe this - sbrk() yet again!! RIGHT! This time it WILL work!! +Groan! There was no problem with sbrk, it was elksemu :-( fixed! +----- Feb 12 '96 - RDB +Yet another problem with sbrk() return val wrong! - FIXed +Alter elksemu change in way *_tab.v files work. +----- Feb 11 '96 - RDB +Fix on strchr (asm86) - SI not saved +First cut at opendir/readdir/closedir +Move in ar.h +add in 'make config' - (split malloc's and options for stdio packages) +Merge in Nat's grp and other pieces. +ELKSemu; Little i386 kernel patch, i8086 programs now run transparently :-) +----- Feb 10 '96 - RDB +Found a _nasty_ bug with atexit; the actual problem was in cstartup but ... +----- Feb 4 '96 - RDB +Corrected minor problem in atexit/on_exit +----- Jan 28 '96 - RDB +Debug, execve in libc _and_ elksemu +perror added +----- Jan 27 '96 - RDB +Debug pwd, pw_fd was static +Started modifing syscall.dat, adjusting elksemu to match. +----- Jan 21 '96 - RDB +Altered fflush to test return status. Corrected porting bug in printf.c +----- Jan 20 '96 - RDB +Imported printf from the 'DLibs' library, I've now found the rest of the +Dlibs stdio, it appears to be very ST specific tho :-( +NB: This is not in the dist, still sending out Joel's +----- Jan 19 '96 - RDB +Making some test alterations to stdio. +Made ungetc into function, removed ungetc specific structure items +Altered putc() to micro-macro. +----- Jan 16 '96 - RDB +Added in patches from Nat, corrected minor oops in misc/alias.c +----- Jan 11 '96 - RDB +Final checks, release version 0.0.2 +----- Jan 9 '96 - RDB +Added 'signal' function. +Added 'setjmp' Is it right for SI & DI to be saved ? +----- Jan 8 '96 - RDB +Added various MS-DOS functions, COM files are now starting to be able to +do something useful. +----- Jan 7 '96 - RDB +Added the 'New_subdir' script. +Now YOU (Yes I mean you reading this!) can use it :-) +----- Jan 6 '96 - RDB +Problem with sbrk() shown up by Joel's malloc, the error checks failed if +you were allocating big blocks, fixed. +----- Jan 6 '96 - RDB +Added in Joel's malloc routine after a solid hack to actually debug it +it seems to work now but I haven't really tested it; I can't do it under +x386 Linux as something tried to link in 'realloc' too. +----- Jan 5 '96 - RDB +Ok, I've messed around and joined in Joel's stdio.h routines +----- Jan 3 '96 - RDB +(This is a good idea, dates, Always overlook the little things, ho hum!) +----- - RDB +Added 'movedata' function like MSC version to string/string.h +----- - RDB +Added support for the -C-f and -C-c options of BCC. BUT note for the moment +the string functions degenerate to the C versions for -C-f +----- - RDB +Added getenv/putenv +----- - RDB +Changed crt0.c. It now only jmps to ___cstartup. This is so the same crt0 +can be used for both DOS and Linux, only the libc needs to be changed. +Cost is 4 bytes at the start of the exe. +----- - RDB +Added support for automatic calling of functions before main. (See Pre_main) +Added support for atexit() and onexit() functions. +----- - RDB +Added fast strchr +Altered strstr to use strchr. +----- - RDB +Added cputype function - CPU detector. +----- - RDB +Dec 12 95 +Just completed a working debugged malloc set _including_ a 'fake' alloca +function. (The assembler version will not work for BCC) It's a classical +algorthm so may be slow in some cases. I had a look at the GNU malloc ... +erm ... I _think_ I see what they're doing! :-) +----- - RDB +Added tiny printf, to be replaced by Joel. +Added HP-UX long->ascii function. +----- - RDB +Split off brk/sbrk etc into own file. Asm alloca not compiled. diff --git a/libc-0.0.4/Contributors b/libc-0.0.4/Contributors new file mode 100644 index 0000000..d96193d --- /dev/null +++ b/libc-0.0.4/Contributors @@ -0,0 +1,8 @@ +Alan Cox <alan@cymru.net> +Bruce Evans <bde@FreeBSD.org> +Chad Page <page0588@sundance.sjsu.edu> +Dale Schumacher <dal@syntel.UUCP> +Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> +Nat Friedman <ndf@aleph1.mit.edu> +Robert de Bath <rdebath@cix.compulink.co.uk> +Steven Huang <sthuang@hns.com> diff --git a/libc-0.0.4/KERNEL b/libc-0.0.4/KERNEL new file mode 100644 index 0000000..6f83f90 --- /dev/null +++ b/libc-0.0.4/KERNEL @@ -0,0 +1,37 @@ + +KERNEL SYSTEM CALL INTERFACE: +The kernel system calls are all done through interrupt 0x80 +All parameters are passed in the 'AX,BX,CX,DX,DI,SI' registers. +The AX register contains the system call number. +The BX,CX,DX,DI,SI registers contain the first 5 arguments from the stack. +(NB If the syscall is know to have less than 5 args the rest are not loaded) +On return from the syscall AX has the return value. +If AX is -ve then errno= -AX and return val = -1; + +The system calls are named in syscall/syscall.dat. +There is a script syscall/mksyscall which generates the assembler for the +system calls, near the top there is a line: + COMPACT=1 +If this is changed to + COMPACT=0 +the code generated will be slightly faster and larger. + +-RDB + +KERNEL SIGNAL INTERFACE: + It is assumed the kernel will never pass a signal to the userspace + routine unless it's _explicitly_ asked for! + +The Kernel need only save space for _one_ function pointer +(to system_signal) and must deal with SIG_DFL and SIG_IGN +in kernel space. + +When a signal is required the kernel must set all the registers as if +returning from a interrupt normally then push the number of the signal +to be generated, push the current pc value, then set the pc to the +address of the 'system_signal' function. + +This is in syscall/signal.c + +-RDB + diff --git a/libc-0.0.4/MAGIC b/libc-0.0.4/MAGIC new file mode 100644 index 0000000..69c9c2d --- /dev/null +++ b/libc-0.0.4/MAGIC @@ -0,0 +1,23 @@ +Useful bits for /etc/magic: + +#------------------------------------------------------------------------------ +# Localstuff: file(1) magic for locally observed files +# +# $Id: Localstuff,v 1.3 1995/01/21 21:09:00 christos Exp $ +# Add any locally observed files here. Remember: +# text if readable, executable if runnable binary, data if unreadable. +# +0 string \01\03\020\04 Linux-8086 impure executable +>16 long !0 not stripped +0 string \01\03\040\04 Linux-8086 executable +>16 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 +# +0 string \01\03\020\20 Minix-386 impure executable +>16 long !0 not stripped +0 string \01\03\040\20 Minix-386 executable +>16 long !0 not stripped +# +#------------------------------------------------------------------------------ diff --git a/libc-0.0.4/Make.defs b/libc-0.0.4/Make.defs new file mode 100644 index 0000000..b960852 --- /dev/null +++ b/libc-0.0.4/Make.defs @@ -0,0 +1,64 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +# Set PLATFORM to i386-Linux to build for Linux/386 and to i86-ELKS to +# build for ELKS. This doesn't quite work yet, though, because of some of +# the platform and/or compiler-specific code flying around here. +# Eventually, compiler-specificity won't be an issue, and we can put +# platform-specific code in i86/ and i386/. -Nat + +# Define enviroment var for others. +ifeq ($(PLATFORM),) +PLATFORM=i86-ELKS +#PLATFORM=i86-DOS +#PLATFORM=i386-Linux +endif + +VERMAJOR=0 +VERMINOR=0 +VERPATCH=4 +VER=$(VERMAJOR).$(VERMINOR).$(VERPATCH) + +LIBDEFS=-D__LIBC__ +LIBC=libc.a + +ifneq ($(PLATFORM),i386-Linux) + +# Normal standard 8086 code +ifeq ($(PLATFORM),i86-ELKS) +ARCH=-0 + +# 8086 elks code With "Caller saves" and "First arg in AX" +# ARCH=-0 -C-c -C-f +endif + +# MSDOS COM file (msdos libs don't support "First arg in AX") +ifeq ($(PLATFORM),i86-DOS) +ARCH=-0 -d -D__MSDOS__ +LIBC=libdos.a +endif + +# BCC 386. +ifeq ($(PLATFORM),i386-BCC) +ARCH=-3 +endif + +CC=bcc $(ARCH) +CCFLAGS=-O -I -I$(TOP)/include +LKFLAGS=-L -L$(TOP)/ -s + +else # ifeq ($(PLATFORM),i386-Linux) + +CC=gcc $(ARCH) +# ARCH=-b i486-linuxaout +LKFLAGS=-static -N +CCFLAGS=-O6 -fomit-frame-pointer -I- -I$(TOP)/include -I. -fno-builtin +WALL= -ansi -pedantic -Wwrite-strings -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \ + -Wnested-externs -Winline -Wshadow + +endif # ifeq ($(PLATFORM),i386-Linux) + +CFLAGS=$(CCFLAGS) $(LIBDEFS) +LDFLAGS=$(LKFLAGS) diff --git a/libc-0.0.4/Makefile b/libc-0.0.4/Makefile new file mode 100644 index 0000000..7b233bd --- /dev/null +++ b/libc-0.0.4/Makefile @@ -0,0 +1,71 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=. +include $(TOP)/Make.defs + +SRC=crt0.c +OBJ=crt0.o + +TARGETS=$(OBJ) $(LIBC) +TXT=COPYING Changes Contributors MAGIC \ + Make.defs Makefile New_subdir Pre_main README TODO KERNEL + +all: $(TARGETS) + +install: all + install -d $(BCCHOME) + rm -rf $(BCCHOME)/include + ln -s $(TOPDIR)/libc/include $(BCCHOME)/include + install -d $(LIBDIR)/i86 + install -m 644 crt0.o $(LIBDIR)/i86 + install -m 644 $(LIBC) $(LIBDIR)/i86 + -install -m 644 error/liberror.txt /usr/lib + +tests: dummy + make -C tests + +$(LIBC): transfer + for i in */Makefile ; do \ + make -C `dirname $$i` $@ || exit 1 ; \ + done + +realclean: clean + rm -f $(OBJ) $(LIBC) libc-$(VER) + @for i in */makefile ; do \ + grep -q '^clean:' $$i && make -C `dirname $$i` clean ; \ + done ; echo -n + +clean: dummy + for i in */Makefile ; do \ + make -C `dirname $$i` $@ || exit 1 ; \ + done + +config: + sh Config.sh + @for i in */Makefile ; do \ + [ -f `dirname $$i`/Config.sh ] && \ + sh `dirname $$i`/Config.sh ] ; \ + done ; echo -n + +dist: clean + tar cf temp.tar \ + $(TXT) $(TARGETS) $(SRC) include \ + `for i in */Makefile */Config; do dirname $$i; done | sort -u` + rm -rf libc-$(VER) + mkdir libc-$(VER) ; cd libc-$(VER) ; tar xf ../temp.tar + tar czf libc-8086-$(VER).tar.gz libc-$(VER) + rm -rf libc-$(VER) temp.tar + +dist_ver: dist + mv libc-8086-$(VER).tar.gz .. + echo $(VER) > ../Libc_version + +transfer: dummy + @echo Checking for transfers + @for i in */Makefile ; do \ + grep -q '^transfer' $$i && make -C `dirname $$i` $@ ; \ + done ; echo -n + +dummy: diff --git a/libc-0.0.4/New_subdir b/libc-0.0.4/New_subdir new file mode 100755 index 0000000..a10ccf7 --- /dev/null +++ b/libc-0.0.4/New_subdir @@ -0,0 +1,67 @@ +#!/bin/sh - +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +cat <<! +This is a shell script to create the bare bones for a new part of the +libc package. To use it you just invoke it with the directory name +you want to create as it's argument, it'll then create that directory +and put a few files in it. + +! +if [ "$1" = "" ] ; then exit 1 ; fi +if [ -e "$1" ] +then echo "There is already something called '$1' in the current directory" + echo "You'll have to remove it or rename it first" + exit 1 +fi + +YEAR=`date +%Y` +NAME="`finger -s $LOGNAME | head -2 | tail -1 | cut -b10-30 | sed 's/ *$//'`" +EMAIL="$LOGNAME@`hostname -f`" +FNAME="`echo $NAME | cut -d\ -f1`" + +mkdir $1 +cat <<! > $1/Makefile +# Copyright (C) $YEAR $NAME <$EMAIL> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include \$(TOP)/Make.defs + +OBJ=$1.o + +all: \$(OBJ) + +libc.a: \$(OBJ) + ar r ../libc.a \$(OBJ) + @touch libc.a + +clean: + rm -f \$(OBJ) libc.a +! +cat <<! > $1/README +Copyright (C) $YEAR $NAME <$EMAIL> +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +There's currently nothing special about $1. + +-$FNAME +! +cat <<! > $1/$1.c +/* Copyright (C) $YEAR $NAME <$EMAIL> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +$1() +{ + /* FIXME :-) */ +} +! + +echo "Ok, the directory $1 has now been created ..." +exit 0 diff --git a/libc-0.0.4/Pre_main b/libc-0.0.4/Pre_main new file mode 100644 index 0000000..e3793f1 --- /dev/null +++ b/libc-0.0.4/Pre_main @@ -0,0 +1,55 @@ + +There is now support for calling functions before main and from inside the +exit() function. + +The exit processing uses the standard 'atexit' and 'on_exit' functions +see the normal man pages. + +Execution of code before main is Linux-8086 specific; the method +is similar to this: + +/**********************/ +int global_var_that_needs_init; + +#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 + .word no_op ! Space filler cause segs are padded to 4 bytes. + .text ! So the function after is also in the correct seg. +#endasm + +static void init_vars() +{ + global_var_that_needs_init = getuid(); +} +/**********************/ + +The most important part is that the asm code _MUST_ be compiled into the +same object file as the variable that is being initialised. + +If this is not so the init_vars function will not be linked in and will +not be executed. + +Also do note that the init functions are called in essentially random order +(It's actually the order that they appear in the executable) so you must be +careful not to call any routines tht have their own autostart from inside +your autostart. Nevertheless you should try to ensure that your routines +will fail gracefully if they are called before the initilisation routine. + +If you do not know if a routine has an autostart create a test program +calling the routine and compile with: + + bcc -0 [other_stuff] -M test.c | sort +2 | more + +Look down the list for lines like this: + + crt0 ZP_safety 1 00000000 R + crt0 auto_start 1 00000008 R + objname auto_func 1 00000008 R <<**** + crt0 data_start 2 00000010 R + crt0 _environ 3 00000010 R + +The line marked is an autostart function call. + +Robert. diff --git a/libc-0.0.4/README b/libc-0.0.4/README new file mode 100644 index 0000000..f8160ba --- /dev/null +++ b/libc-0.0.4/README @@ -0,0 +1,70 @@ + +This is the README for libc-8086-0.0.3.tar.gz +Robert de Bath, 22/Feb/96, rdebath@cix.compulink.co.uk + +The lib is starting to look a lot fatter, it can now be compiled five +different ways for Linux-8086 standard, Linux-8086 with 'First arg in AX', +MS-DOS, BCC-386 or for GNU-386. At the moment the 386 versions are +missing some _very_ important bits. + +THE COMPILER + You should use the newest version of the bcc/bcc-cc1/as86/ld86 tools these + contain patches to ease operating in a cross-compiling enviroment and + the arguments to BCC have changed slightly. + + The standard ld86 can't generate MSDOS COM files by itself. + If you need to change search paths they can all be done from the command + line or by recompiling _only_ bcc.c. + These tools also contain Nat's 'clean' and 'ansi' patches. + +Main Subdirectories. + +include Some include files, some new others Glib or Glib hacked. + (They are a _real_ mess ATM and very light on the ground) + +bcc Lots of BCC helper functions +malloc1 My malloc routines +malloc2 Joel's malloc routines +misc Various larger functions +msdos This is the equlivent of the syscall directory for msdos. +string The functions for string.h +syscall All the system call functions, and a few tied lib ones. +stdio Joel's standard I/O functions - as yet rather incomplete +pwd Routines for /etc/passwd, from Nat +grp Routines for /etc/group, from Nat +regexp Standard regular expression parser +tests Various C programs used to test the lib. + +Directory structure: + + The top Makefile will try to call any "Makefile" it finds in a + subdirectory, so to add a new chunk to "libc.a" just drop in + the directory a Makefile that understands "make clean" and + "make libc.a" (Which must also update ../libc.a) + There's now a tiny script (New_subdir) that'll do this. + + Make config will look in all subdirectories for a file 'Config' + any it finds will be displayed and can be used to switch a directory + on or off by renaming Makefile<->makefile. + (This seemed like a good idea, I'm not so sure now ...) + + The exit(rv) function is already defined. It will call the contents + of the function pointer (*__cleanup)() before it calls _exit(); + This pointer should be used through the 'atexit' or 'on_exit' lib + functions. (See standard man pages) + + If you need to call something before main see the file 'Pre_main'. + +There are symlinks in the archive, they assume a layout something like: + + Linux_8086 + Linux_8086/libc This Libc + Linux_8086/linuxmt The Elks Kernel + Linux_8086/ELKSemu The Elks Emulator + Linux_8086/bcc Compiler src + Linux_8086/as Assembler + Linux_8086/ld Linker + +-Robert + +-=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- -=*=- diff --git a/libc-0.0.4/TODO b/libc-0.0.4/TODO new file mode 100644 index 0000000..a65fac7 --- /dev/null +++ b/libc-0.0.4/TODO @@ -0,0 +1,54 @@ +Here's a short list of bits that are required. If you want to do one of +these it's probably best to post to the list <linux-8086@vger.rutgers.edu>. + +Add more to this todo list! + + +TODO for libc-8086: +Item Notes +--------------------------------------------------------------------------- +Floating Point - BUT note there may need to be kernel support. Also, + BCC doesn't do it properly right now... +Header Files - This will take some time, also some files should + be kernel. +Stdio - Joel is on this. (stdio1) (RDB stdio2) +dirent &co - Directory listing - Partial. +getgrent &co - Nat -Done +getpwent &co - Nat -Done +utmp/wtmp - Nat -Done +hsearch &co - +tsearch &co - +locale processing - multi national, unicode (string stuff has a couple + of stubs) +login - getpass and friends - [I'll just dump the tiny-login + getpass code in -Nat] +rpc - +setjmp - Done, Rob +syslog &co - make stubs to splatter to console. +time calcs - mktime gmtime localtime etc +timezone - Probably V simplistic, List of UTC's + offsets & STDvDST +shadow password - Do we need ? Do we want :-) [No! Ick! ;) -Nat] +termcap - and curses; what does ncurses need ? (150kb!!) +crypt - glibc/crypt ? Use TEA? +signal stuff - Got a basic 'signal' appears to work correctly. +getenv/setenv - Done +bsearch - Grabbed (Public Domain) +lsearch - Grabbed (Public Domain) +random numbers - Got ZX81 version (better than some) (And 2nd now) +math - Until BCC can handle 16 bit FP properly, this is + probably on hold.. +dual-platform build +environment - This will be a gradual process, I imagine. + +Other projects: +Project Notes +--------------------------------------------------------------------------- +Optimiser for BCC - A lot of work, but lucrative. +Tiny vi editor - Use 'ae' ? +Shells: Bourne, Csh, +menu, silly - ash with proper compile-time options. . . ? +Tiny Perl - :-) :-) You first ;) +User commands - Everything in /bin /usr/bin - will existing PD/GPL + compile in 16 bit ? Or do smaller ones exist, + need to written ? diff --git a/libc-0.0.4/bcc/Config b/libc-0.0.4/bcc/Config new file mode 100644 index 0000000..0bfed09 --- /dev/null +++ b/libc-0.0.4/bcc/Config @@ -0,0 +1,2 @@ + +bcclib: Library of bcc helper functions diff --git a/libc-0.0.4/bcc/Makefile b/libc-0.0.4/bcc/Makefile new file mode 100644 index 0000000..b5019a5 --- /dev/null +++ b/libc-0.0.4/bcc/Makefile @@ -0,0 +1,58 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +# Support for integer arithmetic +IOBJ=__idiv.o __idivu.o __imod.o __imodu.o __imul.o __isl.o __isr.o __isru.o +ISRC=bcc_int.c + +# Support for long arithmetic on little-endian (normal) longs +LSRC=bcc_long.c +LOBJ=__laddl.o __landl.o __lcmpl.o __lcoml.o __ldecl.o __ldivl.o __ldivul.o \ + __leorl.o __lincl.o __lmodl.o __lmodul.o __lmull.o __lnegl.o __lorl.o \ + __lsll.o __lsrl.o __lsrul.o __lsubl.o __ltstl.o + +# Memory allocation primitives +AOBJ=errno.o __brk_addr.o sbrk.o brk.o +ASRC=heap.c + +# Support for long arithmetic on big-endian (words-swapped) longs +RSRC=bcc_bsw.c +ROBJ=__laddb.o __landb.o __lcmpb.o __lcomb.o __ldecb.o __ldivb.o __ldivub.o \ + __leorb.o __lincb.o __lmodb.o __lmodub.o __lmulb.o __lnegb.o __lorb.o \ + __lslb.o __lsrb.o __lsrub.o __lsubb.o __ltstb.o + +# Miscellaneous I/O and far access junk +PSRC=bcc_io.c +POBJ=__inport.o __inportb.o __outport.o __outportb.o __peekb.o __peekw.o \ + __pokeb.o __pokew.o + +OBJ=__ldivmod.o $(IOBJ) $(LOBJ) $(AOBJ) +OLDOBJ=$(ROBJ) $(POBJ) + +all: $(OBJ) + +$(IOBJ): $(ISRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ISRC) + +$(LOBJ): $(LSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(LSRC) + +$(AOBJ): $(ASRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ASRC) + +$(ROBJ): $(RSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(RSRC) + +$(POBJ): $(PSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(PSRC) + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a diff --git a/libc-0.0.4/bcc/__ldivmod.c b/libc-0.0.4/bcc/__ldivmod.c new file mode 100644 index 0000000..4cb6d77 --- /dev/null +++ b/libc-0.0.4/bcc/__ldivmod.c @@ -0,0 +1,195 @@ +/************************************************************************/ +/* This file contains the BCC compiler helper functions */ +/* Function ldivmod */ + +#ifdef __AS386_16__ +#asm + .text + .even + +| ldivmod.s - 32 over 32 to 32 bit division and remainder for 8086 + +| ldivmod( dividend bx:ax, divisor di:cx ) [ signed quot di:cx, rem bx:ax ] +| ludivmod( dividend bx:ax, divisor di:cx ) [ unsigned quot di:cx, rem bx:ax ] + +| dx is not preserved + + +| NB negatives are handled correctly, unlike by the processor +| divison by zero does not trap + + +| let dividend = a, divisor = b, quotient = q, remainder = r +| a = b * q + r mod 2^32 +| where: + +| if b = 0, q = 0 and r = a + +| otherwise, q and r are uniquely determined by the requirements: +| r has the same sign as b and absolute value smaller than that of b, i.e. +| if b > 0, then 0 <= r < b +| if b < 0, then 0 >= r > b +| (the absoulute value and its comparison depend on signed/unsigned) + +| the rule for the sign of r means that the quotient is truncated towards +| negative infinity in the usual case of a positive divisor + +| if the divisor is negative, the division is done by negating a and b, +| doing the division, then negating q and r + + + .globl ldivmod + +ldivmod: + mov dx,di ! sign byte of b in dh + mov dl,bh ! sign byte of a in dl + test di,di + jns set_asign + neg di + neg cx + sbb di,*0 +set_asign: + test bx,bx + jns got_signs ! leave r = a positive + neg bx + neg ax + sbb bx,*0 + j got_signs + + .globl ludivmod + .even + +ludivmod: + xor dx,dx ! both sign bytes 0 +got_signs: + push bp + push si + mov bp,sp + push di ! remember b + push cx +b0 = -4 +b16 = -2 + + test di,di + jne divlarge + test cx,cx + je divzero + cmp bx,cx + jae divlarge ! would overflow + xchg dx,bx ! a in dx:ax, signs in bx + div cx + xchg cx,ax ! q in di:cx, junk in ax + xchg ax,bx ! signs in ax, junk in bx + xchg ax,dx ! r in ax, signs back in dx + mov bx,di ! r in bx:ax + j zdivu1 + +divzero: ! return q = 0 and r = a + test dl,dl + jns return + j negr ! a initially minus, restore it + +divlarge: + push dx ! remember sign bytes + mov si,di ! w in si:dx, initially b from di:cx + mov dx,cx + xor cx,cx ! q in di:cx, initially 0 + mov di,cx + ! r in bx:ax, initially a + ! use di:cx rather than dx:cx in order to + ! have dx free for a byte pair later + cmp si,bx + jb loop1 + ja zdivu ! finished if b > r + cmp dx,ax + ja zdivu + +| rotate w (= b) to greatest dyadic multiple of b <= r + +loop1: + shl dx,*1 ! w = 2*w + rcl si,*1 + jc loop1_exit ! w was > r counting overflow (unsigned) + cmp si,bx ! while w <= r (unsigned) + jb loop1 + ja loop1_exit + cmp dx,ax + jbe loop1 ! else exit with carry clear for rcr +loop1_exit: + rcr si,*1 + rcr dx,*1 +loop2: + shl cx,*1 ! q = 2*q + rcl di,*1 + cmp si,bx ! if w <= r + jb loop2_over + ja loop2_test + cmp dx,ax + ja loop2_test +loop2_over: + add cx,*1 ! q++ + adc di,*0 + sub ax,dx ! r = r-w + sbb bx,si +loop2_test: + shr si,*1 ! w = w/2 + rcr dx,*1 + cmp si,b16[bp] ! while w >= b + ja loop2 + jb zdivu + cmp dx,b0[bp] + jae loop2 + +zdivu: + pop dx ! sign bytes +zdivu1: + test dh,dh + js zbminus + test dl,dl + jns return ! else a initially minus, b plus + mov dx,ax ! -a = b * q + r ==> a = b * (-q) + (-r) + or dx,bx + je negq ! use if r = 0 + sub ax,b0[bp] ! use a = b * (-1 - q) + (b - r) + sbb bx,b16[bp] + not cx ! q = -1 - q (same as complement) + not di +negr: + neg bx + neg ax + sbb bx,*0 +return: + mov sp,bp + pop si + pop bp + ret + + .even + +zbminus: + test dl,dl ! (-a) = (-b) * q + r ==> a = b * q + (-r) + js negr ! use if initial a was minus + mov dx,ax ! a = (-b) * q + r ==> a = b * (-q) + r + or dx,bx + je negq ! use if r = 0 + sub ax,b0[bp] ! use a = b * (-1 - q) + (b + r) (b is now -b) + sbb bx,b16[bp] + not cx + not di + mov sp,bp + pop si + pop bp + ret + + .even + +negq: + neg di + neg cx + sbb di,*0 + mov sp,bp + pop si + pop bp + ret +#endasm +#endif diff --git a/libc-0.0.4/bcc/alloca.c b/libc-0.0.4/bcc/alloca.c new file mode 100644 index 0000000..4f85047 --- /dev/null +++ b/libc-0.0.4/bcc/alloca.c @@ -0,0 +1,50 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* Alloca is a nice interesting function */ +/* Needs change to BCC to work, as BCC doesn't use 'mov sp,bp:pop bp' */ +/* The only other way to do it is to use malloc and the emacs alloca */ + +#if 0 +THIS IS BROKEN!!! + +#asm +export _alloca + .text +_alloca: + pop cx ! The program counter + pop ax ! The argument (>1 arg == snafu) + inc ax + and al,$FE ! Round up to even + + test ax,ax + jz too_big ! Well _I_ think it means 64k ! :-) (ANSI too IIUC) + + mov bx,sp + sub bx,ax ! Calc new SP + jb too_big ! SP wrapped, snafu! + + mov ax,[brk_addr] + add ax,#64 ! Check if brk has allocated the memory first but + cmp bx,ax ! leave a little bit of space before we collide! + jb too_big + + xchg bx,sp ! Put it in place, may need the old SP for other args + mov ax,sp ! The bottom of the area allocated + + ! This is needed if si/di popped before mov sp,bp + !push [bx+4] ! This copies the saved register vars and possibly a temp + !push [bx+2] ! value, beware snafu if called within complex expression! + !push [bx] ! + + push ax ! Anything really, it will be deallocated by the caller + jmp cx ! Return + +too_big: + xor ax,ax ! Sorry not enough stack + push ax ! More junk + jmp cx ! Return +#endasm +#endif diff --git a/libc-0.0.4/bcc/bcc_bsw.c b/libc-0.0.4/bcc/bcc_bsw.c new file mode 100644 index 0000000..4dd0d11 --- /dev/null +++ b/libc-0.0.4/bcc/bcc_bsw.c @@ -0,0 +1,487 @@ +/************************************************************************/ +/* This file contains the BCC compiler helper functions */ +/* Support for long arithmetic on big-endian (words-swapped) longs + * __laddb.o __landb.o __lcmpb.o __lcomb.o __ldecb.o __ldivb.o __ldivub.o + * __leorb.o __lincb.o __lmodb.o __lmodub.o __lmulb.o __lnegb.o __lorb.o + * __lslb.o __lsrb.o __lsrub.o __lsubb.o __ltstb.o + */ +#ifdef __AS386_16__ +#asm + .text ! This is common to all. + .even +#endasm + +/************************************************************************/ +/* Function laddb */ + +#ifdef L___laddb +#asm + +| laddb.s + + .globl laddb + .globl laddub + +laddb: +laddub: + add bx,2(di) + adc ax,(di) + ret +#endasm +#endif + +/************************************************************************/ +/* Function landb */ + +#ifdef L___landb +#asm + +| landb.s + + .globl landb + .globl landub + +landb: +landub: + and ax,(di) + and bx,2(di) + ret +#endasm +#endif + +/************************************************************************/ +/* Function lcmpb */ + +#ifdef L___lcmpb +#asm + +| lcmpb.s +| lcmpb, lcmpub don`t preserve ax + + .globl lcmpb + .globl lcmpub + +lcmpb: +lcmpub: + sub ax,(di) | don`t need to preserve ax + je LCMP_NOT_SURE + ret + + .even + +LCMP_NOT_SURE: + cmp bx,2(di) + jb LCMP_B_AND_LT | b (below) becomes lt (less than) as well + jge LCMP_EXIT | ge and already ae + | else make gt as well as a (above) + inc ax | clear ov and mi, set ne for greater than +LCMP_EXIT: + ret + + .even + +LCMP_B_AND_LT: + dec ax | clear ov, set mi and ne for less than + ret +#endasm +#endif + +/************************************************************************/ +/* Function lcomb */ + +#ifdef L___lcomb +#asm + +| lcomb.s + + .globl lcomb + .globl lcomub + +lcomb: +lcomub: + not ax + not bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function ldecb */ + +#ifdef L___ldecb +#asm + +| ldecb.s + + .globl ldecb + .globl ldecub + +ldecb: +ldecub: + cmp 2(bx),*0 + je LDEC_BOTH + dec 2(bx) + ret + + .even + +LDEC_BOTH: + dec 2(bx) + dec (bx) + ret +#endasm +#endif + +/************************************************************************/ +/* Function ldivb */ + +#ifdef L___ldivb +#asm + +| ldivb.s +| ax:bx / (di):2(di), quotient ax:bx, remainder cx:di, dx not preserved + + .globl ldivb + .extern ldivmod + +ldivb: + xchg ax,bx + mov cx,2(di) + mov di,(di) + call ldivmod | bx:ax / di:cx, quot di:cx, rem bx:ax + xchg ax,di + xchg bx,cx + ret +#endasm +#endif + +/************************************************************************/ +/* Function ldivub */ + +#ifdef L___ldivub +#asm + +| ldivub.s +| unsigned ax:bx / (di):2(di), quotient ax:bx,remainder cx:di, dx not preserved + + .globl ldivub + .extern ludivmod + +ldivub: + xchg ax,bx + mov cx,2(di) + mov di,(di) + call ludivmod | unsigned bx:ax / di:cx, quot di:cx, rem bx:ax + xchg ax,di + xchg bx,cx + ret +#endasm +#endif + +/************************************************************************/ +/* Function leorb */ + +#ifdef L___leorb +#asm + +| leorb.s + + .globl leorb + .globl leorub + +leorb: +leorub: + xor ax,(di) + xor bx,2(di) + ret +#endasm +#endif + +/************************************************************************/ +/* Function lincb */ + +#ifdef L___lincb +#asm + +| lincb.s + + .globl lincb + .globl lincub + +lincb: +lincub: + inc 2(bx) + je LINC_HIGH_WORD + ret + + .even + +LINC_HIGH_WORD: + inc (bx) + ret +#endasm +#endif + +/************************************************************************/ +/* Function lmodb */ + +#ifdef L___lmodb +#asm + +| lmodb.s +| ax:bx % (di):2(di), remainder ax:bx, quotient cx:di, dx not preserved + + .globl lmodb + .extern ldivmod + +lmodb: + xchg ax,bx + mov cx,2(di) + mov di,(di) + call ldivmod | bx:ax / di:cx, quot di:cx, rem bx:ax + xchg ax,bx + xchg cx,di + ret +#endasm +#endif + +/************************************************************************/ +/* Function lmodub */ + +#ifdef L___lmodub +#asm + +| lmodub.s +| unsigned ax:bx / (di):2(di), remainder ax:bx,quotient cx:di, dx not preserved + + .globl lmodub + .extern ludivmod + +lmodub: + xchg ax,bx + mov cx,2(di) + mov di,(di) + call ludivmod | unsigned bx:ax / di:cx, quot di:cx, rem bx:ax + xchg ax,bx + xchg cx,di + ret +#endasm +#endif + +/************************************************************************/ +/* Function lmulb */ + +#ifdef L___lmulb +#asm + +| lmulb.s +| lmulb, lmulub don`t preserve cx, dx + + .globl lmulb + .globl lmulub + +lmulb: +lmulub: + mul 2(di) + xchg ax,bx + mov cx,ax + mul (di) + add bx,ax + mov ax,2(di) + mul cx + add bx,dx + xchg ax,bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function lnegb */ + +#ifdef L___lnegb +#asm + +| lnegb.s + + .globl lnegb + .globl lnegub + +lnegb: +lnegub: + neg ax + neg bx + sbb ax,*0 + ret +#endasm +#endif + +/************************************************************************/ +/* Function lorb */ + +#ifdef L___lorb +#asm + +| lorb.s + + .globl lorb + .globl lorub + +lorb: +lorub: + or ax,(di) + or bx,2(di) + ret +#endasm +#endif + +/************************************************************************/ +/* Function lslb */ + +#ifdef L___lslb +#asm + +| lslb.s +| lslb, lslub don`t preserve cx + + .globl lslb + .globl lslub + +lslb: +lslub: + mov cx,di + jcxz LSL_EXIT + cmp cx,*32 + jae LSL_ZERO +LSL_LOOP: + shl bx,*1 + rcl ax,*1 + loop LSL_LOOP +LSL_EXIT: + ret + + .even + +LSL_ZERO: + xor ax,ax + mov bx,ax + ret +#endasm +#endif + +/************************************************************************/ +/* Function lsrb */ + +#ifdef L___lsrb +#asm + +| lsrb.s +| lsrb doesn`t preserve cx + + .globl lsrb + +lsrb: + mov cx,di + jcxz LSR_EXIT + cmp cx,*32 + jae LSR_SIGNBIT +LSR_LOOP: + sar ax,*1 + rcr bx,*1 + loop LSR_LOOP +LSR_EXIT: + ret + + .even + +LSR_SIGNBIT: + mov cx,*32 | equivalent to +infinity in this context + j LSR_LOOP +#endasm +#endif + +/************************************************************************/ +/* Function lsrub */ + +#ifdef L___lsrub +#asm + +| lsrub.s +| lsrub doesn`t preserve cx + + .globl lsrub + +lsrub: + mov cx,di + jcxz LSRU_EXIT + cmp cx,*32 + jae LSRU_ZERO +LSRU_LOOP: + shr ax,*1 + rcr bx,*1 + loop LSRU_LOOP +LSRU_EXIT: + ret + + .even + +LSRU_ZERO: + xor ax,ax + mov bx,ax + ret +#endasm +#endif + +/************************************************************************/ +/* Function lsubb */ + +#ifdef L___lsubb +#asm + +| lsubb.s + + .globl lsubb + .globl lsubub + +lsubb: +lsubub: + sub bx,2(di) + sbb ax,(di) + ret +#endasm +#endif + +/************************************************************************/ +/* Function ltstb */ + +#ifdef L___ltstb +#asm + +| ltstb.s +| ltstb, ltstub don`t preserve ax + + .globl ltstb + .globl ltstub + +ltstb: +ltstub: + test ax,ax + je LTST_NOT_SURE + ret + + .even + +LTST_NOT_SURE: + test bx,bx + js LTST_FIX_SIGN + ret + + .even + +LTST_FIX_SIGN: + inc ax | clear ov and mi, set ne for greater than + ret +#endasm +#endif + +#endif + diff --git a/libc-0.0.4/bcc/bcc_int.c b/libc-0.0.4/bcc/bcc_int.c new file mode 100644 index 0000000..abdb7b4 --- /dev/null +++ b/libc-0.0.4/bcc/bcc_int.c @@ -0,0 +1,162 @@ +/************************************************************************/ +/* This file contains the BCC compiler helper functions */ +/* Support for integer arithmetic + * __idiv.o __idivu.o __imod.o __imodu.o __imul.o __isl.o __isr.o __isru.o + */ + +#ifdef __AS386_16__ +#asm + .text ! This is common to all. + .even +#endasm + +/************************************************************************/ +/* Function idiv */ + +#ifdef L___idiv +#asm + +| idiv.s +| idiv_ doesn`t preserve dx (returns remainder in it) + + .globl idiv_ + +idiv_: + cwd + idiv bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function idivu */ + +#ifdef L___idivu +#asm + +| idivu.s +| idiv_u doesn`t preserve dx (returns remainder in it) + + .globl idiv_u + +idiv_u: + xor dx,dx + div bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function imod */ + +#ifdef L___imod +#asm + +| imod.s +| imod doesn`t preserve dx (returns quotient in it) + + .globl imod + +imod: + cwd + idiv bx + mov ax,dx + ret +#endasm +#endif + +/************************************************************************/ +/* Function imodu */ + +#ifdef L___imodu +#asm + +| imodu.s +| imodu doesn`t preserve dx (returns quotient in it) + + .globl imodu + +imodu: + xor dx,dx + div bx + mov ax,dx ! instruction queue full so xchg slower + ret +#endasm +#endif + +/************************************************************************/ +/* Function imul */ + +#ifdef L___imul +#asm + +| imul.s +| imul_, imul_u don`t preserve dx + + .globl imul_ + .globl imul_u + +imul_: +imul_u: + imul bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function isl */ + +#ifdef L___isl +#asm + +| isl.s +| isl, islu don`t preserve cl + + .globl isl + .globl islu + +isl: +islu: + mov cl,bl + shl ax,cl + ret +#endasm +#endif + +/************************************************************************/ +/* Function isr */ + +#ifdef L___isr +#asm + +| isr.s +| isr doesn`t preserve cl + + .globl isr + +isr: + mov cl,bl + sar ax,cl + ret +#endasm +#endif + +/************************************************************************/ +/* Function isru */ + +#ifdef L___isru +#asm + +| isru.s +| isru doesn`t preserve cl + + .globl isru + +isru: + mov cl,bl + shr ax,cl + ret +#endasm +#endif + +#endif diff --git a/libc-0.0.4/bcc/bcc_io.c b/libc-0.0.4/bcc/bcc_io.c new file mode 100644 index 0000000..af5dfd2 --- /dev/null +++ b/libc-0.0.4/bcc/bcc_io.c @@ -0,0 +1,189 @@ +/************************************************************************/ +/* This file contains the BCC compiler helper functions */ +/* Miscellaneous obsolete junk + * __inport.o __inportb.o __outport.o __outportb.o __peekb.o __peekw.o + * __pokeb.o __pokew.o + */ + +#ifdef __AS368_16__ +#if !__FIRST_ARG_IN_AX__ +#asm + .text ! This is common to all. + .even +#endasm + +/************************************************************************/ +/* Function inport */ + +#ifdef L___inport +#asm + +| int inport( int port ); +| reads a word from the i/o port port and returns it + + .globl _inport +_inport: + pop bx + pop dx + dec sp + dec sp + inw + jmp bx +#endasm +#endif + +/************************************************************************/ +/* Function inportb */ + +#ifdef L___inportb +#asm + +| int inportb( int port ); +| reads a byte from the i/o port port and returns it + + .globl _inportb +_inportb: + pop bx + pop dx + dec sp + dec sp + in + sub ah,ah + jmp bx +#endasm +#endif + +/************************************************************************/ +/* Function outport */ + +#ifdef L___outport +#asm + +| void outport( int port, int value ); +| writes the word value to the i/o port port + + .globl _outport +_outport: + pop bx + pop dx + pop ax + sub sp,*4 + outw + jmp bx +#endasm +#endif + +/************************************************************************/ +/* Function outportb */ + +#ifdef L___outportb +#asm + +| void oportb( int port, char value ); +| writes the byte value to the i/o port port +| this would be outportb except for feeble linkers + + .globl _oportb +_oportb: + pop bx + pop dx + pop ax + sub sp,*4 + out + jmp bx +#endasm +#endif + +/************************************************************************/ +/* Function peekb */ + +#ifdef L___peekb +#asm + +| int peekb( unsigned segment, char *offset ); +| returns the (unsigned) byte at the far pointer segment:offset + + .define _peekb +_peekb: + mov cx,ds + pop dx + pop ds + pop bx + sub sp,*4 + movb al,(bx) + subb ah,ah + mov ds,cx + jmp dx +#endasm +#endif + +/************************************************************************/ +/* Function peekw */ + +#ifdef L___peekw +#asm + +| int peekw( unsigned segment, int *offset ); +| returns the word at the far pointer segment:offset + + .define _peekw +_peekw: + mov cx,ds + pop dx + pop ds + pop bx + sub sp,*4 + mov ax,(bx) + mov ds,cx + jmp dx +#endasm +#endif + +/************************************************************************/ +/* Function pokeb */ + +#ifdef L___pokeb +#asm + +| void pokeb( unsigned segment, char *offset, char value ); +| writes the byte value at the far pointer segment:offset + + .define _pokeb +_pokeb: + mov cx,ds + pop dx + pop ds + pop bx + pop ax + sub sp,*6 + movb (bx),al + mov ds,cx + jmp dx +#endasm +#endif + +/************************************************************************/ +/* Function pokew */ + +#ifdef L___pokew +#asm + +| void pokew( unsigned segment, int *offset, int value ); +| writes the word value at the far pointer segment:offset + + .define _pokew +_pokew: + mov cx,ds + pop dx + pop ds + pop bx + pop ax + sub sp,*6 + mov (bx),ax + mov ds,cx + jmp dx +#endasm +#endif + +#endif /* !__FIRST_ARG_IN_AX__ */ +#endif diff --git a/libc-0.0.4/bcc/bcc_long.c b/libc-0.0.4/bcc/bcc_long.c new file mode 100644 index 0000000..4b6ceae --- /dev/null +++ b/libc-0.0.4/bcc/bcc_long.c @@ -0,0 +1,479 @@ +/************************************************************************/ +/* This file contains the BCC compiler helper functions */ +/* Support for long arithmetic on little-endian (normal) longs + * __laddl.o __landl.o __lcmpl.o __lcoml.o __ldecl.o __ldivl.o __ldivul.o + * __leorl.o __lincl.o __lmodl.o __lmodul.o __lmull.o __lnegl.o __lorl.o + * __lsll.o __lsrl.o __lsrul.o __lsubl.o __ltstl.o + */ + +#ifdef __AS386_16__ +#asm + .text ! This is common to all. + .even +#endasm + +/************************************************************************/ +/* Function laddl */ + +#ifdef L___laddl +#asm + +| laddl.s + + .globl laddl + .globl laddul + +laddl: +laddul: + add ax,[di] + adc bx,2[di] + ret +#endasm +#endif + +/************************************************************************/ +/* Function landl */ + +#ifdef L___landl +#asm + +| landl.s + + .globl landl + .globl landul + +landl: +landul: + and ax,[di] + and bx,2[di] + ret +#endasm +#endif + +/************************************************************************/ +/* Function lcmpl */ + +#ifdef L___lcmpl +#asm + +| lcmpl.s +| lcmpl, lcmpul don`t preserve bx + + .globl lcmpl + .globl lcmpul + +lcmpl: +lcmpul: + sub bx,2[di] + je LCMP_NOT_SURE + ret + + .even + +LCMP_NOT_SURE: + cmp ax,[di] + jb LCMP_B_AND_LT + jge LCMP_EXIT + + inc bx +LCMP_EXIT: + ret + + .even + +LCMP_B_AND_LT: + dec bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function lcoml */ + +#ifdef L___lcoml +#asm + +| lcoml.s + + .globl lcoml + .globl lcomul + +lcoml: +lcomul: + not ax + not bx + ret +#endasm +#endif + +/************************************************************************/ +/* Function ldecl */ + +#ifdef L___ldecl +#asm + +| ldecl.s + + .globl ldecl + .globl ldecul + +ldecl: +ldecul: + cmp word ptr [bx],*0 + je LDEC_BOTH + dec word ptr [bx] + ret + + .even + +LDEC_BOTH: + dec word ptr [bx] + dec word ptr 2[bx] + ret +#endasm +#endif + +/************************************************************************/ +/* Function ldivl */ + +#ifdef L___ldivl +#asm + +| ldivl.s +| bx:ax / 2(di):(di), quotient bx:ax, remainder di:cx, dx not preserved + + .globl ldivl + .extern ldivmod + +ldivl: + mov cx,[di] + mov di,2[di] + call ldivmod + xchg ax,cx + xchg bx,di + ret + +#endasm +#endif + +/************************************************************************/ +/* Function ldivul */ + +#ifdef L___ldivul +#asm + +| ldivul.s +| unsigned bx:ax / 2(di):(di), quotient bx:ax,remainder di:cx, dx not preserved + + .globl ldivul + .extern ludivmod + +ldivul: + mov cx,[di] + mov di,2[di] + call ludivmod + xchg ax,cx + xchg bx,di + ret +#endasm +#endif + +/************************************************************************/ +/* Function leorl */ + +#ifdef L___leorl +#asm + +| leorl.s + + .globl leorl + .globl leorul + +leorl: +leorul: + xor ax,[di] + xor bx,2[di] + ret +#endasm +#endif + +/************************************************************************/ +/* Function lincl */ + +#ifdef L___lincl +#asm + +| lincl.s + + .globl lincl + .globl lincul + +lincl: +lincul: + inc word ptr [bx] + je LINC_HIGH_WORD + ret + + .even + +LINC_HIGH_WORD: + inc word ptr 2[bx] + ret +#endasm +#endif + +/************************************************************************/ +/* Function lmodl */ + +#ifdef L___lmodl +#asm + +| lmodl.s +| bx:ax % 2(di):(di), remainder bx:ax, quotient di:cx, dx not preserved + + .globl lmodl + .extern ldivmod + +lmodl: + mov cx,[di] + mov di,2[di] + call ldivmod + ret +#endasm +#endif + +/************************************************************************/ +/* Function lmodul */ + +#ifdef L___lmodul +#asm + +| lmodul.s +| unsigned bx:ax / 2(di):(di), remainder bx:ax,quotient di:cx, dx not preserved + + .globl lmodul + .extern ludivmod + +lmodul: + mov cx,[di] + mov di,2[di] + call ludivmod + ret +#endasm +#endif + +/************************************************************************/ +/* Function lmull */ + +#ifdef L___lmull +#asm + +| lmull.s +| lmull, lmulul don`t preserve cx, dx + + .globl lmull + .globl lmulul + +lmull: +lmulul: + mov cx,ax + mul word ptr 2[di] + xchg ax,bx + mul word ptr [di] + add bx,ax + mov ax,ptr [di] + mul cx + add bx,dx + ret +#endasm +#endif + +/************************************************************************/ +/* Function lnegl */ + +#ifdef L___lnegl +#asm + +| lnegl.s + + .globl lnegl + .globl lnegul + +lnegl: +lnegul: + neg bx + neg ax + sbb bx,*0 + ret +#endasm +#endif + +/************************************************************************/ +/* Function lorl */ + +#ifdef L___lorl +#asm + +| lorl.s + + .globl lorl + .globl lorul + +lorl: +lorul: + or ax,[di] + or bx,2[di] + ret +#endasm +#endif + +/************************************************************************/ +/* Function lsll */ + +#ifdef L___lsll +#asm + +| lsll.s +| lsll, lslul don`t preserve cx + + .globl lsll + .globl lslul + +lsll: +lslul: + mov cx,di + jcxz LSL_EXIT + cmp cx,*32 + jae LSL_ZERO +LSL_LOOP: + shl ax,*1 + rcl bx,*1 + loop LSL_LOOP +LSL_EXIT: + ret + + .even + +LSL_ZERO: + xor ax,ax + mov bx,ax + ret +#endasm +#endif + +/************************************************************************/ +/* Function lsrl */ + +#ifdef L___lsrl +#asm + +| lsrl.s +| lsrl doesn`t preserve cx + + .globl lsrl + +lsrl: + mov cx,di + jcxz LSR_EXIT + cmp cx,*32 + jae LSR_SIGNBIT +LSR_LOOP: + sar bx,*1 + rcr ax,*1 + loop LSR_LOOP +LSR_EXIT: + ret + + .even + +LSR_SIGNBIT: + mov cx,*32 + j LSR_LOOP +#endasm +#endif + +/************************************************************************/ +/* Function lsrul */ + +#ifdef L___lsrul +#asm + +| lsrul.s +| lsrul doesn`t preserve cx + + .globl lsrul + +lsrul: + mov cx,di + jcxz LSRU_EXIT + cmp cx,*32 + jae LSRU_ZERO +LSRU_LOOP: + shr bx,*1 + rcr ax,*1 + loop LSRU_LOOP +LSRU_EXIT: + ret + + .even + +LSRU_ZERO: + xor ax,ax + mov bx,ax + ret +#endasm +#endif + +/************************************************************************/ +/* Function lsubl */ + +#ifdef L___lsubl +#asm + +| lsubl.s + + .globl lsubl + .globl lsubul + +lsubl: +lsubul: + sub ax,[di] + sbb bx,2[di] + ret +#endasm +#endif + +/************************************************************************/ +/* Function ltstl */ + +#ifdef L___ltstl +#asm + +| ltstl.s +| ltstl, ltstul don`t preserve bx + + .globl ltstl + .globl ltstul + +ltstl: +ltstul: + test bx,bx + je LTST_NOT_SURE + ret + + .even + +LTST_NOT_SURE: + test ax,ax + js LTST_FIX_SIGN + ret + + .even + +LTST_FIX_SIGN: + inc bx + ret +#endasm +#endif + +#endif diff --git a/libc-0.0.4/bcc/heap.c b/libc-0.0.4/bcc/heap.c new file mode 100644 index 0000000..af4e898 --- /dev/null +++ b/libc-0.0.4/bcc/heap.c @@ -0,0 +1,116 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/****************************************************************************/ + +#ifdef L_errno +int errno = 0; /* libc error value */ +#endif + +/****************************************************************************/ + +#ifdef L___brk_addr +#ifdef __AS386_16__ +#asm +.data +export brk_addr +brk_addr: .word __end ! This holds the current return for sbrk(0) +.text +#endasm +#endif +#endif + +/****************************************************************************/ + +#ifdef L_sbrk +#ifdef __AS386_16__ +int sbrk(brk_off) +unsigned int brk_off; +{ +#asm + mov bx,sp +#if !__FIRST_ARG_IN_AX__ + mov ax,[bx+2] ! Fetch the requested value +#endif + test ax,ax + jnz has_change + mov ax,[brk_addr] ! Simple one; read current - can`t fail. + jmp eof + +has_change: + js go_down + add ax,[brk_addr] ! Goin up! + jc Enomem + sub bx,#64 ! Safety space + cmp bx,ax ! Too close ? + jb Enomem + +sbrk_ok: +#ifndef __MSDOS__ + push ax ! MSDOS `kernel` doesn`t care + call ___brk ! Tell the kernel + test ax,ax + pop ax ! ASSUME ___brk doesn`t alter stack! + jnz Enomem ! Ugh! kernel didn`t like the idea! +#endif + xchg [brk_addr],ax ! Save away new val + jmp eof ! Return it +go_down: + add ax,[brk_addr] + jnc Enomem + cmp ax,#__end + jae sbrk_ok + +Enomem: + mov ax,#12 ! This should be ENOMEM not a magic. + mov [_errno],ax + mov ax,#-1 +eof: +#endasm +} +#endif +#endif + +/****************************************************************************/ + +#ifdef L_brk +#ifdef __AS386_16__ +int +brk(new_brk) +void * new_brk; +{ +#asm + mov bx,sp +#if !__FIRST_ARG_IN_AX__ + mov ax,[bx+2] ! Fetch the requested value +#endif + sub bx,#64 ! Safety space + cmp bx,ax ! Too close ? + jb Enomem + cmp ax,#__end + jae brk_ok +Enomem: + mov ax,#12 ! This should be ENOMEM not a magic. + mov [_errno],ax + mov ax,#-1 + ret +brk_ok: +#ifndef __MSDOS__ + push ax + call ___brk ! Tell the kernel + test ax,ax + pop bx ! ASSUME ___brk doesn`t alter stack! + jnz Enomem ! Ugh! kernel didn`t like the idea! + mov [brk_addr],bx ! Save away new val +#else + mov [brk_addr],ax ! MSDOS `kernel` doesn`t care + mov ax,#0 +#endif +#endasm +} +#endif +#endif + +/****************************************************************************/ diff --git a/libc-0.0.4/crt0.c b/libc-0.0.4/crt0.c new file mode 100644 index 0000000..71ca6bc --- /dev/null +++ b/libc-0.0.4/crt0.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#if defined(__AS386_16__) || defined(__AS386_32__) +#define CRT0_OK +/* + * Change of aim here, to allow easy alteration for generation of COM files + * this code has been moved into libc. This means only the linker needs to + * to be told to fetch a different libc the crt0 is unaltered. + * + * This also allows us to deal with __FIRST_ARG_IN_AX__ and __CALLER_SAVES__ + * in the same way. + */ + +#asm +.text +entry startup ! Crt0 startup +startup: + br ___cstartup +export no_op +no_op: ! Generic no operation call (the byte was free :-) ) + ret + + loc 1 ! Segment 1 is where the pointers to the autostart +ZP_safety: ! functions are stored. + .word 0 ! But first some zeros to avoid null pointer writes. + .word 0 + .word 0 + .word 0 +export auto_start +auto_start: + +#endasm +#endif /* __AS386_16__ or __AS386_32__ */ + +#if defined(__GNUC__) && defined(__i386__) +#define CRT0_OK + +#ifdef __ELF__ +__asm__(".globl __startup\n__startup:"); +__asm__("jmp __cstartup"); +__asm__(".globl __no_op\n__no_op:"); +__asm__("ret"); +#else +__asm__(".globl startup\nstartup:"); +__asm__("jmp ___cstartup"); +__asm__(".globl no_op\nno_op:"); +__asm__("ret"); +#endif + +#endif /* defined(__GNUC__) && defined(__i386__) */ + +#ifndef CRT0_OK +#error You are not going to get far without crt0.o! +#endif diff --git a/libc-0.0.4/crt0.o b/libc-0.0.4/crt0.o Binary files differnew file mode 100644 index 0000000..e43705b --- /dev/null +++ b/libc-0.0.4/crt0.o diff --git a/libc-0.0.4/error/Config b/libc-0.0.4/error/Config new file mode 100644 index 0000000..1f384b7 --- /dev/null +++ b/libc-0.0.4/error/Config @@ -0,0 +1,2 @@ + +error: Unix error functions diff --git a/libc-0.0.4/error/Makefile b/libc-0.0.4/error/Makefile new file mode 100644 index 0000000..885f2b8 --- /dev/null +++ b/libc-0.0.4/error/Makefile @@ -0,0 +1,17 @@ +# Copyright (C) 1996 Robert de Bath <robert@debath.thenet.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +OBJ=error.o sys_errlist.o perror.o sys_siglist.o __assert.o + +all: $(OBJ) + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a diff --git a/libc-0.0.4/error/README b/libc-0.0.4/error/README new file mode 100644 index 0000000..02c123f --- /dev/null +++ b/libc-0.0.4/error/README @@ -0,0 +1,10 @@ +Copyright (C) 1996 Robert de Bath <robert@debath.thenet.co.uk> +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +These routines assume the existance of a file /usr/lib/liberror.txt, +this file contains the actual error messages. One useful feature, +the language of the error messages can be easily changed. + + +-Robert diff --git a/libc-0.0.4/error/__assert.c b/libc-0.0.4/error/__assert.c new file mode 100644 index 0000000..bcf04e8 --- /dev/null +++ b/libc-0.0.4/error/__assert.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <unistd.h> + +static void errput(str) +const char * str; +{ + write(2, str, strlen(str)); +} + +void +__assert(assertion, filename, linenumber) +const char * assertion; +const char * filename; +int linenumber; +{ + errput("Failed assertion '"); + errput(assertion); + errput("' in file "); + errput(filename); + errput(" at line "); + errput(itoa(linenumber)); + errput(".\n"); + abort(); +} diff --git a/libc-0.0.4/error/error.c b/libc-0.0.4/error/error.c new file mode 100644 index 0000000..3695719 --- /dev/null +++ b/libc-0.0.4/error/error.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1996 Robert de Bath <robert@debath.thenet.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> + +char **__sys_errlist =0; +int __sys_nerr = 0; + +char * +strerror(err) +int err; +{ + int fd; + static char retbuf[80]; + char inbuf[256]; + int cc; + int bufoff = 0; + + if( __sys_nerr ) + { + if( err < 0 || err >= __sys_nerr ) goto unknown; + return __sys_errlist[err]; + } + + if( err <= 0 ) goto unknown; /* NB the <= allows comments in the file */ + fd = open("/usr/lib/liberror.txt", 0); + if( fd < 0 ) goto unknown; + + while( (cc=read(fd, inbuf, sizeof(inbuf))) > 0 ) + { + int i; + for(i=0; i<cc; i++) + { + if( inbuf[i] == '\n' ) + { + retbuf[bufoff] = '\0'; + if( err == atoi(retbuf) ) + { + char * p = strchr(retbuf, ' '); + if( p == 0 ) goto unknown; + while(*p == ' ') p++; + close(fd); + return p; + } + bufoff = 0; + } + else if( bufoff < sizeof(retbuf)-1 ) + retbuf[bufoff++] = inbuf[i]; + } + } +unknown:; + if( fd >= 0 ) close(fd); + strcpy(retbuf, "Unknown error "); + strcpy(retbuf+14, itoa(err)); + return retbuf; +} diff --git a/libc-0.0.4/error/liberror.txt b/libc-0.0.4/error/liberror.txt new file mode 100644 index 0000000..2b510bd --- /dev/null +++ b/libc-0.0.4/error/liberror.txt @@ -0,0 +1,121 @@ +1 Operation not permitted +2 No such file or directory +3 No such process +4 Interrupted system call +5 I/O error +6 No such device or address +7 Arg list too long +8 Exec format error +9 Bad file number +10 No child processes +11 Try again +12 Out of memory +13 Permission denied +14 Bad address +15 Block device required +16 Device or resource busy +17 File exists +18 Cross-device link +19 No such device +20 Not a directory +21 Is a directory +22 Invalid argument +23 File table overflow +24 Too many open files +25 Not a typewriter +26 Text file busy +27 File too large +28 No space left on device +29 Illegal seek +30 Read-only file system +31 Too many links +32 Broken pipe +33 Math argument out of domain of func +34 Math result not representable +35 Resource deadlock would occur +36 File name too long +37 No record locks available +38 Function not implemented +39 Directory not empty +40 Too many symbolic links encountered +41 Operation would block +42 No message of desired type +43 Identifier removed +44 Channel number out of range +45 Level 2 not synchronized +46 Level 3 halted +47 Level 3 reset +48 Link number out of range +49 Protocol driver not attached +50 No CSI structure available +51 Level 2 halted +52 Invalid exchange +53 Invalid request descriptor +54 Exchange full +55 No anode +56 Invalid request code +57 Invalid slot +58 File locking deadlock error +59 Bad font file format +60 Device not a stream +61 No data available +62 Timer expired +63 Out of streams resources +64 Machine is not on the network +65 Package not installed +66 Object is remote +67 Link has been severed +68 Advertise error +69 Srmount error +70 Communication error on send +71 Protocol error +72 Multihop attempted +73 RFS specific error +74 Not a data message +75 Value too large for defined data type +76 Name not unique on network +77 File descriptor in bad state +78 Remote address changed +79 Can not access a needed shared library +80 Accessing a corrupted shared library +81 .lib section in a.out corrupted +82 Attempting to link in too many shared libraries +83 Cannot exec a shared library directly +84 Illegal byte sequence +85 Interrupted system call should be restarted +86 Streams pipe error +87 Too many users +88 Socket operation on non-socket +89 Destination address required +90 Message too long +91 Protocol wrong type for socket +92 Protocol not available +93 Protocol not supported +94 Socket type not supported +95 Operation not supported on transport endpoint +96 Protocol family not supported +97 Address family not supported by protocol +98 Address already in use +99 Cannot assign requested address +100 Network is down +101 Network is unreachable +102 Network dropped connection because of reset +103 Software caused connection abort +104 Connection reset by peer +105 No buffer space available +106 Transport endpoint is already connected +107 Transport endpoint is not connected +108 Cannot send after transport endpoint shutdown +109 Too many references: cannot splice +110 Connection timed out +111 Connection refused +112 Host is down +113 No route to host +114 Operation already in progress +115 Operation now in progress +116 Stale NFS file handle +117 Structure needs cleaning +118 Not a XENIX named type file +119 No XENIX semaphores available +120 Is a named type file +121 Remote I/O error diff --git a/libc-0.0.4/error/perror.c b/libc-0.0.4/error/perror.c new file mode 100644 index 0000000..f9b0965 --- /dev/null +++ b/libc-0.0.4/error/perror.c @@ -0,0 +1,19 @@ + +#include <errno.h> + +void +perror(str) +__const char * str; +{ + register char * ptr; + if(str) + { + write(2, str, strlen(str)); + write(2, ": ", 2); + } + else write(2, "perror: ", 8); + + ptr = strerror(errno); + write(2, ptr, strlen(ptr)); + write(2, "\n", 1); +} diff --git a/libc-0.0.4/error/sys_errlist.c b/libc-0.0.4/error/sys_errlist.c new file mode 100644 index 0000000..1d9e65b --- /dev/null +++ b/libc-0.0.4/error/sys_errlist.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1996 Robert de Bath <robert@debath.thenet.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is a flash way of auto-initing the error array from an external file + * I wouldn't be surprised tho if it's a lot better just to hard code the + * error messages into the array. + * + * Of course the best of all is to use strerror(). + */ + +#ifdef __AS386_16__ +#define NR_ERRORS 128 + +extern char **__sys_errlist; +extern int __sys_nerr; + +char *sys_errlist[NR_ERRORS]; +int sys_nerr = NR_ERRORS; + +#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 + .word no_op ! Space filler cause segs are padded to 4 bytes. + .text ! So the function after is also in the correct seg. +#endasm + +static void init_vars() +{ + char inbuf[256]; + char errbuf[80]; + int i, cc, fd, err, len, bufoff=0; + char * ptr; + + fd = open("/usr/lib/liberror.txt", 0); + if( fd < 0 ) return; + + for(i=0; i<NR_ERRORS; i++) sys_errlist[i] = "Unknown error"; + + while( (cc=read(fd, inbuf, sizeof(inbuf))) > 0 ) + { + for(i=0; i<cc; i++) + { + if( inbuf[i] == '\n' ) + { + errbuf[bufoff] = '\0'; + err = atoi(errbuf); + ptr = strchr(errbuf, ' '); + if( ptr && err > 0 && err < NR_ERRORS ) + { + while(*ptr == ' ') ptr++; + len = strlen(ptr)+1; + sys_errlist[err] = (void*)sbrk(len); + if( (int)sys_errlist[err] == -1 ) + { + sys_errlist[err] == ""; + break; + } + memcpy(sys_errlist[err], ptr, len); + } + bufoff = 0; + } + else if( bufoff < sizeof(errbuf)-1 ) + errbuf[bufoff++] = inbuf[i]; + } + } + close(fd); + + __sys_errlist = sys_errlist; + __sys_nerr = sys_nerr = NR_ERRORS; +} + +#endif /* __AS386_16__ */ diff --git a/libc-0.0.4/error/sys_siglist.c b/libc-0.0.4/error/sys_siglist.c new file mode 100644 index 0000000..8f502f6 --- /dev/null +++ b/libc-0.0.4/error/sys_siglist.c @@ -0,0 +1,38 @@ + +#include <signal.h> + +__const char * __const sys_siglist[NSIG] = +{ + "Unknown signal", + "Hangup", + "Interrupt", + "Quit", + "Illegal instruction", + "Trace/breakpoint trap", + "IOT trap/Abort", + "Bus error", + "Floating point exception", + "Killed", + "User defined signal 1", + "Segmentation fault", + "User defined signal 2", + "Broken pipe", + "Alarm clock", + "Terminated", + "Stack fault", + "Child exited", + "Continued", + "Stopped (signal)", + "Stopped", + "Stopped (tty input)", + "Stopped (tty output)", + "Possible I/O", + "CPU time limit exceeded", + "File size limit exceeded", + "Virtual time alarm", + "Profile signal", + "Window size changed", + "File lock lost", + "Power failure", + "Unused signal" +}; diff --git a/libc-0.0.4/grp/Makefile b/libc-0.0.4/grp/Makefile new file mode 100644 index 0000000..9c01e23 --- /dev/null +++ b/libc-0.0.4/grp/Makefile @@ -0,0 +1,41 @@ +# Copyright (C) 1996 Nat Friedman <ndf@aleph1.mit.edu> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +ifeq ($(PLATFORM),i386-Linux) +CFLAGS+=$(WALL) +else # ifeq ($(PLATFORM),i86-ELKS) +CFLAGS=$(CCFLAGS) $(LIBDEFS) -ansi +endif + +GSRC=__getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c initgroups.c \ + config-grp.h +GOBJ=__getgrent.o grent.o getgrnam.o getgrgid.o fgetgrent.o initgroups.o + +all: $(GOBJ) + +%.o: %.c config-grp.h + $(CC) $(CFLAGS) -o $@ $< -c + +$(LIBC): $(GOBJ) + ar r ../$(LIBC) $(GOBJ) + @touch libc.a + +test: test_grp.c libgrp.a + $(CC) $(CFLAGS) test_grp.c -o test_grp -L -lgrp # -static + +libgrp: libgrp.a + +libgrp.a: $(GOBJ) + ar r libgrp.a $(GOBJ) + ranlib libgrp.a + +clean: + rm -f $(GOBJ) libc.a libgrp.a + + + + diff --git a/libc-0.0.4/grp/__getgrent.c b/libc-0.0.4/grp/__getgrent.c new file mode 100644 index 0000000..ed46163 --- /dev/null +++ b/libc-0.0.4/grp/__getgrent.c @@ -0,0 +1,168 @@ +/* + * __getgrent.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <malloc.h> +#include <grp.h> +#include "config-grp.h" + +/* + * This is the core group-file read function. It behaves exactly like + * getgrent() except that it is passed a file descriptor, and getgrent() + * is just a wrapper for this function. + */ +struct group * +__getgrent(int grp_fd) +{ +#ifndef GR_SCALE_DYNAMIC + static char line_buff[GR_MAX_LINE_LEN]; + static char * members[GR_MAX_MEMBERS]; +#else + static char * line_buff = NULL; + static char ** members = NULL; +#endif + static struct group group; + register char * ptr; + char * field_begin; + char * endptr; + short member_num; + short line_index; + + + /* We use the restart label to handle malformatted lines */ +restart: + line_index=0; + +#ifndef GR_SCALE_DYNAMIC + *line_buff='\0'; + /* Read the line into the static buffer */ + while (1) + { + if (read(grp_fd, &line_buff[line_index], 1)<=0) + return NULL; + if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' || + *line_buff=='\t') + { + while (line_buff[line_index]!='\n' && + read(grp_fd, &line_buff[line_index], 1)==1); + goto restart; + } + if (line_buff[line_index]=='\n') + { + line_buff[line_index]='\0'; + break; + } + line_index++; + if (line_index==GR_MAX_LINE_LEN) + { + while (line_buff[line_index]!='\n' && + read(grp_fd, &line_buff[line_index], 1)==1); + return NULL; + } + } + +#else /* !GR_SCALE_DYNAMIC */ + line_buff=realloc(line_buff, 1); + while (1) + { + if (read(grp_fd, &line_buff[line_index], 1)<=0) + return NULL; + if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' || + *line_buff=='\t') + { + while (line_buff[line_index]!='\n' && + read(grp_fd, &line_buff[line_index], 1)==1); + goto restart; + } + if (line_buff[line_index]=='\n') + { + line_buff[line_index]='\0'; + break; + } + line_index++; + line_buff=realloc(line_buff, line_index+1); + } +#endif /* GR_SCALE_DYNAMIC */ + + /* Now parse the line */ + group.gr_name=line_buff; + ptr=strchr(line_buff, ':'); + if (ptr==NULL) goto restart; + *ptr++='\0'; + + group.gr_passwd=ptr; + ptr=strchr(ptr, ':'); + if (ptr==NULL) goto restart; + *ptr++='\0'; + + field_begin=ptr; + ptr=strchr(ptr, ':'); + if (ptr==NULL) goto restart; + *ptr++='\0'; + + group.gr_gid=(gid_t) strtoul(field_begin, &endptr, 10); + if (*endptr!='\0') goto restart; + + member_num=0; + field_begin=ptr; + +#ifndef GR_SCALE_DYNAMIC + while ((ptr=strchr(ptr, ','))!=NULL) + { + *ptr='\0'; + ptr++; + members[member_num]=field_begin; + field_begin=ptr; + member_num++; + } + if (*field_begin=='\0') + members[member_num]=NULL; + else + { + members[member_num]=field_begin; + members[member_num+1]=NULL; + } +#else /* !GR_SCALE_DYNAMIC */ + if (members!=NULL) + free (members); + members=(char **) malloc(1*sizeof(char *)); + while ((ptr=strchr(ptr, ','))!=NULL) + { + *ptr='\0'; + ptr++; + members[member_num]=field_begin; + field_begin=ptr; + member_num++; + members=(char **)realloc((void *)members, (member_num+1)*sizeof(char *)); + } + if (*field_begin=='\0') + members[member_num]=NULL; + else + { + members[member_num]=field_begin; + members[member_num+1]=NULL; + } +#endif /* GR_SCALE_DYNAMIC */ + + group.gr_mem=members; + return &group; +} diff --git a/libc-0.0.4/grp/config-grp.h b/libc-0.0.4/grp/config-grp.h new file mode 100644 index 0000000..337d54b --- /dev/null +++ b/libc-0.0.4/grp/config-grp.h @@ -0,0 +1,65 @@ +/* + * config-grp.h - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef _CONFIG_GRP_H +#define _CONFIG_GRP_H + +/* + * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer + * so that lines of any length can be used. On very very small systems, + * you may want to leave this undefined becasue it will make the grp functions + * somewhat larger (because of the inclusion of malloc and the code necessary). + * On larger systems, you will want to define this, because grp will _not_ + * deal with long lines gracefully (they will be skipped). + */ +#define GR_SCALE_DYNAMIC + +#ifndef GR_SCALE_DYNAMIC +/* + * If scaling is not dynamic, the buffers will be statically allocated, and + * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of + * characters per line in the group file. GR_MAX_MEMBERS is the maximum + * number of members of any given group. + */ +#define GR_MAX_LINE_LEN 128 +/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ +#define GR_MAX_MEMBERS 11 + +#endif /* !GR_SCALE_DYNAMIC */ + + +/* + * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate + * space for it's GID array before calling setgroups(). This is probably + * unnecessary scalage, so it's undefined by default. + */ +#undef GR_DYNAMIC_GROUP_LIST + +#ifndef GR_DYNAMIC_GROUP_LIST +/* + * GR_MAX_GROUPS is the size of the static array initgroups() uses for + * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. + */ +#define GR_MAX_GROUPS 64 + +#endif /* !GR_DYNAMIC_GROUP_LIST */ + +#endif /* !_CONFIG_GRP_H */ diff --git a/libc-0.0.4/grp/fgetgrent.c b/libc-0.0.4/grp/fgetgrent.c new file mode 100644 index 0000000..800236f --- /dev/null +++ b/libc-0.0.4/grp/fgetgrent.c @@ -0,0 +1,35 @@ +/* + * fgetgrent.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <errno.h> +#include <grp.h> + +struct group * +fgetgrent(FILE * file) +{ + if (file==NULL) + { + errno=EINTR; + return NULL; + } + + return __getgrent(fileno(file)); +} diff --git a/libc-0.0.4/grp/getgrgid.c b/libc-0.0.4/grp/getgrgid.c new file mode 100644 index 0000000..c1dd20e --- /dev/null +++ b/libc-0.0.4/grp/getgrgid.c @@ -0,0 +1,48 @@ +/* + * getgrgid.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <grp.h> + +struct group * +getgrgid(const gid_t gid) +{ + struct group * group; + int grp_fd; + + if ((grp_fd=open("/etc/group", O_RDONLY))<0) + return NULL; + + while ((group=__getgrent(grp_fd))!=NULL) + if (group->gr_gid==gid) + { + close(grp_fd); + return group; + } + + close(grp_fd); + return NULL; +} + + + + diff --git a/libc-0.0.4/grp/getgrnam.c b/libc-0.0.4/grp/getgrnam.c new file mode 100644 index 0000000..e6c27fc --- /dev/null +++ b/libc-0.0.4/grp/getgrnam.c @@ -0,0 +1,51 @@ +/* + * getgrnam.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <grp.h> + +struct group * +getgrnam(const char * name) +{ + int grp_fd; + struct group * group; + + if (name==NULL) + { + errno=EINVAL; + return NULL; + } + + if ((grp_fd=open("/etc/group", O_RDONLY))<0) + return NULL; + + while ((group=__getgrent(grp_fd))!=NULL) + if (!strcmp(group->gr_name, name)) + { + close(grp_fd); + return group; + } + + close(grp_fd); + return NULL; +} diff --git a/libc-0.0.4/grp/grent.c b/libc-0.0.4/grp/grent.c new file mode 100644 index 0000000..19d618b --- /dev/null +++ b/libc-0.0.4/grp/grent.c @@ -0,0 +1,57 @@ +/* + * grent.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * setgrent(), endgrent(), and getgrent() are mutually-dependent functions, + * so they are all included in the same object file, and thus all linked + * in together. + */ + +#include <unistd.h> +#include <fcntl.h> +#include <grp.h> + +static int grp_fd=-1; + +void +setgrent(void) +{ + if (grp_fd!=-1) + close(grp_fd); + grp_fd=open("/etc/group", O_RDONLY); +} + +void +endgrent(void) +{ + if (grp_fd!=-1) + close(grp_fd); + grp_fd=-1; +} + +struct group * +getgrent(void) +{ + if (grp_fd==-1) + return NULL; + return __getgrent(grp_fd); +} + + diff --git a/libc-0.0.4/grp/initgroups.c b/libc-0.0.4/grp/initgroups.c new file mode 100644 index 0000000..df3ffa8 --- /dev/null +++ b/libc-0.0.4/grp/initgroups.c @@ -0,0 +1,80 @@ +/* + * initgroups.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <grp.h> +#include "config-grp.h" + +int +initgroups(__const char * user, gid_t gid) +{ + register struct group * group; +#ifndef GR_DYNAMIC_GROUP_LIST + gid_t group_list[GR_MAX_GROUPS]; +#else + gid_t * group_list=NULL; +#endif + register char ** tmp_mem; + int num_groups; + int grp_fd; + + + if ((grp_fd=open("/etc/group", O_RDONLY))<0) + return -1; + + num_groups=0; +#ifdef GR_DYNAMIC_GROUP_LIST + group_list=(gid_t *) realloc(group_list, 1); +#endif + group_list[num_groups]=gid; +#ifndef GR_DYNAMIC_GROUP_LIST + while (num_groups<GR_MAX_GROUPS && + (group=__getgrent(grp_fd))!=NULL) +#else + while ((group=__getgrent(grp_fd))!=NULL) +#endif + { + if (group->gr_gid!=gid); + { + tmp_mem=group->gr_mem; + while(*tmp_mem!=NULL) + { + if (!strcmp(*tmp_mem, user)) + { + num_groups++; +#ifdef GR_DYNAMIC_GROUP_LIST + group_list=(gid_t *)realloc(group_list, + num_groups*sizeof(gid_t *)); +#endif + group_list[num_groups]=group->gr_gid; + } + tmp_mem++; + } + } + } + close(grp_fd); + return setgroups(num_groups, group_list); +} + + + + diff --git a/libc-0.0.4/grp/test_grp.c b/libc-0.0.4/grp/test_grp.c new file mode 100644 index 0000000..b5ecd36 --- /dev/null +++ b/libc-0.0.4/grp/test_grp.c @@ -0,0 +1,107 @@ +/* + * test_grp.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <grp.h> + +int +main(int argc, char ** argv) +{ + struct group * group; + char ** tmp_mem; + int test_gid; + + fprintf(stderr, "Beginning test of libc/grp...\n"); + + fprintf(stderr, "=> Testing setgrent(), getgrent(), endgrent()...\n"); + fprintf(stderr, "-> setgrent()...\n"); + setgrent(); + fprintf(stderr, "-> getgrent()...\n"); + printf("********************************************************************************\n"); + while ((group=getgrent())!=NULL) + { + printf("gr_name\t\t: %s\n", group->gr_name); + printf("gr_passwd\t: %s\n", group->gr_passwd); + printf("gr_gid\t\t: %d\n", (int) group->gr_gid); + printf("gr_mem\t\t: "); + fflush(stdout); + tmp_mem=group->gr_mem; + while(*tmp_mem!=NULL) + { + printf("%s, ", *tmp_mem); + tmp_mem++; + } + printf("\n********************************************************************************\n"); + } + fprintf(stderr, "-> endgrent()...\n"); + endgrent(); + fprintf(stderr, "=> Test of setgrent(), getgrent(), endgrent() complete.\n"); + fprintf(stderr, "=> Testing getgrid(), getgrnam()...\n"); + fprintf(stderr, "-> getgrgid()...\n"); + printf("********************************************************************************\n"); + for(test_gid=0;test_gid<100;test_gid++) + { + fprintf(stderr, "-> getgrgid(%d)...\n", test_gid); + group=getgrgid((gid_t) test_gid); + if (group!=NULL) + { + printf("gr_name\t: %s\n", group->gr_name); + printf("gr_passwd\t: %s\n", group->gr_passwd); + printf("gr_gid\t: %d\n", (int) group->gr_gid); + printf("gr_mem\t\t: "); + fflush(stdout); + tmp_mem=group->gr_mem; + while(*tmp_mem!=NULL) + { + printf("%s, ", *tmp_mem); + tmp_mem++; + } + } + printf("\n********************************************************************************\n"); + } + fprintf(stderr, "-> getgrnam()...\n"); + group=getgrnam("root"); + if (group==NULL) + { + printf(">NULL<\n"); + } + else + { + printf("gr_name\t: %s\n", group->gr_name); + printf("gr_passwd\t: %s\n", group->gr_passwd); + printf("gr_gid\t: %d\n", (int) group->gr_gid); + printf("gr_mem\t\t: "); + fflush(stdout); + tmp_mem=group->gr_mem; + while(*tmp_mem!=NULL) + { + printf("%s, ", *tmp_mem); + tmp_mem++; + } + printf("\n"); + } + + + return 0; +} + + diff --git a/libc-0.0.4/include/a.out.h b/libc-0.0.4/include/a.out.h new file mode 100644 index 0000000..f6a7b94 --- /dev/null +++ b/libc-0.0.4/include/a.out.h @@ -0,0 +1,115 @@ +/* Copyright (C) 1990-1996 + * This file is part of the ld86 command for Linux-86 + * It is distributed under the GNU Library General Public License. + * + * - This may actually be BSD or Minix code, can someone clarify please. -RDB + */ + +#ifndef __AOUT_H +#define __AOUT_H + +struct exec { /* a.out header */ + unsigned char a_magic[2]; /* magic number */ + unsigned char a_flags; /* flags, see below */ + unsigned char a_cpu; /* cpu id */ + unsigned char a_hdrlen; /* length of header */ + unsigned char a_unused; /* reserved for future use */ + unsigned short a_version; /* version stamp (not used at present) */ + 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 */ + long a_entry; /* entry point */ + long a_total; /* total memory allocated */ + long a_syms; /* size of symbol table */ + + /* SHORT FORM ENDS HERE */ + long a_trsize; /* text relocation size */ + long a_drsize; /* data relocation size */ + long a_tbase; /* text relocation base */ + long a_dbase; /* data relocation base */ +}; + +#define A_MAGIC0 (unsigned char) 0x01 +#define A_MAGIC1 (unsigned char) 0x03 +#define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 ||(X).a_magic[1] != A_MAGIC1) + +/* CPU Id of TARGET machine (byte order coded in low order two bits) */ +#define A_NONE 0x00 /* unknown */ +#define A_I8086 0x04 /* intel i8086/8088 */ +#define A_M68K 0x0B /* motorola m68000 */ +#define A_NS16K 0x0C /* national semiconductor 16032 */ +#define A_I80386 0x10 /* intel i80386 */ +#define A_SPARC 0x17 /* Sun SPARC */ + +#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */ +#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ + +/* Flags. */ +#define A_UZP 0x01 /* unmapped zero page (pages) */ +#define A_PAL 0x02 /* page aligned executable */ +#define A_NSYM 0x04 /* new style symbol table */ +#define A_EXEC 0x10 /* executable */ +#define A_SEP 0x20 /* separate I/D */ +#define A_PURE 0x40 /* pure text */ +#define A_TOVLY 0x80 /* text overlay */ + +/* Offsets of various things. */ +#define A_MINHDR 32 +#define A_TEXTPOS(X) ((long)(X).a_hdrlen) +#define A_DATAPOS(X) (A_TEXTPOS(X) + (X).a_text) +#define A_HASRELS(X) ((X).a_hdrlen > (unsigned char) A_MINHDR) +#define A_HASEXT(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 8)) +#define A_HASLNS(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16)) +#define A_HASTOFF(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24)) +#define A_TRELPOS(X) (A_DATAPOS(X) + (X).a_data) +#define A_DRELPOS(X) (A_TRELPOS(X) + (X).a_trsize) +#define A_SYMPOS(X) (A_TRELPOS(X) + (A_HASRELS(X) ? \ + ((X).a_trsize + (X).a_drsize) : 0)) + +struct reloc { + long r_vaddr; /* virtual address of reference */ + unsigned short r_symndx; /* internal segnum or extern symbol num */ + unsigned short r_type; /* relocation type */ +}; + +/* r_tyep values: */ +#define R_ABBS 0 +#define R_RELLBYTE 2 +#define R_PCRBYTE 3 +#define R_RELWORD 4 +#define R_PCRWORD 5 +#define R_RELLONG 6 +#define R_PCRLONG 7 +#define R_REL3BYTE 8 +#define R_KBRANCHE 9 + +/* r_symndx for internal segments */ +#define S_ABS ((unsigned short)-1) +#define S_TEXT ((unsigned short)-2) +#define S_DATA ((unsigned short)-3) +#define S_BSS ((unsigned short)-4) + +struct nlist { /* symbol table entry */ + char n_name[24]; /* symbol name */ + long n_value; /* value */ + unsigned char n_sclass; /* storage class */ + unsigned char n_numaux; /* number of auxiliary entries (not used) */ + unsigned short n_type; /* language base and derived type (not used) */ +}; + +/* Low bits of storage class (section). */ +#define N_SECT 07 /* section mask */ +#define N_UNDF 00 /* undefined */ +#define N_ABS 01 /* absolute */ +#define N_TEXT 02 /* text */ +#define N_DATA 03 /* data */ +#define N_BSS 04 /* bss */ +#define N_COMM 05 /* (common) */ + +/* High bits of storage class. */ +#define N_CLASS 0370 /* storage class mask */ +#define C_NULL +#define C_EXT 0020 /* external symbol */ +#define C_STAT 0030 /* static */ + +#endif /* _AOUT_H */ diff --git a/libc-0.0.4/include/ar.h b/libc-0.0.4/include/ar.h new file mode 100644 index 0000000..c608371 --- /dev/null +++ b/libc-0.0.4/include/ar.h @@ -0,0 +1,18 @@ +#ifndef __AR_H +#define __AR_H + +#define ARMAG "!<arch>\n" +#define SARMAG 8 +#define ARFMAG "`\n" + +struct ar_hdr { + char ar_name[16], + ar_date[12], + ar_uid[6], + ar_gid[6], + ar_mode[8], + ar_size[10], + ar_fmag[2]; +}; + +#endif /* __AR_H */ diff --git a/libc-0.0.4/include/assert.h b/libc-0.0.4/include/assert.h new file mode 100644 index 0000000..c58c57f --- /dev/null +++ b/libc-0.0.4/include/assert.h @@ -0,0 +1,23 @@ +#ifdef __ASSERT_H +#define __ASSERT_H +#include <features.h> + +/* If NDEBUG is defined, do nothing. + If not, and EXPRESSION is zero, print an error message and abort. */ + +#ifdef NDEBUG + +#define assert(expr) ((void) 0) + +#else /* Not NDEBUG. */ + +extern void __assert __P((const char *, const char *, int)); + +#define assert(expr) \ + ((void) ((expr) || \ + (__assert (__STRING(expr), \ + __FILE__, __LINE__), 0))) + +#endif /* NDEBUG. */ + +#endif /* __ASSERT_H */ diff --git a/libc-0.0.4/include/ctype.h b/libc-0.0.4/include/ctype.h new file mode 100644 index 0000000..038659f --- /dev/null +++ b/libc-0.0.4/include/ctype.h @@ -0,0 +1,37 @@ +/* + * ctype.h Character classification and conversion + */ + +#ifndef __CTYPE_H +#define __CTYPE_H + +extern unsigned char _ctype[]; + +#define __CT_d 0x01 /* numeric digit */ +#define __CT_u 0x02 /* upper case */ +#define __CT_l 0x04 /* lower case */ +#define __CT_c 0x08 /* control character */ +#define __CT_s 0x10 /* whitespace */ +#define __CT_p 0x20 /* punctuation */ +#define __CT_x 0x40 /* hexadecimal */ + +#define toupper(c) (islower(c) ? (c)^0x20 : (c)) +#define tolower(c) (isupper(c) ? (c)^0x20 : (c)) +#define _toupper(c) ((c)^0x20) +#define _tolower(c) ((c)^0x20) +#define toascii(c) ((c)&0x7F) + +#define isalnum(c) (_ctype[(int) c]&(__CT_u|__CT_l|__CT_d)) +#define isalpha(c) (_ctype[(int) c]&(__CT_u|__CT_l)) +#define isascii(c) !((c)&~0x7F) +#define iscntrl(c) (_ctype[(int) c]&__CT_c) +#define isdigit(c) (_ctype[(int) c]&__CT_d) +#define isgraph(c) !(_ctype[(int) c]&(__CT_c|__CT_s)) +#define islower(c) (_ctype[(int) c]&__CT_l) +#define isprint(c) !(_ctype[(int) c]&__CT_c) +#define ispunct(c) (_ctype[(int) c]&__CT_p) +#define isspace(c) (_ctype[(int) c]&__CT_s) +#define isupper(c) (_ctype[(int) c]&__CT_u) +#define isxdigit(c) (_ctype[(int) c]&__CT_x) + +#endif /* __CTYPE_H */ diff --git a/libc-0.0.4/include/dirent.h b/libc-0.0.4/include/dirent.h new file mode 100644 index 0000000..0a931b9 --- /dev/null +++ b/libc-0.0.4/include/dirent.h @@ -0,0 +1,45 @@ + +#ifndef __DIRENT_H +#define __DIRENT_H + +#include <features.h> +#include <sys/types.h> + +#ifndef MAXNAMLEN +#define MAXNAMLEN 255 +#endif + +/* Directory stream type. */ +typedef struct { + int dd_fd; /* file descriptor */ + int dd_loc; /* offset in buffer */ + int dd_size; /* # of valid entries in buffer */ + struct dirent *dd_buf; /* -> directory buffer */ +} DIR; /* stream data from opendir() */ + +struct dirent { + long d_ino; + off_t d_off; + unsigned short d_reclen; + char d_name[MAXNAMLEN+1]; +}; + +extern DIR *opendir __P ((__const char *__name)); +extern int closedir __P ((DIR * __dirp)); +extern struct dirent *readdir __P ((DIR * __dirp)); +extern void rewinddir __P ((DIR * __dirp)); + +extern void seekdir __P ((DIR * __dirp, __off_t __pos)); +extern off_t telldir __P ((DIR * __dirp)); + +/* Scan the directory DIR, calling SELECT on each directory entry. + Entries for which SELECT returns nonzero are individually malloc'd, + sorted using qsort with CMP, and collected in a malloc'd array in + *NAMELIST. Returns the number of entries selected, or -1 on error. */ +extern int scandir __P ((__const char *__dir, + struct dirent ***__namelist, + __dir_select_fn_t __select, + __dir_compar_fn_t __compar)); + +#endif /* dirent.h */ + diff --git a/libc-0.0.4/include/dos.h b/libc-0.0.4/include/dos.h new file mode 100644 index 0000000..28575b4 --- /dev/null +++ b/libc-0.0.4/include/dos.h @@ -0,0 +1,34 @@ + +#ifndef __DOS_H +#define __DOS_H +#include <features.h> + +union REGS +{ + struct { unsigned int ax, bx, cx, dx, si, di, cflag; } x; + struct { unsigned char al, ah, bl, bh, cl, ch, dl, dh; } h; +}; + +struct SREGS +{ + unsigned int es, cs, ss, ds; +}; + +extern unsigned int __envseg; +extern unsigned int __psp; +char * __fconv __P((char * fname)); + +unsigned int __segalloc __P((unsigned int paracount)); +void __setvect __P((int i, long j)); +long __getvect __P((int vecno)); + +unsigned int __get_ds __P((void)); +unsigned int __get_es __P((void)); +void __set_es __P((unsigned int seg)); +int __peek_es __P((unsigned int off)); +int __deek_es __P((unsigned int off)); + +#define movedata __movedata + +#endif + diff --git a/libc-0.0.4/include/errno.h b/libc-0.0.4/include/errno.h new file mode 100644 index 0000000..c8d2002 --- /dev/null +++ b/libc-0.0.4/include/errno.h @@ -0,0 +1,25 @@ +#ifndef __ERRNO_H +#define __ERRNO_H + +#include <features.h> +#include <linuxmt/errno.h> + +#ifdef __USE_BSD +extern int sys_nerr; +extern char *sys_errlist[]; +#endif +#ifdef __USE_GNU +extern int _sys_nerr; +extern char *_sys_errlist[]; +#endif + +extern int errno; + +__BEGIN_DECLS + +extern void perror __P ((__const char* __s)); +extern char* strerror __P ((int __errno)); + +__END_DECLS + +#endif diff --git a/libc-0.0.4/include/fcntl.h b/libc-0.0.4/include/fcntl.h new file mode 100644 index 0000000..ddd9afc --- /dev/null +++ b/libc-0.0.4/include/fcntl.h @@ -0,0 +1,20 @@ +#ifndef __FCNTL_H +#define __FCNTL_H + +#include <features.h> +#include <sys/types.h> +#include <linuxmt/fcntl.h> + +#ifndef FNDELAY +#define FNDELAY O_NDELAY +#endif + +__BEGIN_DECLS + +extern int creat __P ((__const char * __filename, mode_t __mode)); +extern int fcntl __P ((int __fildes,int __cmd, ...)); +extern int open __P ((__const char * __filename, int __flags, ...)); + +__END_DECLS + +#endif diff --git a/libc-0.0.4/include/features.h b/libc-0.0.4/include/features.h new file mode 100644 index 0000000..11eb610 --- /dev/null +++ b/libc-0.0.4/include/features.h @@ -0,0 +1,36 @@ + +#ifndef __FEATURES_H +#define __FEATURES_H + +#ifdef __STDC__ + +#define __P(x) x +#define __const const + +/* Almost ansi */ +#if __STDC__ != 1 +#define const +#define volatile +#endif + +#else /* K&R */ + +#define __P(x) () +#define __const +#define const +#define volatile + +#endif + +/* No C++ */ +#define __BEGIN_DECLS +#define __END_DECLS + +/* GNUish things */ +#define __CONSTVALUE +#define __CONSTVALUE2 + +#include <sys/cdefs.h> + +#endif + diff --git a/libc-0.0.4/include/getopt.h b/libc-0.0.4/include/getopt.h new file mode 100644 index 0000000..0d71ff6 --- /dev/null +++ b/libc-0.0.4/include/getopt.h @@ -0,0 +1,17 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#ifndef __GETOPT_H +#define __GETOPT_H + +#include <features.h> + +extern char *optarg; +extern int opterr; +extern int optind; + +extern int getopt __P((int argc, char *const *argv, const char *shortopts)); + +#endif /* __GETOPT_H */ diff --git a/libc-0.0.4/include/grp.h b/libc-0.0.4/include/grp.h new file mode 100644 index 0000000..96b2b4b --- /dev/null +++ b/libc-0.0.4/include/grp.h @@ -0,0 +1,37 @@ +#ifndef __GRP_H +#define __GRP_H + +#include <sys/types.h> +#include <features.h> +#include <stdio.h> + +/* The group structure */ +struct group +{ + char *gr_name; /* Group name. */ + char *gr_passwd; /* Password. */ + gid_t gr_gid; /* Group ID. */ + char **gr_mem; /* Member list. */ +}; + +extern void setgrent __P ((void)); +extern void endgrent __P ((void)); +extern struct group * getgrent __P ((void)); + +extern struct group * getgrgid __P ((__const gid_t gid)); +extern struct group * getgrnam __P ((__const char * name)); + +extern struct group * fgetgrent __P ((FILE * file)); + +extern int setgroups __P ((size_t n, __const gid_t * groups)); +extern int initgroups __P ((__const char * user, gid_t gid)); + + +#ifdef __LIBC__ +extern struct group * __getgrent __P ((int grp_fd)); +#endif + +#endif /* _GRP_H */ + + + diff --git a/libc-0.0.4/include/limits.h b/libc-0.0.4/include/limits.h new file mode 100644 index 0000000..579287e --- /dev/null +++ b/libc-0.0.4/include/limits.h @@ -0,0 +1,33 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#ifndef __LIMITS_H +#define __LIMITS_H + +#if __AS386_16__ +#define MB_LEN_MAX 1 /* Longest multi-byte character */ +#define CHAR_MAX 127 /* maximum char value */ +#define CHAR_MIN (-127) /* mimimum char value */ +#define SCHAR_MAX 127 /* maximum signed char value */ +#define SCHAR_MIN (-127) /* minimum signed char value */ +#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 INT_MAX 32767 /* maximum (signed) int value */ +#define INT_MIN (-32767) /* minimum (signed) int value */ +#define LONG_MAX 2147483647 /* maximum (signed) long value */ +#define LONG_MIN (-2147483647) /* minimum (signed) long value */ +#define UCHAR_MAX 255 /* maximum unsigned char value */ +#define USHRT_MAX 0xffff /* maximum unsigned short value */ +#define UINT_MAX 0xffff /* maximum unsigned int value */ +#define ULONG_MAX 0xffffffff /* maximum unsigned long value */ +#ifndef RAND_MAX +#define RAND_MAX INT_MAX +#endif +#else +#error "Limits.h not implemented" +#endif + +#endif diff --git a/libc-0.0.4/include/linuxmt b/libc-0.0.4/include/linuxmt new file mode 120000 index 0000000..45fae66 --- /dev/null +++ b/libc-0.0.4/include/linuxmt @@ -0,0 +1 @@ +../kinclude/linuxmt
\ No newline at end of file diff --git a/libc-0.0.4/include/malloc.h b/libc-0.0.4/include/malloc.h new file mode 100644 index 0000000..c00fa21 --- /dev/null +++ b/libc-0.0.4/include/malloc.h @@ -0,0 +1,29 @@ + +#ifndef __MALLOC_H +#define __MALLOC_H +#include <features.h> + +/* + * Mini malloc allows you to use a less efficient but smaller malloc the + * cost is about 100 bytes of code in free but malloc (700bytes) doesn't + * have to be linked. Unfortunatly memory can only be reused if everything + * above it has been freed + * + */ + +void free __P((void *)); +void *malloc __P((unsigned int)); +void *realloc __P((void *, unsigned int)); +void *alloca __P((unsigned int)); + +extern void *(*__alloca_alloc) __P((unsigned int)); + +#ifdef __LIBC__ +#define __MINI_MALLOC__ +#endif + +#ifdef __MINI_MALLOC__ +#define malloc(x) ((*__alloca_alloc)(x)) +#endif + +#endif diff --git a/libc-0.0.4/include/memory.h b/libc-0.0.4/include/memory.h new file mode 100644 index 0000000..3b2f590 --- /dev/null +++ b/libc-0.0.4/include/memory.h @@ -0,0 +1 @@ +#include <string.h> diff --git a/libc-0.0.4/include/paths.h b/libc-0.0.4/include/paths.h new file mode 100644 index 0000000..58bade7 --- /dev/null +++ b/libc-0.0.4/include/paths.h @@ -0,0 +1,20 @@ +/* paths.h <ndf@linux.mit.edu> */ + +#ifndef ___PATHS_H +#define ___PATHS_H + + +#define _PATH_CONSOLE "/dev/console" +#define _PATH_TTY "/dev/tty" +#define _PATH_NOLOGIN "/etc/nologin" +#define _PATH_LOGIN "/bin/login" +#define _PATH_BSHELL "/bin/sh" +#define _PATH_UTMP "/var/run/utmp" +#define _PATH_WTMP "/var/log/wtmp" +#define _PATH_DEFPATH "/bin:/usr/bin:/usr/local/bin:." +#define _PATH_DEV "/dev/" +#define _PATH_TMP "/tmp/" +#define _PATH_LASTLOG "/var/log/lastlog" +#define _PATH_LOCALE "/usr/lib/locale" + +#endif /* __PATHS_H */ diff --git a/libc-0.0.4/include/pwd.h b/libc-0.0.4/include/pwd.h new file mode 100644 index 0000000..1b48c6a --- /dev/null +++ b/libc-0.0.4/include/pwd.h @@ -0,0 +1,40 @@ +#ifndef __PWD_H +#define __PWD_H + +#include <sys/types.h> +#include <features.h> +#include <stdio.h> + +/* The passwd structure. */ +struct passwd +{ + char *pw_name; /* Username. */ + char *pw_passwd; /* Password. */ + uid_t pw_uid; /* User ID. */ + gid_t pw_gid; /* Group ID. */ + char *pw_gecos; /* Real name. */ + char *pw_dir; /* Home directory. */ + char *pw_shell; /* Shell program. */ +}; + + +extern void setpwent __P ((void)); +extern void endpwent __P ((void)); +extern struct passwd * getpwent __P ((void)); + +extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); +extern int getpw __P ((uid_t uid, char *buf)); + +extern struct passwd * fgetpwent __P ((FILE * file)); + +extern struct passwd * getpwuid __P ((__const uid_t)); +extern struct passwd * getpwnam __P ((__const char *)); + +#ifdef __LIBC__ +extern struct passwd * __getpwent __P ((__const int passwd_fd)); +#endif + +#endif /* pwd.h */ + + + diff --git a/libc-0.0.4/include/regexp.h b/libc-0.0.4/include/regexp.h new file mode 100644 index 0000000..73d6bf4 --- /dev/null +++ b/libc-0.0.4/include/regexp.h @@ -0,0 +1,21 @@ +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + */ +#define NSUBEXP 10 +typedef struct regexp { + char *startp[NSUBEXP]; + char *endp[NSUBEXP]; + char regstart; /* Internal use only. */ + char reganch; /* Internal use only. */ + char *regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + char program[1]; /* Unwarranted chumminess with compiler. */ +} regexp; + +extern regexp *regcomp(); +extern int regexec(); +extern void regsub(); +extern void regerror(); diff --git a/libc-0.0.4/include/regmagic.h b/libc-0.0.4/include/regmagic.h new file mode 100644 index 0000000..5acf447 --- /dev/null +++ b/libc-0.0.4/include/regmagic.h @@ -0,0 +1,5 @@ +/* + * The first byte of the regexp internal "program" is actually this magic + * number; the start node begins in the second byte. + */ +#define MAGIC 0234 diff --git a/libc-0.0.4/include/search.h b/libc-0.0.4/include/search.h new file mode 100644 index 0000000..b9c8a17 --- /dev/null +++ b/libc-0.0.4/include/search.h @@ -0,0 +1,94 @@ +/* Copyright (C) 1993 Ulrich Drepper + +This file is intended to be included in the GNU C Library and the +Linux C Library. So the copyright notice will be: + + +Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + +For now the file can be distributed under the LGPL. */ + +#ifndef _SEARCH_H +#define _SEARCH_H + +#include <features.h> + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + +__BEGIN_DECLS + +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T +typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t)); +#endif + +/* for use with hsearch(3) */ + +typedef struct entry { char *key; char *data; } ENTRY; +typedef enum { FIND, ENTER } ACTION; + +extern ENTRY * hsearch __P((ENTRY __item, ACTION __action)); +extern int hcreate __P((unsigned __nel)); +extern void hdestroy __P((void)); + + +/* The tsearch routines are very interesting. They make many + * assumptions about the compiler. It assumpts that the first field + * in node must be the "key" field, which points to the datum. + * Everything depends on that. It is a very tricky stuff. H.J. + */ +/* For tsearch */ +typedef enum { preorder, postorder, endorder, leaf } VISIT; + +extern void *tsearch __P((__const void * __key, void **__rootp, + __compar_fn_t compar)); + +extern void *tfind __P((__const void * __key, __const void ** __rootp, + __compar_fn_t compar)); + +extern void *tdelete __P((__const void * __key, void ** __rootp, + __compar_fn_t compar)); + +#ifndef __ACTION_FN_T +#define __ACTION_FN_T +/* FYI, the first argument should be a pointer to "key". + * Please read the man page for details. + */ +typedef void (*__action_fn_t) __P((__const void *__nodep, + __const VISIT __value, + __const int __level)); +#endif + +extern void twalk __P((__const void * __root, __action_fn_t action)); + + +extern void * lfind __P((__const void * __key, __const void * __base, + size_t * __nmemb, size_t __size, + __compar_fn_t __compar)); + +extern void * lsearch __P((__const void * __key, __const void * __base, + size_t * __nmemb, size_t __size, + __compar_fn_t __compar)); + +__END_DECLS + +#endif /* search.h */ diff --git a/libc-0.0.4/include/setjmp.h b/libc-0.0.4/include/setjmp.h new file mode 100644 index 0000000..c2bfadb --- /dev/null +++ b/libc-0.0.4/include/setjmp.h @@ -0,0 +1,26 @@ + +#ifndef __SETJMP_H +#define __SETJMP_H + +#include <features.h> + +/* + * I know most systems use an array of ints here, but I prefer this - RDB + */ + +typedef struct +{ + unsigned int pc; + unsigned int sp; + unsigned int bp; + unsigned int si; + unsigned int di; +} jmp_buf[1]; + +int setjmp __P((jmp_buf env)); +void longjmp __P((jmp_buf env, int rv)); + +/* LATER: Seems GNU beat me to it, must be OK then :-) + * Humm, what's this about setjmp being a macro !? + */ +#endif diff --git a/libc-0.0.4/include/sgtty.h b/libc-0.0.4/include/sgtty.h new file mode 100644 index 0000000..9e26956 --- /dev/null +++ b/libc-0.0.4/include/sgtty.h @@ -0,0 +1 @@ +#include <termios.h> diff --git a/libc-0.0.4/include/signal.h b/libc-0.0.4/include/signal.h new file mode 100644 index 0000000..1d54fc3 --- /dev/null +++ b/libc-0.0.4/include/signal.h @@ -0,0 +1,85 @@ + +#ifndef __SIGNAL_H +#define __SIGNAL_H +#include <features.h> + +typedef unsigned long sigset_t; /* at least 32 bits */ + +#define _NSIG 32 +#define NSIG _NSIG + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGUNUSED 31 + +/* + * sa_flags values: SA_STACK is not currently supported, but will allow the + * usage of signal stacks by using the (now obsolete) sa_restorer field in + * the sigaction structure as a stack pointer. This is now possible due to + * the changes in signal handling. LBT 010493. + * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the + * SA_RESTART flag to get restarting signals (which were the default long ago) + */ +#define SA_NOCLDSTOP 1 +#define SA_STACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_INTERRUPT 0x20000000 +#define SA_NOMASK 0x40000000 +#define SA_ONESHOT 0x80000000 + +#define SIG_BLOCK 0 /* for blocking signals */ +#define SIG_UNBLOCK 1 /* for unblocking signals */ +#define SIG_SETMASK 2 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__sighandler_t)(/* int */); + +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ + +struct sigaction { + __sighandler_t sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)( /*void*/ ); +}; + +/* BSDisms */ +extern __const char * __const sys_siglist[]; +#define sig_t __sighandler_t + +#endif diff --git a/libc-0.0.4/include/stdarg.h b/libc-0.0.4/include/stdarg.h new file mode 100644 index 0000000..978529b --- /dev/null +++ b/libc-0.0.4/include/stdarg.h @@ -0,0 +1,38 @@ + /* + * @(#) stdarg.h 1.2 91/11/30 21:10:39 + * + * Sample stdarg.h file for use with the unproto filter. + * + * This file serves two purposes. + * + * 1 - As an include file for use with ANSI-style C source that implements + * variadic functions. + * + * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is + * defined, its value will appear in the place of the "..." in argument + * lists of variadic function *definitions* (not declarations). + * + * Compilers that pass arguments via the stack can use the default code at the + * end of this file (this usually applies for the VAX, MC68k and 80*86 + * architectures). + * + * RISC-based systems often need special tricks. An example of the latter is + * given for the SPARC architecture. Read your /usr/include/varargs.h for + * more information. + * + * You can use the varargs.c program provided with the unproto package to + * verify that the stdarg.h file has been set up correctly. + */ + +#ifdef sparc +# define _VA_ALIST_ "__builtin_va_alist" + typedef char *va_list; +# define va_start(ap, p) (ap = (char *) &__builtin_va_alist) +# define va_arg(ap, type) ((type *) __builtin_va_arg_incr((type *) ap))[0] +# define va_end(ap) +#else /* vax, mc68k, 80*86 */ + typedef char *va_list; +# define va_start(ap, p) (ap = (char *) (&(p)+1)) +# define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1] +# define va_end(ap) +#endif diff --git a/libc-0.0.4/include/stddef.h b/libc-0.0.4/include/stddef.h new file mode 100644 index 0000000..112c18f --- /dev/null +++ b/libc-0.0.4/include/stddef.h @@ -0,0 +1,26 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +/* We don't care, ignore GCC's __need hackery */ + +#undef __need_wchar_t +#undef __need_size_t +#undef __need_ptrdiff_t +#undef __need_NULL + +#if __AS386_16__ /* Only for 8086 */ +#ifndef __STDDEF_H +#define __STDDEF_H + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif +#endif diff --git a/libc-0.0.4/include/stdio.h b/libc-0.0.4/include/stdio.h new file mode 100644 index 0000000..ba70b1d --- /dev/null +++ b/libc-0.0.4/include/stdio.h @@ -0,0 +1,125 @@ + +#ifndef __STDIO_H +#define __STDIO_H + +#include <features.h> +#include <sys/types.h> + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#define _IOFBF 0x00 /* full buffering */ +#define _IOLBF 0x01 /* line buffering */ +#define _IONBF 0x02 /* no buffering */ +#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ + +#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ +#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ + +#define __MODE_READ 0x10 /* Opened in read only */ +#define __MODE_WRITE 0x20 /* Opened in write only */ +#define __MODE_RDWR 0x30 /* Opened in read/write */ + +#define __MODE_READING 0x40 /* Buffer has pending read data */ +#define __MODE_WRITING 0x80 /* Buffer has pending write data */ + +#define __MODE_EOF 0x100 /* EOF status */ +#define __MODE_ERR 0x200 /* Error status */ +#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ + +#ifdef __MSDOS__ +#define __MODE_IOTRAN 0x1000 /* MSDOS nl <-> cr,nl translation */ +#else +#define __MODE_IOTRAN 0 +#endif + +/* when you add or change fields here, be sure to change the initialization + * in stdio_init and fopen */ +struct __stdio_file { + unsigned char *bufpos; /* the next byte to write to or read from */ + unsigned char *bufread; /* the end of data returned by last read() */ + unsigned char *bufwrite; /* highest address writable by macro */ + unsigned char *bufstart; /* the start of the buffer */ + unsigned char *bufend; /* the end of the buffer; ie the byte after the last + malloc()ed byte */ + + int fd; /* the file descriptor associated with the stream */ + int mode; + + char unbuf[8]; /* The buffer for 'unbuffered' streams */ + + struct __stdio_file * next; +}; + +#define EOF (-1) +#ifndef NULL +#define NULL (0) +#endif + +typedef struct __stdio_file FILE; + +#define BUFSIZ (256) + +extern FILE stdin[1]; +extern FILE stdout[1]; +extern FILE stderr[1]; + +#ifdef __MSDOS__ +#define putc(c, fp) fputc(c, fp) +#define getc(fp) fgetc(fp) +#else +#define putc(c, stream) \ + (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream)) \ + : (unsigned char) (*(stream)->bufpos++ = (c)) ) + +#define getc(stream) \ + (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \ + (*(stream)->bufpos++)) +#endif + +#define putchar(c) putc((c), stdout) +#define getchar() getc(stdin) + +#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) +#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) +#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0) +#define fileno(fp) ((fp)->fd) + +/* declare functions; not like it makes much difference without ANSI */ +/* RDB: The return values _are_ important, especially if we ever use + 8086 'large' model + */ + +/* These two call malloc */ +#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) +extern int setvbuf __P((FILE*, char*, int, size_t)); + +/* These don't */ +#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) +extern void setbuffer __P((FILE*, char*, int)); + +extern int fgetc __P((FILE*)); +extern int fputc __P((int, FILE*)); + +extern int fclose __P((FILE*)); +extern int fflush __P((FILE*)); +extern char *fgets __P((char*, size_t, FILE*)); +extern FILE *__fopen __P((char*, int, FILE*, char*)); + +#define fopen(__file, __mode) __fopen((__file), -1, (FILE*)0, (__mode)) +#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode)) +#define fdopen(__file, __mode) __fopen((char*)0, (__file), (FILE*)0, (__mode)) + +extern int fputs __P((char*, FILE*)); +extern int puts __P((char*)); + +extern int printf __P ((__const char*, ...)); +extern int fprintf __P ((FILE*, __const char*, ...)); +extern int sprintf __P ((char*, __const char*, ...)); + +#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos) + +#endif /* __STDIO_H */ diff --git a/libc-0.0.4/include/stdlib.h b/libc-0.0.4/include/stdlib.h new file mode 100644 index 0000000..9f235d8 --- /dev/null +++ b/libc-0.0.4/include/stdlib.h @@ -0,0 +1,30 @@ +/* stdlib.h <ndf@linux.mit.edu> */ +#include <features.h> +#include <sys/types.h> + +#ifndef __STDLIB_H +#define __STDLIB_H + +/* Don't overwrite user definitions of NULL */ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +/* For program termination */ +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +extern void * malloc __P ((size_t size)); +extern void * calloc __P ((size_t nmemb, size_t size)); +extern void free __P ((void * ptr)); +extern void * realloc __P ((void * ptr, size_t size)); + +extern int rand __P ((void)); +extern void srand __P ((unsigned int seed)); + +extern long strtol __P ((const char * nptr, char ** endptr, int base)); +extern unsigned long strtoul __P ((const char * nptr, + char ** endptr, int base)); +extern double strtod __P ((const char * nptr, char ** endptr)); + +#endif /* __STDLIB_H */ diff --git a/libc-0.0.4/include/string.h b/libc-0.0.4/include/string.h new file mode 100644 index 0000000..8be8eff --- /dev/null +++ b/libc-0.0.4/include/string.h @@ -0,0 +1,52 @@ + +#ifndef __STRING_H +#define __STRING_H +#include <features.h> +#include <stddef.h> + +/* Basic string functions */ +extern size_t strlen __P ((__const char* __str)); + +extern char * strcat __P ((char*, __const char*)); +extern char * strcpy __P ((char*, __const char*)); +extern int strcmp __P ((__const char*, __const char*)); + +extern char * strncat __P ((char*, char*, size_t)); +extern char * strncpy __P ((char*, char*, size_t)); +extern int strncmp __P ((__const char*, __const char*, size_t)); + +extern char * strchr __P ((char*, int)); +extern char * strrchr __P ((char*, int)); +extern char * strdup __P ((char*)); + +/* Basic mem functions */ +extern void * memcpy __P ((void*, __const void*, size_t)); +extern void * memccpy __P ((void*, void*, int, size_t)); +extern void * memchr __P ((__const void*, __const int, size_t)); +extern void * memset __P ((void*, int, size_t)); +extern int memcmp __P ((__const void*, __const void*, size_t)); + +extern void * memmove __P ((void*, void*, size_t)); + +/* Minimal (very!) locale support */ +#define strcoll strcmp +#define strxfrm strncpy + +/* BSDisms */ +#define index strchr +#define rindex strrchr + +/* Other common BSD functions */ +extern int strcasecmp __P ((char*, char*)); +extern int strncasecmp __P ((char*, char*, size_t)); +char *strpbrk __P ((char *, char *)); +char *strsep __P ((char **, char *)); +char *strstr __P ((char *, char *)); +char *strtok __P ((char *, char *)); +size_t strcspn __P ((char *, char *)); +size_t strspn __P ((char *, char *)); + +/* Linux silly hour */ +char *strfry __P ((char *)); + +#endif diff --git a/libc-0.0.4/include/strings.h b/libc-0.0.4/include/strings.h new file mode 100644 index 0000000..3b2f590 --- /dev/null +++ b/libc-0.0.4/include/strings.h @@ -0,0 +1 @@ +#include <string.h> diff --git a/libc-0.0.4/include/sys/cdefs.h b/libc-0.0.4/include/sys/cdefs.h new file mode 100644 index 0000000..366b0c6 --- /dev/null +++ b/libc-0.0.4/include/sys/cdefs.h @@ -0,0 +1,33 @@ + +#ifndef __SYS_CDEFS_H +#define __SYS_CDEFS_H +#include <features.h> + +#if defined (__STDC__) && __STDC__ + +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x + +/* This is not a typedef so `const __ptr_t' does the right thing. */ +#define __ptr_t void * +typedef long double __long_double_t; + +#else + +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#define __ptr_t char * +typedef double __long_double_t; + +#endif + +/* No C++ */ +#define __BEGIN_DECLS +#define __END_DECLS + +/* GNUish things */ +#define __CONSTVALUE +#define __CONSTVALUE2 + +#endif diff --git a/libc-0.0.4/include/sys/errno.h b/libc-0.0.4/include/sys/errno.h new file mode 100644 index 0000000..339f4fc --- /dev/null +++ b/libc-0.0.4/include/sys/errno.h @@ -0,0 +1 @@ +#include <errno.h> diff --git a/libc-0.0.4/include/sys/fcntl.h b/libc-0.0.4/include/sys/fcntl.h new file mode 100644 index 0000000..cd30455 --- /dev/null +++ b/libc-0.0.4/include/sys/fcntl.h @@ -0,0 +1 @@ +#include <fcntl.h> diff --git a/libc-0.0.4/include/sys/file.h b/libc-0.0.4/include/sys/file.h new file mode 100644 index 0000000..2401b15 --- /dev/null +++ b/libc-0.0.4/include/sys/file.h @@ -0,0 +1,35 @@ +#ifndef _SYS_FILE_H +#define _SYS_FILE_H + +#include <features.h> +#include <fcntl.h> + +#ifndef L_SET + +#define L_SET 0 /* absolute offset */ +#define L_INCR 1 /* relative to current offset */ +#define L_XTND 2 /* relative to end of file */ + +#endif + +#ifndef LOCK_SH + +/* Operations for the `flock' call. */ +#define LOCK_SH 1 /* Shared lock. */ +#define LOCK_EX 2 /* Exclusive lock. */ +#define LOCK_UN 8 /* Unlock. */ + +/* Can be OR'd in to one of the above. */ +#define LOCK_NB 4 /* Don't block when locking. */ + +#endif + +__BEGIN_DECLS + +/* Apply or remove an advisory lock, according to OPERATION, + on the file FD refers to. */ +extern int flock __P ((int __fd, int __operation)); + +__END_DECLS + +#endif diff --git a/libc-0.0.4/include/sys/ioctl.h b/libc-0.0.4/include/sys/ioctl.h new file mode 100644 index 0000000..55e5882 --- /dev/null +++ b/libc-0.0.4/include/sys/ioctl.h @@ -0,0 +1,9 @@ + +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H +#include <features.h> +#include <linuxmt/ioctl.h> + +extern int ioctl __P((int __fildes, int __cmd, ...)); + +#endif diff --git a/libc-0.0.4/include/sys/param.h b/libc-0.0.4/include/sys/param.h new file mode 100644 index 0000000..1a31d1f --- /dev/null +++ b/libc-0.0.4/include/sys/param.h @@ -0,0 +1,18 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#ifndef _PARAM_H +#define _PARAM_H + +#include <limits.h> + +#ifndef NR_OPEN +#define NR_OPEN 32 +#endif +#ifndef NR_FILE +#define NR_FILE 32 +#endif + +#endif diff --git a/libc-0.0.4/include/sys/signal.h b/libc-0.0.4/include/sys/signal.h new file mode 100644 index 0000000..2e602da --- /dev/null +++ b/libc-0.0.4/include/sys/signal.h @@ -0,0 +1 @@ +#include <signal.h> diff --git a/libc-0.0.4/include/sys/stat.h b/libc-0.0.4/include/sys/stat.h new file mode 100644 index 0000000..4a4bdbd --- /dev/null +++ b/libc-0.0.4/include/sys/stat.h @@ -0,0 +1,27 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include <linuxmt/stat.h> +#include <sys/types.h> +#include <features.h> + +struct stat +{ + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; + +int stat __P((__const char * __path, struct stat * __statbuf)); +int lstat __P((__const char * __path, struct stat * __statbuf)); +int fstat __P((int __fd, struct stat * __statbuf)); + +#endif diff --git a/libc-0.0.4/include/sys/types.h b/libc-0.0.4/include/sys/types.h new file mode 100644 index 0000000..7b7de09 --- /dev/null +++ b/libc-0.0.4/include/sys/types.h @@ -0,0 +1,2 @@ +#include <stddef.h> +#include <linuxmt/types.h> diff --git a/libc-0.0.4/include/sys/wait.h b/libc-0.0.4/include/sys/wait.h new file mode 100644 index 0000000..70a0e4a --- /dev/null +++ b/libc-0.0.4/include/sys/wait.h @@ -0,0 +1,2 @@ + +/** FIXME **/ diff --git a/libc-0.0.4/include/termcap.h b/libc-0.0.4/include/termcap.h new file mode 100644 index 0000000..a7ae37b --- /dev/null +++ b/libc-0.0.4/include/termcap.h @@ -0,0 +1,21 @@ + +#ifndef _TERMCAP_H +#define _TERMCAP_H + +#include <features.h> +#include <sys/types.h> + +extern char PC; +extern char *UP; +extern char *BC; +extern int ospeed; + +extern int tgetent __P((char *, const char *)); +extern int tgetflag __P((const char *)); +extern int tgetnum __P((const char *)); +extern char *tgetstr __P((const char *, char **)); + +extern int tputs __P((const char *, int, int (*)(int))); +extern char *tgoto __P((const char *, int, int)); + +#endif /* _TERMCAP_H */ diff --git a/libc-0.0.4/include/termio.h b/libc-0.0.4/include/termio.h new file mode 100644 index 0000000..9e26956 --- /dev/null +++ b/libc-0.0.4/include/termio.h @@ -0,0 +1 @@ +#include <termios.h> diff --git a/libc-0.0.4/include/termios.h b/libc-0.0.4/include/termios.h new file mode 100644 index 0000000..4ca1ec8 --- /dev/null +++ b/libc-0.0.4/include/termios.h @@ -0,0 +1,24 @@ +#ifndef __TERMIOS_H +#define __TERMIOS_H + +#include <features.h> +#include <sys/types.h> +#include <linuxmt/termios.h> + +extern int cfgetispeed __P ((struct termios *__termios_p)); +extern int cfgetospeed __P ((struct termios *__termios_p)); +extern int cfsetispeed __P ((struct termios *__termios_p, speed_t __speed)); +extern int cfsetospeed __P ((struct termios *__termios_p, speed_t __speed)); + +extern void cfmakeraw __P ((struct termios *__t)); + +extern int tcsetattr __P ((int __fd, int __opt, struct termios *__termios_p)); +extern int tcgetattr __P ((int __fildes, struct termios *__termios_p)); +extern int tcdrain __P ((int __fildes)); +extern int tcflow __P ((int __fildes, int __action)); +extern int tcflush __P ((int __fildes, int __queue_selector)); +extern int tcsendbreak __P ((int __fildes, int __duration)); +extern pid_t tcgetpgrp __P ((int __fildes)); +extern int tcsetpgrp __P ((int __fildes, pid_t __pgrp_id)); + +#endif diff --git a/libc-0.0.4/include/time.h b/libc-0.0.4/include/time.h new file mode 100644 index 0000000..b9eb87c --- /dev/null +++ b/libc-0.0.4/include/time.h @@ -0,0 +1,61 @@ +#ifndef __TIME_H +#define __TIME_H + +#include <features.h> +#include <sys/types.h> +#include <stddef.h> + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef long clock_t; +#endif + +#define CLOCKS_PER_SEC 100 +#define CLK_TCK 100 /* That must be the same as HZ ???? */ + +struct timeval { + long tv_sec; + long tv_usec; +}; + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + +extern char *tzname[2]; +extern int daylight; +extern long int timezone; + +__BEGIN_DECLS + +extern int stime __P ((time_t* __tptr)); + +extern clock_t clock __P ((void)); +extern time_t time __P ((time_t * __tp)); +extern __CONSTVALUE double difftime __P ((time_t __time2, + time_t __time1)) __CONSTVALUE2; +extern time_t mktime __P ((struct tm * __tp)); + +extern char * asctime __P ((__const struct tm * __tp)); +extern char * ctime __P ((__const time_t * __tp)); +extern size_t strftime __P ((char * __s, size_t __smax, + __const char * __fmt, __const struct tm * __tp)); +extern void tzset __P ((void)); + +extern struct tm* gmtime __P ((__const time_t *__tp)); +extern struct tm* localtime __P ((__const time_t * __tp)); + +__END_DECLS + +#endif diff --git a/libc-0.0.4/include/unistd.h b/libc-0.0.4/include/unistd.h new file mode 100644 index 0000000..c283a38 --- /dev/null +++ b/libc-0.0.4/include/unistd.h @@ -0,0 +1,34 @@ +/* unistd.h <ndf@linux.mit.edu> */ +#include <features.h> +#include <sys/types.h> + +#ifndef __UNISTD_H +#define __UNISTD_H + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +extern int close __P ((int)); +extern size_t read __P ((int __fd, char * __buf, size_t __nbytes)); +extern size_t write __P ((int __fd, __const char * __buf, size_t __n)); +extern off_t lseek __P ((int __fd, off_t __n, int __whence)); +extern int pipe __P ((int __pipedes[2])); +extern unsigned int alarm __P ((unsigned int __seconds)); +extern unsigned int sleep __P ((unsigned int __seconds)); +extern int pause __P ((void)); + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef R_OK +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ +#endif + +#endif /* __UNISTD_H */ diff --git a/libc-0.0.4/include/utime.h b/libc-0.0.4/include/utime.h new file mode 100644 index 0000000..7f82b9f --- /dev/null +++ b/libc-0.0.4/include/utime.h @@ -0,0 +1,15 @@ +#ifndef __UTIME_H +#define __UTIME_H + +#include <features.h> +#include <sys/types.h> + +struct utimbuf { + time_t actime; + time_t modtime; +}; + +extern int utime __P ((char *__filename, struct utimbuf *__utimebuf)); + +#endif + diff --git a/libc-0.0.4/include/utmp.h b/libc-0.0.4/include/utmp.h new file mode 100644 index 0000000..ca630a3 --- /dev/null +++ b/libc-0.0.4/include/utmp.h @@ -0,0 +1,48 @@ +/* utmp.h <ndf@linux.mit.edu> */ + +#ifndef __UTMP_H +#define __UTMP_H + +#include <features.h> +#include <sys/types.h> +#include <paths.h> +#include <time.h> + +#define UT_UNKNOWN 0 +#define UT_LINESIZE 12 +#define UT_NAMESIZE 8 +#define UT_HOSTSIZE 16 + +#define RUN_LVL 1 +#define BOOT_TIME 2 +#define NEW_TIME 3 +#define OLD_TIME 4 + +#define INIT_PROCESS 5 +#define LOGIN_PROCESS 6 +#define USER_PROCESS 7 +#define DEAD_PROCESS 8 + +struct utmp +{ + short ut_type; /* type of login */ + pid_t ut_pid; /* pid of login-process */ + char ut_line[UT_LINESIZE]; /* devicename of tty -"/dev/", null-term */ + char ut_id[2]; /* abbrev. ttyname, as 01, s1 etc. */ + time_t ut_time; /* logintime */ + char ut_user[UT_NAMESIZE]; /* username, not null-term */ + char ut_host[UT_HOSTSIZE]; /* hostname for remote login... */ + long ut_addr; /* IP addr of remote host */ + +}; + +extern void setutent __P ((void)); +extern void utmpname __P ((__const char *)); +extern struct utmp *getutent __P ((void)); +extern struct utmp *getutid __P ((struct utmp *)); +extern struct utmp *getutline __P ((struct utmp *)); +extern void pututline __P ((struct utmp *)); +extern struct utmp *_getutline __P ((struct utmp *)); +extern void endutent __P ((void)); + +#endif /* __UTMP_H */ diff --git a/libc-0.0.4/include/varargs.h b/libc-0.0.4/include/varargs.h new file mode 100644 index 0000000..b5c647f --- /dev/null +++ b/libc-0.0.4/include/varargs.h @@ -0,0 +1,12 @@ + +#ifndef __VARARGS_H +#define __VARARGS_H + +typedef char *va_list; + +#define va_dcl va_list va_alist; +#define va_start(ap) ap = (va_list)&va_alist +#define va_arg(ap,t) ((t *)(ap += sizeof(t)))[-1] +#define va_end(ap) ap = NULL + +#endif diff --git a/libc-0.0.4/kinclude/Config b/libc-0.0.4/kinclude/Config new file mode 100644 index 0000000..f3d064f --- /dev/null +++ b/libc-0.0.4/kinclude/Config @@ -0,0 +1 @@ +kinc: The kernel include files diff --git a/libc-0.0.4/kinclude/arch/errno.h b/libc-0.0.4/kinclude/arch/errno.h new file mode 100644 index 0000000..ee3fcab --- /dev/null +++ b/libc-0.0.4/kinclude/arch/errno.h @@ -0,0 +1,127 @@ +#ifndef _I86_ERRNO_H +#define _I86_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ +#define EDEADLOCK 58 /* File locking deadlock error */ +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#endif diff --git a/libc-0.0.4/kinclude/arch/ioctl.h b/libc-0.0.4/kinclude/arch/ioctl.h new file mode 100644 index 0000000..55b276b --- /dev/null +++ b/libc-0.0.4/kinclude/arch/ioctl.h @@ -0,0 +1,9 @@ +/* + * Nothing here yet. + */ + +#ifndef _ASMI86_IOCTL_H +#define _ASMI86_IOCTL_H + + +#endif /* _ASMI86_IOCTL_H */ diff --git a/libc-0.0.4/kinclude/arch/types.h b/libc-0.0.4/kinclude/arch/types.h new file mode 100644 index 0000000..d6690d1 --- /dev/null +++ b/libc-0.0.4/kinclude/arch/types.h @@ -0,0 +1,48 @@ +/* arch/i86/include/asm/types.h - Basic Linux/MT data types. */ + +#ifndef LINUXMT_8086_TYPES +#define LINUXMT_8086_TYPES + +/* First we define all of the __u and __s types...*/ + +typedef unsigned char __u8; +typedef unsigned char * __pu8; +typedef char __s8; +typedef char * __ps8; + +typedef unsigned int __u16; +typedef unsigned int * __pu16; +typedef int __s16; +typedef int * __ps16; + +typedef unsigned long __u32; +typedef unsigned long * __pu32; +typedef long __s32; +typedef long * __ps32; + +/* __uint == 16bit here */ + +typedef unsigned int __uint; +typedef int __sint; +typedef unsigned int * __puint; +typedef int * __psint; + +/* Then we define registers, etc... */ + +struct _registers { + __u16 ksp, sp, ss, ax, bx, cx, dx, di, si, ds, es, bp, ip, cs, flags; +}; + +typedef struct _registers __registers; +typedef struct _registers * __pregisters; + +typedef __u32 __pptr; + +struct _mminit { + __u16 cs, endcs, ds, endds, ss, endss, lowss; +}; + +typedef struct _mminit __arch_mminit; +typedef struct _mminit * __parch_mminit; + +#endif diff --git a/libc-0.0.4/kinclude/linuxmt/errno.h b/libc-0.0.4/kinclude/linuxmt/errno.h new file mode 100644 index 0000000..b4c07a3 --- /dev/null +++ b/libc-0.0.4/kinclude/linuxmt/errno.h @@ -0,0 +1 @@ +#include "../arch/errno.h" diff --git a/libc-0.0.4/kinclude/linuxmt/fcntl.h b/libc-0.0.4/kinclude/linuxmt/fcntl.h new file mode 100644 index 0000000..d9188a1 --- /dev/null +++ b/libc-0.0.4/kinclude/linuxmt/fcntl.h @@ -0,0 +1,70 @@ +#ifndef __LINUXMT_FCNTL_H +#define __LINUXMT_FCNTL_H + +/* + * Definitions taken from the i386 Linux kernel. + */ + +/* open/fcntl */ + +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#if 0 +#define O_SYNC 010000 /* Not supported */ +#define FASYNC 020000 /* Not supported */ +#endif + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#ifdef __KERNEL__ +#define F_POSIX 1 +#define F_FLOCK 2 +#endif /* __KERNEL__ */ + +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#endif diff --git a/libc-0.0.4/kinclude/linuxmt/ioctl.h b/libc-0.0.4/kinclude/linuxmt/ioctl.h new file mode 100644 index 0000000..20f5ac6 --- /dev/null +++ b/libc-0.0.4/kinclude/linuxmt/ioctl.h @@ -0,0 +1 @@ +#include "../arch/ioctl.h" diff --git a/libc-0.0.4/kinclude/linuxmt/stat.h b/libc-0.0.4/kinclude/linuxmt/stat.h new file mode 100644 index 0000000..0eb1c0e --- /dev/null +++ b/libc-0.0.4/kinclude/linuxmt/stat.h @@ -0,0 +1,55 @@ +#ifndef _LINUX_STAT_H +#define _LINUX_STAT_H + +#ifdef __KERNEL__ + +#include "../arch/stat.h" + +#endif + +#define S_IFMT 00170000 +#ifdef __LINUXMT_NETWORK__ +#define S_IFSOCK 0140000 +#endif +#define S_IFLNK 0120000 +#define S_IFREG 0100000 +#define S_IFBLK 0060000 +#define S_IFDIR 0040000 +#define S_IFCHR 0020000 +#define S_IFIFO 0010000 +#define S_ISUID 0004000 +#define S_ISGID 0002000 +#define S_ISVTX 0001000 + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) + +#define S_IRWXU 00700 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 + +#define S_IRWXG 00070 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 + +#define S_IRWXO 00007 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +#ifdef __KERNEL__ +#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) +#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO) +#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) +#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) +#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) +#endif + +#endif diff --git a/libc-0.0.4/kinclude/linuxmt/termios.h b/libc-0.0.4/kinclude/linuxmt/termios.h new file mode 100644 index 0000000..52bde9a --- /dev/null +++ b/libc-0.0.4/kinclude/linuxmt/termios.h @@ -0,0 +1,258 @@ +#ifndef _LINUXMT_TERMIOS_H +#define _LINUXMT_TERMIOS_H +#include <linuxmt/types.h> + +/* This is just a magic number to make these relatively unique ('T') */ +#define __TERMIOS_MAJ ('T'<<8) + +#define TCGETS (__TERMIOS_MAJ+0x01) +#define TCSETS (__TERMIOS_MAJ+0x02) +#define TCSETSW (__TERMIOS_MAJ+0x03) +#define TCSETSF (__TERMIOS_MAJ+0x04) +#define TCGETA (__TERMIOS_MAJ+0x05) +#define TCSETA (__TERMIOS_MAJ+0x06) +#define TCSETAW (__TERMIOS_MAJ+0x07) +#define TCSETAF (__TERMIOS_MAJ+0x08) +#define TCSBRK (__TERMIOS_MAJ+0x09) +#define TCXONC (__TERMIOS_MAJ+0x0A) +#define TCFLSH (__TERMIOS_MAJ+0x0B) +#define TIOCEXCL (__TERMIOS_MAJ+0x0C) +#define TIOCNXCL (__TERMIOS_MAJ+0x0D) +#define TIOCSCTTY (__TERMIOS_MAJ+0x0E) +#define TIOCGPGRP (__TERMIOS_MAJ+0x0F) +#define TIOCSPGRP (__TERMIOS_MAJ+0x10) +#define TIOCOUTQ (__TERMIOS_MAJ+0x11) +#define TIOCSTI (__TERMIOS_MAJ+0x12) +#define TIOCGWINSZ (__TERMIOS_MAJ+0x13) +#define TIOCSWINSZ (__TERMIOS_MAJ+0x14) +#define TIOCMGET (__TERMIOS_MAJ+0x15) +#define TIOCMBIS (__TERMIOS_MAJ+0x16) +#define TIOCMBIC (__TERMIOS_MAJ+0x17) +#define TIOCMSET (__TERMIOS_MAJ+0x18) +#define TIOCGSOFTCAR (__TERMIOS_MAJ+0x19) +#define TIOCSSOFTCAR (__TERMIOS_MAJ+0x1A) +#define FIONREAD (__TERMIOS_MAJ+0x1B) +#define TIOCINQ FIONREAD +#define TIOCLINUX (__TERMIOS_MAJ+0x1C) +#define TIOCCONS (__TERMIOS_MAJ+0x1D) +#define TIOCGSERIAL (__TERMIOS_MAJ+0x1E) +#define TIOCSSERIAL (__TERMIOS_MAJ+0x1F) +#define TIOCPKT (__TERMIOS_MAJ+0x20) +#define FIONBIO (__TERMIOS_MAJ+0x21) +#define TIOCNOTTY (__TERMIOS_MAJ+0x22) +#define TIOCSETD (__TERMIOS_MAJ+0x23) +#define TIOCGETD (__TERMIOS_MAJ+0x24) +#define TCSBRKP (__TERMIOS_MAJ+0x25) /* Needed for POSIX tcsendbreak */ +#define TIOCTTYGSTRUCT (__TERMIOS_MAJ+0x26) /* For debugging only */ +#define FIONCLEX (__TERMIOS_MAJ+0x50) /* these numbers need to be adjusted. */ +#define FIOCLEX (__TERMIOS_MAJ+0x51) +#define FIOASYNC (__TERMIOS_MAJ+0x52) +#define TIOCSERCONFIG (__TERMIOS_MAJ+0x53) +#define TIOCSERGWILD (__TERMIOS_MAJ+0x54) +#define TIOCSERSWILD (__TERMIOS_MAJ+0x55) +#define TIOCGLCKTRMIOS (__TERMIOS_MAJ+0x56) +#define TIOCSLCKTRMIOS (__TERMIOS_MAJ+0x57) +#define TIOCSERGSTRUCT (__TERMIOS_MAJ+0x58) /* For debugging only */ +#define TIOCSERGETLSR (__TERMIOS_MAJ+0x59) /* Get line status register */ +#define TIOCSERGETMULTI (__TERMIOS_MAJ+0x5A) /* Get multiport config */ +#define TIOCSERSETMULTI (__TERMIOS_MAJ+0x5B) /* Set multiport config */ + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +/* line disciplines */ +#define N_TTY 0 +#define N_SLIP 1 +#define N_MOUSE 2 +#define N_PPP 3 + +#endif /* _LINUXMT_TERMIOS_H */ diff --git a/libc-0.0.4/kinclude/linuxmt/types.h b/libc-0.0.4/kinclude/linuxmt/types.h new file mode 100644 index 0000000..b38f81c --- /dev/null +++ b/libc-0.0.4/kinclude/linuxmt/types.h @@ -0,0 +1,31 @@ +#ifndef __LINUXMT_TYPES_H +#define __LINUXMT_TYPES_H + +#include "../arch/types.h" + +/* Throw away _FUNCTION parameters - the syntax is ripped off of Minix's + _PROTOTYPE. Considering Borland did the same thing to MFC on a bigger + scale, I don't think PH will mind :) */ + +/* Yes, this should be in arch/types.h too */ + +#define _FUNCTION(function, params) function() +#define _VFUNCTION(functiom, params) (*function) () + +typedef __u32 off_t; +typedef __u16 pid_t; +typedef __u16 uid_t; +typedef __u16 gid_t; +typedef __u32 time_t; +typedef __u16 umode_t; +typedef __u16 nlink_t; +typedef __u16 mode_t; +typedef __u32 loff_t; + +typedef __u16 dev_t; +typedef __u16 ino_t; +typedef __u32 tcflag_t; +typedef __u8 cc_t; + +#endif + diff --git a/libc-0.0.4/libc.a b/libc-0.0.4/libc.a Binary files differnew file mode 100644 index 0000000..a02a759 --- /dev/null +++ b/libc-0.0.4/libc.a diff --git a/libc-0.0.4/malloc1/Config b/libc-0.0.4/malloc1/Config new file mode 100644 index 0000000..4404398 --- /dev/null +++ b/libc-0.0.4/malloc1/Config @@ -0,0 +1 @@ +malloc: Robert's malloc routines diff --git a/libc-0.0.4/malloc1/Makefile b/libc-0.0.4/malloc1/Makefile new file mode 100644 index 0000000..d4aa9cf --- /dev/null +++ b/libc-0.0.4/malloc1/Makefile @@ -0,0 +1,24 @@ + +TOP=.. +include $(TOP)/Make.defs + +ASRC=malloc.c +AOBJ=malloc.o alloca.o free.o calloc.o realloc.o + +OBJ=$(AOBJ) + +all: $(OBJ) + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a + +$(AOBJ): $(ASRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ASRC) + +transfer: + -@rm ../include/malloc.h + cp -p malloc.h ../include/. diff --git a/libc-0.0.4/malloc1/README b/libc-0.0.4/malloc1/README new file mode 100644 index 0000000..95f5928 --- /dev/null +++ b/libc-0.0.4/malloc1/README @@ -0,0 +1,9 @@ +Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +This is a combined alloca/malloc package. It uses a classic algorithm +and so may be seen to be quite slow compared to more modern routines +with 'nasty' distributions of allocation. + +-Robert diff --git a/libc-0.0.4/malloc1/malloc.c b/libc-0.0.4/malloc1/malloc.c new file mode 100644 index 0000000..687a84b --- /dev/null +++ b/libc-0.0.4/malloc1/malloc.c @@ -0,0 +1,540 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#include <malloc.h> +#include <errno.h> + +#define MCHUNK 2048 /* Allocation unit in 'mem' elements */ +#define XLAZY_FREE /* If set frees can be infinitly defered */ +#define XMINALLOC 32 /* Smallest chunk to alloc in 'mem's */ +#define XVERBOSE /* Lots of noise, debuging ? */ + +#undef malloc +#define MAX_INT ((int)(((unsigned)-1)>>1)) + +#ifdef VERBOSE +#define noise __noise +#else +#define noise(y,x) +#endif + +typedef union mem_cell +{ + union mem_cell *next; /* A pointer to the next mem */ + unsigned int size; /* An int >= sizeof pointer */ + char *depth; /* For the alloca hack */ +} +mem; + +#define m_size(p) ((p) [0].size) /* For malloc */ +#define m_next(p) ((p) [1].next) /* For malloc and alloca */ +#define m_deep(p) ((p) [0].depth) /* For alloca */ + +extern void *__mini_malloc __P ((unsigned int)); +extern void *(*__alloca_alloc) __P ((unsigned int)); +extern mem *__freed_list; + +#ifdef L_free +/* Start the alloca with just the dumb version of malloc */ + +void *(*__alloca_alloc) __P ((unsigned int)) = __mini_malloc; +mem *__freed_list = 0; + +#ifdef VERBOSE +/* NB: Careful here, stdio may use malloc - so we can't */ +static +phex(val) +{ + static char hex[] = "0123456789ABCDEF"; + int i; + for (i = sizeof(int)*8-4; i >= 0; i -= 4) + write(2, hex + ((val >> i) & 0xF), 1); +} + +noise(y, x) +char *y; +mem *x; +{ + write(2, "Malloc ", 7); + phex(x); + write(2, " sz ", 4); + if(x) phex(m_size(x)); else phex(0); + write(2, " nxt ", 5); + if(x) phex(m_next(x)); else phex(0); + write(2, " is ", 4); + write(2, y, strlen(y)); + write(2, "\n", 1); +} +#endif + +#endif + +#ifdef L_alloca +static mem *alloca_stack = 0; + +void * +alloca(size) +unsigned size; +{ + auto char probe; /* Probes stack depth: */ + register mem *hp; + + /* + * Reclaim garbage, defined as all alloca'd storage that was allocated + * from deeper in the stack than currently. + */ + + for (hp = alloca_stack; hp != 0;) + if (m_deep(hp) < &probe) + { + register mem *np = m_next(hp); + free((void *) hp); /* Collect garbage. */ + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + alloca_stack = hp; /* -> last valid storage. */ + if (size == 0) + return 0; /* No allocation required. */ + + hp = (mem *) (*__alloca_alloc) (sizeof(mem) + size); + if (hp == 0) + return hp; + + m_next(hp) = alloca_stack; + m_deep(hp) = &probe; + alloca_stack = hp; + + /* User storage begins just after header. */ + return (void *) (hp + 2); +} +#endif /* L_alloca */ + +#ifdef L_free +void +free(ptr) +void *ptr; +{ + register mem *top; + register mem *chk = (mem *) ptr; + + if (chk == 0) + return; /* free(NULL) - be nice */ + chk--; + + try_this:; + top = (mem *) sbrk(0); + if (chk + m_size(chk) == top) + { + noise("FREE sbrk", chk); + sbrk(-m_size(chk) * sizeof(mem)); + /* + * Adding this code allow free to release blocks in any order; they + * can still only be allocated from the top of the heap tho. + */ +#ifdef __MINI_MALLOC__ + if (__alloca_alloc == __mini_malloc && __freed_list) + { + mem *prev, *curr; + chk = __freed_list; + __freed_list = m_next(__freed_list); + goto try_this; + } +#endif + } + else + { /* Nope, not sure where this goes, leave + * it for malloc to deal with */ +#ifdef __MINI_MALLOC__ + if( __freed_list || chk > __freed_list ) + { m_next(chk) = __freed_list; __freed_list = chk; } + else + { + register mem *prev; + prev=__freed_list; + for(top=__freed_list; top && top > chk; prev=top, top=m_next(top)) + ; + m_next(chk) = top; + m_next(prev) = chk; + } +#else + m_next(chk) = __freed_list; + __freed_list = chk; +#endif + noise("ADD LIST", chk); + } +} + +void * +__mini_malloc(size) +unsigned int size; +{ + register mem *ptr; + register unsigned int sz; + + /* First time round this _might_ be odd, But we won't do that! */ + sz = (unsigned int) sbrk(0); + if (sz & (sizeof(mem) - 1)) + sbrk(4 - (sz & (sizeof(mem) - 1))); + + if (size <= 0) + return 0; + /* Minor oops here, sbrk has a signed argument */ + if( size > (((unsigned)-1)>>1)-sizeof(mem)*3 ) + { + errno = ENOMEM; + return 0; + } + + size += sizeof(mem) * 2 - 1; /* Round up and leave space for size field */ + size /= sizeof(mem); + + ptr = (mem *) sbrk(size * sizeof(mem)); + if ((int) ptr == -1) + return 0; + + m_size(ptr) = size; + noise("CREATE", ptr); + return ptr + 1; +} +#endif /* L_free */ + +#ifdef L_malloc + +/* + * The chunk_list pointer is either NULL or points to a chunk in a + * circular list of all the free blocks in memory + */ + +static mem *chunk_list = 0; +static void insert_chunk(); +static mem *search_chunk(); + +void * +malloc(size) +unsigned int size; +{ + register mem *ptr = 0; + register unsigned int sz; + + if (size == 0) + return 0; /* ANSI STD */ + + sz = size + sizeof(mem) * 2 - 1; + sz /= sizeof(mem); + +#ifdef MINALLOC + if (sz < MINALLOC) + sz = MINALLOC; +#endif + +#ifdef VERBOSE + { + static mem arr[2]; + m_size(arr) = sz; + noise("WANTED", arr); + } +#endif + + __alloca_alloc = malloc; /* We'll be messing with the heap now TVM */ + +#ifdef LAZY_FREE + ptr = search_chunk(sz); + if (ptr == 0) + { +#endif + + /* First deal with the freed list */ + if (__freed_list) + { + while (__freed_list) + { + ptr = __freed_list; + __freed_list = m_next(__freed_list); + + if (m_size(ptr) == sz) /* Oh! Well that's lucky ain't it + * :-) */ + { + noise("LUCKY MALLOC", ptr); + return ptr + 1; + } + + insert_chunk(ptr); + } + ptr = m_next(chunk_list); + if (m_size(ptr) < (MAX_INT/sizeof(mem)) + && ptr + m_size(ptr) == (void *) sbrk(0)) + { + /* Time to free for real */ + m_next(chunk_list) = m_next(ptr); + if (ptr == m_next(ptr)) + chunk_list = 0; + free(ptr + 1); + } +#ifdef LAZY_FREE + ptr = search_chunk(sz); +#endif + } +#ifndef LAZY_FREE + ptr = search_chunk(sz); +#endif + if (ptr == 0) + { +#ifdef MCHUNK + unsigned int alloc; + alloc = sizeof(mem) * (MCHUNK * ((sz + MCHUNK - 1) / MCHUNK) - 1); + ptr = __mini_malloc(alloc); + if (ptr) + insert_chunk(ptr - 1); + else /* Oooo, near end of RAM */ + { + for(alloc/=2; alloc>256; ) + { + ptr = __mini_malloc(alloc); + if (ptr) insert_chunk(ptr - 1); + else alloc/=2; + } + } + ptr = search_chunk(sz); + if (ptr == 0) +#endif + { +#ifndef MCHUNK + ptr = __mini_malloc(size); +#endif +#ifdef VERBOSE + if( ptr == 0 ) + noise("MALLOC FAIL", 0); + else + noise("MALLOC NOW", ptr - 1); +#endif + return ptr; + } + } +#ifdef LAZY_FREE + } +#endif + +#ifdef VERBOSE + ptr[1].size = 0x55555555; +#endif + noise("MALLOC RET", ptr); + return ptr + 1; +} + +/* + * This function takes a pointer to a block of memory and inserts it into + * the chain of memory chunks + */ + +static void +insert_chunk(mem_chunk) +mem *mem_chunk; +{ + register mem *p1, *p2; + if (chunk_list == 0) /* Simple case first */ + { + m_next(mem_chunk) = chunk_list = mem_chunk; + noise("FIRST CHUNK", mem_chunk); + return; + } + p1 = mem_chunk; + p2 = chunk_list; + + do + { + if (p1 > p2) + { + if (m_next(p2) <= p2) + { /* We're at the top of the chain, p1 is + * higher */ + + if (p2 + m_size(p2) == p1) + { /* Good, stick 'em together */ + noise("INSERT CHUNK", mem_chunk); + m_size(p2) += m_size(p1); + noise("JOIN 1", p2); + } + else + { + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + } + return; + } + if (m_next(p2) > p1) + { + /* In chain, p1 between p2 and next */ + + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + + /* Try to join above */ + if (p1 + m_size(p1) == m_next(p1)) + { + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 2", p1); + } + /* Try to join below */ + if (p2 + m_size(p2) == p1) + { + m_size(p2) += m_size(p1); + m_next(p2) = m_next(p1); + noise("JOIN 3", p2); + } + chunk_list = p2; /* Make sure it's valid */ + return; + } + } + else if (p1 < p2) + { + if (m_next(p2) <= p2 && p1 < m_next(p2)) + { + /* At top of chain, next is bottom of chain, p1 is below next */ + + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + chunk_list = p2; + + if (p1 + m_size(p1) == m_next(p1)) + { + if (p2 == m_next(p1)) + chunk_list = p1; + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 4", p1); + } + return; + } + } + chunk_list = p2; /* Save for search */ + p2 = m_next(p2); + } + while (p2 != chunk_list); + + /* If we get here we have a problem, ignore it, maybe it'll go away */ + noise("DROPPED CHUNK", mem_chunk); +} + +/* + * This function will search for a chunk in memory of at least 'mem_size' + * when found, if the chunk is too big it'll be split, and pointer to the + * chunk returned. If none is found NULL is returned. + */ + +static mem * +search_chunk(mem_size) +unsigned int mem_size; +{ + register mem *p1, *p2; + if (chunk_list == 0) /* Simple case first */ + return 0; + + /* Search for a block >= the size we want */ + p1 = m_next(chunk_list); + p2 = chunk_list; + do + { + noise("CHECKED", p1); + if (m_size(p1) >= mem_size) + break; + + p2 = p1; + p1 = m_next(p1); + } + while (p2 != chunk_list); + + /* None found, exit */ + if (m_size(p1) < mem_size) + return 0; + + /* If it's exactly right remove it */ + if (m_size(p1) < mem_size + 2) + { + noise("FOUND RIGHT", p1); + chunk_list = m_next(p2) = m_next(p1); + if (chunk_list == p1) + chunk_list = 0; + return p1; + } + + noise("SPLIT", p1); + /* Otherwise split it */ + m_next(p2) = p1 + mem_size; + chunk_list = p2; + + p2 = m_next(p2); + m_size(p2) = m_size(p1) - mem_size; + m_next(p2) = m_next(p1); + m_size(p1) = mem_size; + if (chunk_list == p1) + chunk_list = p2; +#ifdef VERBOSE + p1[1].size = 0xAAAAAAAA; +#endif + noise("INSERT CHUNK", p2); + noise("FOUND CHUNK", p1); + noise("LIST IS", chunk_list); + return p1; +} + +#endif /* L_malloc */ + +#ifdef L_calloc +void * +calloc(elm, sz) +unsigned int elm, sz; +{ + register unsigned int v; + register void *ptr; + ptr = malloc(v = elm * sz); + if (ptr) + memset(ptr, 0, v); + return ptr; +} +#endif /* L_calloc */ + +#ifdef L_realloc +void * +realloc(ptr, size) +void *ptr; +unsigned int size; +{ + void *nptr; + unsigned int osize; + if (ptr == 0) + return malloc(size); + + osize = (m_size(((mem *) ptr) - 1) - 1) * sizeof(mem); + if (size <= osize) + { + return ptr; + } + + nptr = malloc(size); + + if (nptr == 0) + return 0; + + memcpy(nptr, ptr, osize); + free(ptr); + + return nptr; +} +#endif /* L_realloc */ diff --git a/libc-0.0.4/malloc1/malloc.h b/libc-0.0.4/malloc1/malloc.h new file mode 100644 index 0000000..c00fa21 --- /dev/null +++ b/libc-0.0.4/malloc1/malloc.h @@ -0,0 +1,29 @@ + +#ifndef __MALLOC_H +#define __MALLOC_H +#include <features.h> + +/* + * Mini malloc allows you to use a less efficient but smaller malloc the + * cost is about 100 bytes of code in free but malloc (700bytes) doesn't + * have to be linked. Unfortunatly memory can only be reused if everything + * above it has been freed + * + */ + +void free __P((void *)); +void *malloc __P((unsigned int)); +void *realloc __P((void *, unsigned int)); +void *alloca __P((unsigned int)); + +extern void *(*__alloca_alloc) __P((unsigned int)); + +#ifdef __LIBC__ +#define __MINI_MALLOC__ +#endif + +#ifdef __MINI_MALLOC__ +#define malloc(x) ((*__alloca_alloc)(x)) +#endif + +#endif diff --git a/libc-0.0.4/malloc2/Config b/libc-0.0.4/malloc2/Config new file mode 100644 index 0000000..11c476d --- /dev/null +++ b/libc-0.0.4/malloc2/Config @@ -0,0 +1 @@ +malloc: Joel's malloc functions diff --git a/libc-0.0.4/malloc2/README b/libc-0.0.4/malloc2/README new file mode 100644 index 0000000..ecf3fd2 --- /dev/null +++ b/libc-0.0.4/malloc2/README @@ -0,0 +1,19 @@ +This is just the malloc for libc. It is untested; it won't even compile +right now. In particular, __malloc_init needs some bug fixing! + +Apparently, there is another malloc that Robert Debath wrote which probably +works by now. However, I honestly think that my malloc may be just as +good when it's finished. + +In about six months, you'll probably see something like this: + + +Linux/less-than-32-bit installation program +Do you want + 1. Chad Page's kernel + 2. Alan Cox's kernel +Enter your chioce --> 2 +Do you want + 1. Robert Debath's malloc + 2. Joel Weber's malloc +[more choices for compilers, filetools, etc] diff --git a/libc-0.0.4/malloc2/makefile b/libc-0.0.4/malloc2/makefile new file mode 100644 index 0000000..8678d62 --- /dev/null +++ b/libc-0.0.4/malloc2/makefile @@ -0,0 +1,23 @@ + +TOP=.. +include $(TOP)/Make.defs + +MOBJ=malloc.o stack.o + +OBJ=$(MOBJ) + +all: $(OBJ) + +libc.a: $(OBJ) + ar r ../libc.a $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a + +$(AOBJ): $(ASRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ASRC) + +transfer: + -@rm ../include/malloc.h + cp -p malloc.h ../include/. diff --git a/libc-0.0.4/malloc2/malloc.c b/libc-0.0.4/malloc2/malloc.c new file mode 100644 index 0000000..143d324 --- /dev/null +++ b/libc-0.0.4/malloc2/malloc.c @@ -0,0 +1,127 @@ +/* simplified linux malloc.h + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <malloc.h> + +typedef struct __malloc_struct malloc_struct; + +typedef union __malloc_union +{ + char *c; + malloc_struct *m; +} malloc_union; + + +struct __malloc_struct +{ + unsigned char status; +#define ALLOC 0x53 +#define FREE 0x55 +#define END_OF_WORLD 0x57 + malloc_union next; +} *malloc_start; + +extern int __STACKSIZE; + +/* WARNING: this init will only work if there is a hard limit on the + amount of RAM that can be allocated. + */ + +#ifdef __AS386_16__ +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .word _malloc_init ! Pointer to the autorun function + .word no_op ! Space filler cause segs are padded to 4 bytes. + .text ! So the function after is also in the correct seg. +#endasm +#endif + +malloc_init() +{ + extern unsigned int sbrk(); + + unsigned int ptr, sz, count; + + malloc_start = (malloc_struct*) ((sbrk(16)+1)&~1); + malloc_start->status = FREE; + + count=254; + for(sz=16384; sz>64; ) + { + ptr= sbrk(sz); + if( ptr == (unsigned)-1 ) sz>>=1; + else count+=sz; + } + if( __STACKSIZE > count || __STACKSIZE <= 0 ) __STACKSIZE = ((count>>1)&-2); + ptr = sbrk(-__STACKSIZE); + + malloc_start->next.m = ((malloc_struct*)ptr) - 1; + + malloc_start->next.m->status = END_OF_WORLD; +} + +char *malloc(size) +size_t size; +{ + register malloc_union tmp, tmp2; + + /* Make sure we don't lose the alignment */ + size = (size+sizeof(malloc_struct)-1)/sizeof(malloc_struct); + + tmp.m = malloc_start; + while ( ( tmp.m->next.m - tmp.m - 2 ) < size + || ( tmp.m->status == ALLOC )) + tmp.m = tmp.m->next.m; + + if (tmp.m->status == FREE){ + tmp2.m = size + tmp.m + 1; + tmp2.m->status = FREE; + tmp2.m->next.c = tmp.m->next.c; + tmp.m->status = ALLOC; + tmp.m->next.c = tmp2.c; + } + else return 0; + tmp.m++; + return tmp.c; +} + +__malloc_cleanup() /* finds consecutive free blocks and joins them */ +{ + malloc_struct *tmp; + + tmp = malloc_start; + while ((tmp->status != END_OF_WORLD)&&(tmp->next.m->status != END_OF_WORLD)){ + if ((tmp->status==FREE)&&(tmp->next.m->status==FREE)) + tmp->next.m = tmp->next.m->next.m; + else tmp = tmp->next.m; + } +} + +free(what) +char *what; +{ + malloc_union tmp; + + tmp.c = what; tmp.m--; + if( tmp.m->status == ALLOC ) + { + tmp.m->status = FREE; + __malloc_cleanup; + } +} diff --git a/libc-0.0.4/malloc2/malloc.h b/libc-0.0.4/malloc2/malloc.h new file mode 100644 index 0000000..ffcb3a4 --- /dev/null +++ b/libc-0.0.4/malloc2/malloc.h @@ -0,0 +1,21 @@ +/* simplified linux malloc.h + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +char *malloc(size); +void free(what); +char *realloc(what, size); diff --git a/libc-0.0.4/malloc2/stack.c b/libc-0.0.4/malloc2/stack.c new file mode 100644 index 0000000..5f33e21 --- /dev/null +++ b/libc-0.0.4/malloc2/stack.c @@ -0,0 +1,10 @@ + +/* + * Under Linux 8086 the stack and heap areas are at the top and bottom + * of the same area of memory, this version of malloc requires that the + * malloc area is of a fixed size this means that there must also be a + * specific amount of stack space reserved outside of this. The number + * of bytes to be reserved is specified below. + */ + +int __STACKSIZE = 2048; diff --git a/libc-0.0.4/misc/Config b/libc-0.0.4/misc/Config new file mode 100644 index 0000000..9ede0c2 --- /dev/null +++ b/libc-0.0.4/misc/Config @@ -0,0 +1 @@ +misc: Various unix lib functions diff --git a/libc-0.0.4/misc/Makefile b/libc-0.0.4/misc/Makefile new file mode 100644 index 0000000..b136fc4 --- /dev/null +++ b/libc-0.0.4/misc/Makefile @@ -0,0 +1,45 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +MSRC=aliases.c +MOBJ=abs.o raise.o bcopy.o bzero.o bcmp.o index.o rindex.o remove.o creat.o + +ESRC=atexit.c +EOBJ=on_exit.o atexit.o __do_exit.o + +OBJ=$(MOBJ) $(EOBJ) \ + atoi.o atol.o ltoa.o ltostr.o \ + ctype.o qsort.o bsearch.o rand.o lsearch.o getopt.o \ + getenv.o putenv.o itoa.o cputype.o \ + strtol.o popen.o system.o + +# No ELKS strtod() until BCC does 16 bit FP... +ifeq ($(PLATFORM),i386-Linux) +OBJ+=strtod.o +endif + +all: $(OBJ) + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a + +$(MOBJ): $(MSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(MSRC) + +$(EOBJ): $(ESRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ESRC) + +strto%.o: strto%.c +ifeq ($(PLATFORM),i386-Linux) + $(CC) $(CFLAGS) $< -c -o $@ $(WALL) +else + $(CC) $(CFLAGS) $< -c -o $@ -ansi +endif diff --git a/libc-0.0.4/misc/aliases.c b/libc-0.0.4/misc/aliases.c new file mode 100644 index 0000000..466cb74 --- /dev/null +++ b/libc-0.0.4/misc/aliases.c @@ -0,0 +1,109 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <sys/types.h> + +#ifdef L_abs +int +abs(arg1) +int arg1; +{ + return arg1>0?arg1:-arg1; +} +#endif + +#ifdef L_raise +int +raise(signo) +int signo; +{ + return kill(getpid(), signo); +} +#endif + +#ifdef L_bcopy +#undef bcopy +void +bcopy(src, dest, len) +void * src, *dest; +unsigned int len; +{ + (void) memcpy(dest, src, len); +} +#endif + +#ifdef L_bzero +#undef bzero +void +bzero(dest, len) +void *dest; +unsigned int len; +{ + (void) memset(dest, '\0', len); +} +#endif + +#ifdef L_bcmp +#undef bcmp +int +bcmp(dest, src, len) +void * src, *dest; +unsigned int len; +{ + return memcmp(dest, src, len); +} +#endif + +#ifdef L_index +#undef index +char * +index(src, chr) +char *src; +int chr; +{ + return strchr(src, chr); +} +#endif + +#ifdef L_rindex +#undef rindex +char * +rindex(src, chr) +char *src; +int chr; +{ + return strrchr(src, chr); +} +#endif + +#ifdef L_remove +#include <errno.h> + +int +remove(src) +char *src; +{ + extern int errno; + int er = errno; + int rv = unlink(src); + if( rv < 0 && errno == EISDIR ) + rv = rmdir(src); + if( rv >= 0 ) errno = er; + return rv; +} +#endif + +#ifdef L_creat +#include <fcntl.h> + +int +creat(file, mode) +__const char * file; +mode_t mode; +{ + return open(file, O_TRUNC|O_CREAT|O_WRONLY, mode); +} +#endif + diff --git a/libc-0.0.4/misc/atexit.c b/libc-0.0.4/misc/atexit.c new file mode 100644 index 0000000..6e8e45b --- /dev/null +++ b/libc-0.0.4/misc/atexit.c @@ -0,0 +1,102 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * This deals with both the atexit and on_exit function calls + * + * Note calls installed with atexit are called with the same args as on_exit + * fuctions; the void* is given the NULL value. + * + */ + +#include <errno.h> + +/* ATEXIT.H */ +#define MAXONEXIT 20 /* AIUI Posix requires 10 */ + +typedef void (*vfuncp) (); + +extern vfuncp __cleanup; +extern void __do_exit(); + +extern struct exit_table +{ + vfuncp called; + void *argument; +} +__on_exit_table[MAXONEXIT]; + +extern int __on_exit_count; + +/* End ATEXIT.H */ + +#ifdef L_atexit +int +atexit(ptr) +vfuncp ptr; +{ + if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT) + { + errno = ENOMEM; + return -1; + } + __cleanup = __do_exit; + if( ptr ) + { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = 0; + __on_exit_count++; + } + return 0; +} + +#endif + +#ifdef L_on_exit +int +on_exit(ptr, arg) +vfuncp ptr; +void *arg; +{ + if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT) + { + errno = ENOMEM; + return -1; + } + __cleanup = __do_exit; + if( ptr ) + { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = arg; + __on_exit_count++; + } + return 0; +} + +#endif + +#ifdef L___do_exit + +int __on_exit_count = 0; +struct exit_table __on_exit_table[MAXONEXIT]; + +void +__do_exit(rv) +int rv; +{ + register int count = __on_exit_count-1; + register vfuncp ptr; + __on_exit_count = -1; /* ensure no more will be added */ + __cleanup = 0; /* Calling exit won't re-do this */ + + /* In reverse order */ + for (; count >= 0; count--) + { + ptr = __on_exit_table[count].called; + (*ptr) (rv, __on_exit_table[count].argument); + } +} + +#endif diff --git a/libc-0.0.4/misc/atoi.c b/libc-0.0.4/misc/atoi.c new file mode 100644 index 0000000..5272646 --- /dev/null +++ b/libc-0.0.4/misc/atoi.c @@ -0,0 +1,24 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +int +atoi(number) +register char *number; +{ + register int n = 0, neg = 0; + + while (*number <= ' ' && *number > 0) + ++number; + if (*number == '-') + { + neg = 1; + ++number; + } + else if (*number == '+') + ++number; + while (*number>='0' && *number<='9') + n = (n * 10) + ((*number++) - '0'); + return (neg ? -n : n); +} diff --git a/libc-0.0.4/misc/atol.c b/libc-0.0.4/misc/atol.c new file mode 100644 index 0000000..901dfe2 --- /dev/null +++ b/libc-0.0.4/misc/atol.c @@ -0,0 +1,24 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +long +atol(number) +register char *number; +{ + register long n = 0, neg = 0; + + while (*number <= ' ' && *number > 0) + ++number; + if (*number == '-') + { + neg = 1; + ++number; + } + else if (*number == '+') + ++number; + while (*number>='0' && *number<='9') + n = (n * 10) + ((*number++) - '0'); + return (neg ? -n : n); +} diff --git a/libc-0.0.4/misc/bsearch.c b/libc-0.0.4/misc/bsearch.c new file mode 100644 index 0000000..9898667 --- /dev/null +++ b/libc-0.0.4/misc/bsearch.c @@ -0,0 +1,46 @@ + +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ +#include <stdio.h> + +static int _bsearch; /* index of element found, or where to + * insert */ + +char * +bsearch(key, base, num, size, cmp) +register char *key; /* item to search for */ +register char *base; /* base address */ +int num; /* number of elements */ +register int size; /* element size in bytes */ +register int (*cmp) (); /* comparison function */ +{ + register int a, b, c, dir; + + a = 0; + b = num - 1; + while (a <= b) + { + c = (a + b) >> 1; /* == ((a + b) / 2) */ + if (dir = (*cmp) ((base + (c * size)), key)) + { + if (dir > 0) + b = c - 1; + else /* (dir < 0) */ + a = c + 1; + } + else + { + _bsearch = c; + return (base + (c * size)); + } + } + _bsearch = b; + return (NULL); +} diff --git a/libc-0.0.4/misc/cputype.c b/libc-0.0.4/misc/cputype.c new file mode 100644 index 0000000..642edf6 --- /dev/null +++ b/libc-0.0.4/misc/cputype.c @@ -0,0 +1,344 @@ +/* + * This does a determination of the cpu type that is actually being used. + * It can determine the CPU on anything upto and including a 386 accuratly + * whatever mode the CPU is in (This is 16 bit code) + * An MSDOS compiled version is available. + * + * For Post 386 interpretation the argument must be set to 1, if this is done + * an attempt to determine the CPU type will be made using MSDOS calls and + * potentially Illegal instructions. + * + * If STANDALONE is defined this will decode and print the output from cputype + * + * $ cputype # Call cputype(0) and interpret + * $ cputype + # Call cputype(1) get a SIGILL (or perhaps interpret) + * + * NOTE: This code is COPYRIGHT and not under the GNU Lib copyright, this + * may be distributed freely as source or as a standalone binary + * compiled from this unmodified source. + * + * You may use the cputype() function in your own personal code. + * You may distribute a binary version of code containing the + * cputype() function if either you distribute this source with + * the binary version or distribute a clear reference to a freely + * available copy of this source code and the source code to the + * rest of your package with the binary version of the package. + * + * (C) Copyright R de Bath 1989-1995 + */ + +#ifdef STANDALONE + +#include <stdio.h> +#include <signal.h> + +char * name_808x[] = { +"8088", "8086", "80C88", "80C86", "NEC V20", "NEC V30", "808x Clone" +}; + +char * name_8018x[] = { +"80188", "80186", "8018x Clone" +}; + +void +main(argc, argv) +int argc; char **argv; +{ + int c, major, flg, fpu; +#ifdef SIGFPE + signal(SIGFPE, SIG_IGN); +#endif + + printf("Cpu identifier - (C) R de Bath <rdebath@cix.compulink.co.uk>\n"); + + c = cputype(argc!=1); + fpu = (c<0); major = ((c>>8)&0x1F); c &= 0xFF; + + if( major == 0 ) + { + if( c > 6 ) c = 6; + printf("Cpu is an %s\n", name_808x[c]); + } + else if( major == 1 ) + { + if( c > 3 ) c = 3; + printf("Cpu is an %s\n", name_8018x[c]); + } + else + { + printf("Cpu is an 80%x86%s", major&0xF, major>15?"+":""); + if(c&0x01) printf( " in protected mode"); + printf(" MSW= "); + if( c&0x10 ) printf("ET,"); else printf("--,"); + if( c&0x08 ) printf("TS,"); else printf("--,"); + if( c&0x04 ) printf("EM,"); else printf("--,"); + if( c&0x02 ) printf("MP,"); else printf("--,"); + if( c&0x01 ) printf("PE\n"); else printf("--\n"); + + if( !fpu && ( c&0x06) ) + printf("An FPU appears to exist but it is unavailable\n"); + else + { + if( c&0x02 ) printf("Math processor requires WAIT\n"); + if( c&0x04 ) printf("Emulated math present\n"); + if( c&0x08 ) printf("Math processor belongs to a different process\n"); + /* if( c&0x10 ) printf("Humm\n"); */ + } + } + if( fpu ) printf("FPU available for use\n"); + + exit(0); +} +#endif + +/* + * The assembler for CPU determination. + * + * Improvements and additional CPUs are solicited. + */ + +#ifdef __AS386_16__ +#asm + .text +export _cputype +_cputype: + ; First save everything ... + push bp + mov bp,sp + push ds + push es + push bx + push cx + push dx + pushf +#if __FIRST_ARG_IN_AX__ + mov cx, ax ; Collect the flag +#else + mov cx, [bp+4] ; Collect the flag +#endif + + ; Tiny mode code ... + mov ax, cs + mov es, ax + mov ds, ax + mov bx, #0 ; Init to 8086 + + ; First easy check is it a 286 or better ... + push sp + pop ax + cmp ax, sp + jz ge286 + br pre286 + + ; Come here when we`re done (286+) +cpu_prot: + ; .286P + smsw ax ; Fetch 5 LSB of MSW (PE,MP,EP,...) + and al,#31 + mov bl,al + + ; Check for FPU + fninit + xor ax,ax + push ax + mov bp,sp + fnstcw word ptr [bp] + pop ax + cmp ah,#3 + jne cpuend + or bh,#$80 + + ; Another check for FPU *BUT* I think this only get`s 287+ +; finit +; fstsw ax +; or al,al +; jnz cpuend +; or bh,#$80 + + ; .8086 +cpuend: + mov ax, bx + popf + pop dx + pop cx + pop bx + pop es + pop ds + pop bp + ret + +ge286: ; .286P + ; Does the caller want the exact CPU + cmp cx,#0 + jne try_486 + +; Simple test for a 286 ... + + mov bh,#2 ; Major CPU type >= 80286 + ; What`s the contents of the GDT pointer + sub sp,#6 + mov bp,sp + sgdt [bp] + add sp,#4 + pop ax ; 286 == FFFF, 386+ anything else + inc ax + jz cpu_prot + mov bh,#$13 ; Major CPU type >= 80386 + +; smsw ax +; ror ax,#1 +; jnc try_486 ; If in real mode and running MSDOS + + jmp cpu_prot ; Assume 486 test will NOT work in prot mode + + ; This is an alternate way of finding a 386 ... + ; But it *can* be hidden by V86 mode. +; pushf +; mov ax,#$7000 +; push ax +; popf +; pushf +; pop ax +; popf +; and ax,#$7000 +; jz cpu_prot ; It`s id`ed as a 286 we already know + ; different but it`s probably a bad idea + ; to try for a 486. + +try_486: + ; This trys to trap undefined instructions + ; it may not work if the CPU is in protected mode + ; Note: This does actually re-test 286 v 386 + cli + push bp + mov bp, sp + mov ax,#$3506 + int #$21 ; WARNING - DOS DOS DOS DOS DOS !!!!! + mov [vector+2], es + mov [vector], bx + mov ax,#$2506 + lea dx, [int6] + int #$21 + mov bh,#2 ; 286 + + ; .486 +test386: + mov ebx,#$00040300 ; 386 or 486 +test486: + bswap ebx ; Byte twiddle now 486 + + mov ax,#1 +do_cpuid: + db $0F ; CPUID instruction + db $A2 + and ah,#15 ; Select family number + mov bh,ah ; put it where we want it + + ; .286P +fail386: + mov ax, #$2506 + mov dx, [vector] + mov ds, [vector+2] + int #$21 + pop bp + sti + br cpu_prot + + + ; Tests for processors before the 80286 ... + ; .8086 +pre286: + ; Is it an 8018x ? These mask shifts to less that 32 bits + mov cl,#32 + mov ax, #$0100 + shl ax,cl + mov bx, ax + jnz test8 + + ; Try for an NEC V20/30 + mov ax, #$0208 + db $D5 + db 16 ; Only the 8088 actually checks the arg to AAD + cmp al, #$28 ; as intel ran out of microcode space + jz cmos + mov bx,#4 ; NEC V20 + jmp test8 + + ; The CMOS 8088/6 had the bug with rep lods repaired. +cmos: push si + sti + mov cx, #$FFFF + rep + lodsb + pop si + or cx,cx + jne test8 + mov bx,#2 ; Intel 80C88 + + ; This tests the prefetch of the CPU, 8 bit ones have 4 bytes + ; 16 bit cpus have a queue of 6 bytes. +test8: push di + push bx + mov dx,#0 + mov bx,#4 + std + mov al,#$90 + +retest: lea di,[_nop] + cli + mov cx,#3 + rep + stosb + nop + nop + nop + nop +_inc: inc dx + nop +_nop: nop + sti + mov byte ptr [_inc], #$42 + dec bx + jnz retest + pop bx + cmp dx,#0 + jz done8 + inc bx +done8: pop di + cld + + br cpuend + + + ; Function called by the illegal instruction trap +int6: + mov sp, bp + jmp fail386 +;; + push bp + mov bp, sp + push ax + mov ax,cs + cmp 4[bp],ax + pop ax + jnz pass + cmp bh,#2 + je move23 + cmp bh,#3 + je move34 + add [bp+2], #(fail386 - do_cpuid) + jmp return +move34: add [bp+2], #(fail386 - test486) + jmp return +move23: add [bp+2], #(fail386 - test386) +return: pop bp + iret + +pass: pop bp + jmp [vector] + +vector: dd 0 + +#endasm + +#endif diff --git a/libc-0.0.4/misc/ctype.c b/libc-0.0.4/misc/ctype.c new file mode 100644 index 0000000..1514668 --- /dev/null +++ b/libc-0.0.4/misc/ctype.c @@ -0,0 +1,68 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * CTYPE.C Character classification and conversion + */ + +#include <ctype.h> + +#undef toupper +#undef tolower + +unsigned char _ctype[128] = +{ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x00..0x03 */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x04..0x07 */ + __CT_c, __CT_c|__CT_s, __CT_c|__CT_s, __CT_c|__CT_s, /* 0x08..0x0B */ + __CT_c|__CT_s, __CT_c|__CT_s, __CT_c, __CT_c, /* 0x0C..0x0F */ + + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x10..0x13 */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x14..0x17 */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x18..0x1B */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x1C..0x1F */ + + __CT_s, __CT_p, __CT_p, __CT_p, /* 0x20..0x23 */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x24..0x27 */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x28..0x2B */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x2C..0x2F */ + + __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x,/* 0x30..0x33 */ + __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x,/* 0x34..0x37 */ + __CT_d|__CT_x, __CT_d|__CT_x, __CT_p, __CT_p, /* 0x38..0x3B */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x3C..0x3F */ + + __CT_p, __CT_u|__CT_x, __CT_u|__CT_x, __CT_u|__CT_x, /* 0x40..0x43 */ + __CT_u|__CT_x, __CT_u|__CT_x, __CT_u|__CT_x, __CT_u, /* 0x44..0x47 */ + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x48..0x4B */ + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x4C..0x4F */ + + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x50..0x53 */ + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x54..0x57 */ + __CT_u, __CT_u, __CT_u, __CT_p, /* 0x58..0x5B */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x5C..0x5F */ + + __CT_p, __CT_l|__CT_x, __CT_l|__CT_x, __CT_l|__CT_x, /* 0x60..0x63 */ + __CT_l|__CT_x, __CT_l|__CT_x, __CT_l|__CT_x, __CT_l, /* 0x64..0x67 */ + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x68..0x6B */ + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x6C..0x6F */ + + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x70..0x73 */ + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x74..0x77 */ + __CT_l, __CT_l, __CT_l, __CT_p, /* 0x78..0x7B */ + __CT_p, __CT_p, __CT_p, __CT_c /* 0x7C..0x7F */ +}; + +int toupper(c) +int c; +{ + return(islower(c) ? (c ^ 0x20) : (c)); +} + +int tolower(c) +int c; +{ + return(isupper(c) ? (c ^ 0x20) : (c)); +} diff --git a/libc-0.0.4/misc/getenv.c b/libc-0.0.4/misc/getenv.c new file mode 100644 index 0000000..45d072e --- /dev/null +++ b/libc-0.0.4/misc/getenv.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +extern char ** environ; + +char * +getenv(name) +char * name; +{ + register int l; + register char ** ep = environ; + l = strlen(name); + + if( ep == 0 || l == 0 ) return 0; + + while(*ep) + { + if( **ep == *name && memcmp(name, *ep, l) == 0 && (*ep)[l] == '=' ) + return *ep+l+1; + ep++; + } + return 0; +} + diff --git a/libc-0.0.4/misc/getopt.c b/libc-0.0.4/misc/getopt.c new file mode 100644 index 0000000..d951214 --- /dev/null +++ b/libc-0.0.4/misc/getopt.c @@ -0,0 +1,122 @@ + +/* + * From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Newsgroups: net.sources + * Subject: getopt library routine Date: 30 Mar 85 04:45:33 GMT + */ +/* + * getopt -- public domain version of standard System V routine + * + * Strictly enforces the System V Command Syntax Standard; provided by D A + * Gwyn of BRL for generic ANSI C implementations + * + * #define STRICT to prevent acceptance of clustered options with arguments + * and ommision of whitespace between option and arg. + */ + +#include <stdio.h> +#include <string.h> + +int opterr = 1; /* error => print message */ +int optind = 1; /* next argv[] index */ +char *optarg = NULL; /* option parameter if any */ + +static int +Err(name, mess, c) /* returns '?' */ +char *name; /* program name argv[0] */ +char *mess; /* specific message */ +int c; /* defective option letter */ +{ + if (opterr) + { + (void) fprintf(stderr, + "%s: %s -- %c\n", + name, mess, c + ); + } + + return '?'; /* erroneous-option marker */ +} + +int +getopt(argc, argv, optstring) /* returns letter, '?', EOF */ +int argc; /* argument count from main */ +char *argv[]; /* argument vector from main */ +char *optstring; /* allowed args, e.g. "ab:c" */ +{ + static int sp = 1; /* position within argument */ + register int osp; /* saved `sp' for param test */ +#ifndef STRICT + register int oind; /* saved `optind' for param test */ +#endif + register int c; /* option letter */ + register char *cp; /* -> option in `optstring' */ + + optarg = NULL; + + if (sp == 1) /* fresh argument */ + if (optind >= argc /* no more arguments */ + || argv[optind][0] != '-' /* no more options */ + || argv[optind][1] == '\0' /* not option; stdin */ + ) + return EOF; + else if (strcmp(argv[optind], "--") == 0) + { + ++optind; /* skip over "--" */ + return EOF; /* "--" marks end of options */ + } + + c = argv[optind][sp]; /* option letter */ + osp = sp++; /* get ready for next letter */ + +#ifndef STRICT + oind = optind; /* save optind for param test */ +#endif + if (argv[optind][sp] == '\0')/* end of argument */ + { + ++optind; /* get ready for next try */ + sp = 1; /* beginning of next argument */ + } + + if (c == ':' || c == '?' /* optstring syntax conflict */ + || (cp = strchr(optstring, c)) == NULL /* not found */ + ) + return Err(argv[0], "illegal option", c); + + if (cp[1] == ':') /* option takes parameter */ + { +#ifdef STRICT + if (osp != 1) + return Err(argv[0], + "option must not be clustered", + c + ); + + if (sp != 1) /* reset by end of argument */ + return Err(argv[0], + "option must be followed by white space", + c + ); + +#else + if (oind == optind) /* argument w/o whitespace */ + { + optarg = &argv[optind][sp]; + sp = 1; /* beginning of next argument */ + } + + else +#endif + if (optind >= argc) + return Err(argv[0], + "option requires an argument", + c + ); + + else /* argument w/ whitespace */ + optarg = argv[optind]; + + ++optind; /* skip over parameter */ + } + + return c; +} diff --git a/libc-0.0.4/misc/itoa.c b/libc-0.0.4/misc/itoa.c new file mode 100644 index 0000000..0822cfc --- /dev/null +++ b/libc-0.0.4/misc/itoa.c @@ -0,0 +1,24 @@ +/* itoa.c <ndf@linux.mit.edu> */ +#define __MAX_INT_CHARS 7 + +char * +itoa(i) +int i; +{ + static char a[__MAX_INT_CHARS]; + char *b = a + sizeof(a) - 1; + int sign = (i < 0); + + if (sign) + i = -i; + *b = 0; + do + { + *--b = '0' + (i % 10); + i /= 10; + } + while (i); + if (sign) + *--b = '-'; + return b; +} diff --git a/libc-0.0.4/misc/lsearch.c b/libc-0.0.4/misc/lsearch.c new file mode 100644 index 0000000..f3253e9 --- /dev/null +++ b/libc-0.0.4/misc/lsearch.c @@ -0,0 +1,47 @@ +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ + +#include <stdio.h> + +char * +lfind(key, base, num, size, cmp) +register char *key, *base; +unsigned int *num; +register unsigned int size; +register int (*cmp) (); +{ + register int n = *num; + + while (n--) + { + if ((*cmp) (base, key) == 0) + return (base); + base += size; + } + return (NULL); +} + +char * +lsearch(key, base, num, size, cmp) +char *key, *base; +register unsigned int *num; +register unsigned int size; +int (*cmp) (); +{ + register char *p; + char *memcpy(); + + if ((p = lfind(key, base, num, size, cmp)) == NULL) + { + p = memcpy((base + (size * (*num))), key, size); + ++(*num); + } + return (p); +} diff --git a/libc-0.0.4/misc/ltoa.c b/libc-0.0.4/misc/ltoa.c new file mode 100644 index 0000000..be1c7e2 --- /dev/null +++ b/libc-0.0.4/misc/ltoa.c @@ -0,0 +1,37 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +static char buf[12]; + +extern char * ultoa(); + +char * ltoa(val) +long val; +{ + char *p; + int flg = 0; + if( val < 0 ) { flg++; val= -val; } + p = ultoa(val); + if(flg) *--p = '-'; + return p; +} + +char * ultoa(val) +unsigned long val; +{ + char *p; + + p = buf+sizeof(buf); + *--p = '\0'; + + do + { + *--p = '0' + val%10; + val/=10; + } + while(val); + return p; +} + diff --git a/libc-0.0.4/misc/ltostr.c b/libc-0.0.4/misc/ltostr.c new file mode 100644 index 0000000..c8966d9 --- /dev/null +++ b/libc-0.0.4/misc/ltostr.c @@ -0,0 +1,43 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +static char buf[34]; + +extern char * ultostr(); + +char * ltostr(val, radix) +long val; +int radix; +{ + char *p; + int flg = 0; + if( val < 0 ) { flg++; val= -val; } + p = ultostr(val, radix); + if(p && flg) *--p = '-'; + return p; +} + +char * ultostr(val, radix) +unsigned long val; +int radix; +{ + register char *p; + register int c; + + if( radix > 36 || radix < 2 ) return 0; + + p = buf+sizeof(buf); + *--p = '\0'; + + do + { + c = val%radix; + val/=radix; + if( c > 9 ) *--p = 'a'-10+c; else *--p = '0'+c; + } + while(val); + return p; +} + diff --git a/libc-0.0.4/misc/popen.c b/libc-0.0.4/misc/popen.c new file mode 100644 index 0000000..c848ca4 --- /dev/null +++ b/libc-0.0.4/misc/popen.c @@ -0,0 +1,42 @@ + +#include <stdio.h> + + +FILE * popen(command, rw) +char * command; +char * rw; +{ + int pipe_fd[2]; + int pid, reading; + + if( pipe(pipe_fd) < 0 ) return NULL; + reading = (rw[0] == 'r'); + + pid = vfork(); + if( pid < 0 ) { close(pipe_fd[0]); close(pipe_fd[1]); return NULL; } + if( pid == 0 ) + { + close(pipe_fd[!reading]); + close(reading); + if( pipe_fd[reading] != reading ) + { + dup2(pipe_fd[reading], reading); + close(pipe_fd[reading]); + } + + execl("/bin/sh", "sh", "-c", command, (char*)0); + _exit(255); + } + + close(pipe_fd[reading]); + return fdopen(pipe_fd[!reading], rw); +} + +int pclose(fd) +FILE *fd; +{ + int waitstat; + if( fclose(fd) != 0 ) return EOF; + wait(&waitstat); +} + diff --git a/libc-0.0.4/misc/putenv.c b/libc-0.0.4/misc/putenv.c new file mode 100644 index 0000000..09a68d6 --- /dev/null +++ b/libc-0.0.4/misc/putenv.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; +#define ADD_NUM 4 + +int +putenv(var) +char * var; +{ +static char ** mall_env = 0; +static int extras = 0; + char **p, **d; + char * r; + int len; + + r = strchr(var, '='); + if( r == 0 ) len = strlen(var); + else len = r-var; + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + { + while( p[0] = p[1] ) p++; + extras++; + break; + } + } + if( r == 0 ) return 0; + if( extras <= 0 ) /* Need more space */ + { + d = malloc((p-environ+1+ADD_NUM)*sizeof(char*)); + if( d == 0 ) return -1; + + memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*)); + p = d + (p-environ); + extras=ADD_NUM; + + if( mall_env ) free(mall_env); + environ = d; + mall_env = d; + } + *p++ = var; + *p = '\0'; + extras--; + + return 0; +} + + diff --git a/libc-0.0.4/misc/qsort.c b/libc-0.0.4/misc/qsort.c new file mode 100644 index 0000000..cee53c3 --- /dev/null +++ b/libc-0.0.4/misc/qsort.c @@ -0,0 +1,166 @@ +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ +#include <string.h> + +char *_qbuf = 0; /* pointer to storage for qsort() */ + +#define PIVOT ((i+j)>>1) +#define moveitem(dst,src,size) if(dst != src) memcpy(dst, src, size) + +static +_wqsort(base, lo, hi, cmp) +register int *base; +register int lo; +register int hi; +register int (*cmp) (); +{ + int k; + register int i, j, t; + register int *p = &k; + + while (hi > lo) + { + i = lo; + j = hi; + t = PIVOT; + *p = base[t]; + base[t] = base[i]; + base[i] = *p; + while (i < j) + { + while (((*cmp) ((base + j), p)) > 0) + --j; + base[i] = base[j]; + while ((i < j) && (((*cmp) ((base + i), p)) <= 0)) + ++i; + base[j] = base[i]; + } + base[i] = *p; + if ((i - lo) < (hi - i)) + { + _wqsort(base, lo, (i - 1), cmp); + lo = i + 1; + } + else + { + _wqsort(base, (i + 1), hi, cmp); + hi = i - 1; + } + } +} + +static +_lqsort(base, lo, hi, cmp) +register long *base; +register int lo; +register int hi; +register int (*cmp) (); +{ + long k; + register int i, j, t; + register long *p = &k; + + while (hi > lo) + { + i = lo; + j = hi; + t = PIVOT; + *p = base[t]; + base[t] = base[i]; + base[i] = *p; + while (i < j) + { + while (((*cmp) ((base + j), p)) > 0) + --j; + base[i] = base[j]; + while ((i < j) && (((*cmp) ((base + i), p)) <= 0)) + ++i; + base[j] = base[i]; + } + base[i] = *p; + if ((i - lo) < (hi - i)) + { + _lqsort(base, lo, (i - 1), cmp); + lo = i + 1; + } + else + { + _lqsort(base, (i + 1), hi, cmp); + hi = i - 1; + } + } +} + +static +_nqsort(base, lo, hi, size, cmp) +register char *base; +register int lo; +register int hi; +register int size; +register int (*cmp) (); +{ + register int i, j; + register char *p = _qbuf; + + while (hi > lo) + { + i = lo; + j = hi; + p = (base + size * PIVOT); + moveitem(_qbuf, p, size); + moveitem(p, (base + size * i), size); + moveitem((base + size * i), _qbuf, size); + p = _qbuf; + while (i < j) + { + while (((*cmp) ((base + size * j), p)) > 0) + --j; + moveitem((base + size * i), (base + size * j), size); + while ((i < j) && (((*cmp) ((base + size * i), p)) <= 0)) + ++i; + moveitem((base + size * j), (base + size * i), size); + } + moveitem((base + size * i), p, size); + if ((i - lo) < (hi - i)) + { + _nqsort(base, lo, (i - 1), size, cmp); + lo = i + 1; + } + else + { + _nqsort(base, (i + 1), hi, size, cmp); + hi = i - 1; + } + } +} + +qsort(base, num, size, cmp) +char *base; +int num; +int size; +int (*cmp) (); +{ + char _qtemp[128]; + + if (_qbuf == 0) + { + if (size > sizeof(_qtemp))/* records too large! */ + return; + _qbuf = _qtemp; + } + if (size == 2) + _wqsort(base, 0, num - 1, cmp); + else if (size == 4) + _lqsort(base, 0, num - 1, cmp); + else + _nqsort(base, 0, num - 1, size, cmp); + if (_qbuf == _qtemp) + _qbuf = 0; +} diff --git a/libc-0.0.4/misc/rand.c b/libc-0.0.4/misc/rand.c new file mode 100644 index 0000000..4eb0789 --- /dev/null +++ b/libc-0.0.4/misc/rand.c @@ -0,0 +1,61 @@ +#ifdef ZX81_RNG +/* + * This is my favorite tiny RNG, If you had a ZX81 you may recognise it :-) + * (RdeBath) + */ + +#include <stdlib.h> + +#define MAXINT (((unsigned)-1)>>1) + +static unsigned int sseed = 0; + +int rand() +{ + return ( sseed = (((sseed+1L)*75L)%65537L)-1 ) & MAXINT; +} + +void srand(seed) +unsigned int seed; +{ + sseed=seed; +} + +#else + +/* + * This generator is a combination of three linear congruential generators + * with periods or 2^15-405, 2^15-1041 and 2^15-1111. It has a period that + * is the product of these three numbers. + */ + +static int seed1 = 1; +static int seed2 = 1; +static int seed3 = 1; +#define MAXINT (((unsigned)-1)>>1) + +#define CRANK(a,b,c,m,s) \ + q = s/a; \ + s = b*(s-a*q) - c*q; \ + if(s<0) s+=m; + +int rand() +{ + register int q, z; + CRANK(206, 157, 31, 32363, seed1); + CRANK(217, 146, 45, 31727, seed2); + CRANK(222, 142, 133, 31657, seed3); + + return seed1^seed2^seed3; +} + +void srand(seed) +unsigned int seed; +{ + seed &= MAXINT; + seed1= seed%32362 + 1; + seed2= seed%31726 + 1; + seed3= seed%31656 + 1; +} + +#endif diff --git a/libc-0.0.4/misc/strtod.c b/libc-0.0.4/misc/strtod.c new file mode 100644 index 0000000..8acb423 --- /dev/null +++ b/libc-0.0.4/misc/strtod.c @@ -0,0 +1,96 @@ +/* + * strtod.c - This file is part of the libc-8086 package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include <stdlib.h> +#include <ctype.h> + +double +strtod(const char *nptr, char ** endptr) +{ + unsigned short negative; + double number; + double fp_part; + int exponent; + unsigned short exp_negative; + + /* advance beyond any leading whitespace */ + while (isspace(*nptr)) + nptr++; + + /* check for optional '+' or '-' */ + negative=0; + if (*nptr=='-') + { + negative=1; + nptr++; + } + else + if (*nptr=='+') + nptr++; + + number=0; + while (isdigit(*nptr)) + { + number=number*10+(*nptr-'0'); + nptr++; + } + + if (*nptr=='.') + { + nptr++; + fp_part=0; + while (isdigit(*nptr)) + { + fp_part=fp_part/10.0 + (*nptr-'0')/10.0; + nptr++; + } + number+=fp_part; + } + + if (*nptr=='e' || *nptr=='E') + { + nptr++; + exp_negative=0; + if (*nptr=='-') + { + exp_negative=1; + nptr++; + } + else + if (*nptr=='+') + nptr++; + + exponent=0; + while (isdigit(*nptr)) + { + exponent=exponent*10+(*nptr-'0'); + exponent++; + } + } + + while (exponent) + { + if (exp_negative) + number/=10; + else + number*=10; + exponent--; + } + return (negative ? -number:number); +} diff --git a/libc-0.0.4/misc/strtol.c b/libc-0.0.4/misc/strtol.c new file mode 100644 index 0000000..bcd3334 --- /dev/null +++ b/libc-0.0.4/misc/strtol.c @@ -0,0 +1,106 @@ +/* + * strtol.c - This file is part of the libc-8086 package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <ctype.h> +#include <stdlib.h> + +long int +strtol(const char *nptr, char **endptr, int base) +{ + const char * ptr; + unsigned short negative; + long int number; + + ptr=nptr; + + while (isspace(*ptr)) + ptr++; + + negative=0; + if (*ptr=='-') + negative=1; + + number=(long int)strtoul(nptr, endptr, base); + + return (negative ? -number:number); +} + +unsigned long int +strtoul(const char *nptr, char **endptr, int base) +{ + unsigned long int number; + + /* Sanity check the arguments */ + if (base==1 || base>36 || base<0) + base=0; + + /* advance beyond any leading whitespace */ + while (isspace(*nptr)) + nptr++; + + /* check for optional '+' or '-' */ + if (*nptr=='-') + nptr++; + else + if (*nptr=='+') + nptr++; + + /* If base==0 and the string begins with "0x" then we're supposed + to assume that it's hexadecimal (base 16). */ + else + if (base==0 && *nptr=='0') + if (toupper(*(nptr+1))=='X') + { + base=16; + nptr+=2; + } + /* If base==0 and the string begins with "0" but not "0x", + then we're supposed to assume that it's octal (base 8). */ + else + { + base=8; + nptr++; + } + + + /* If base is still 0 (it was 0 to begin with and the string didn't begin + with "0"), then we are supposed to assume that it's base 10 */ + if (base==0) + base=10; + + number=0; + while (isalnum(*nptr)) + { + number= (number*base)+((isalpha(*nptr) ? toupper(*nptr) : *nptr) + - (isdigit(*nptr) ? '0' : 'A' + 9)); + nptr++; + if (*nptr>'0'+base) + break; + } + + /* Some code is simply _impossible_ to write with -Wcast-qual .. :-\ */ + if (endptr!=NULL) + *endptr=(char *)nptr; + + /* All done */ + return number; +} + + diff --git a/libc-0.0.4/misc/system.c b/libc-0.0.4/misc/system.c new file mode 100644 index 0000000..f48f68d --- /dev/null +++ b/libc-0.0.4/misc/system.c @@ -0,0 +1,49 @@ + +#include <stddef.h> +#include <signal.h> + +int +system(command) +char * command; +{ + int wait_val, wait_ret, pid; + __sighandler_t save_quit; + __sighandler_t save_int; + + if( command == 0 ) return 1; + + save_quit = signal(SIGQUIT, SIG_IGN); + save_int = signal(SIGINT, SIG_IGN); + + if( (pid=vfork()) < 0 ) + { + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + return -1; + } + if( pid == 0 ) + { + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + + execl("/bin/sh", "sh", "-c", command, (char*)0); + _exit(127); + } + /* Signals are not absolutly guarenteed with vfork */ + signal(SIGQUIT, SIG_IGN); + signal(SIGINT, SIG_IGN); + + do + { + if( (wait_ret = wait(&wait_val)) == -1 ) + { + wait_val = -1; + break; + } + } + while( wait_ret != pid ); + + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + return wait_val; +} diff --git a/libc-0.0.4/msdos/Config b/libc-0.0.4/msdos/Config new file mode 100644 index 0000000..ec28084 --- /dev/null +++ b/libc-0.0.4/msdos/Config @@ -0,0 +1 @@ +msdos: Msdos system calls diff --git a/libc-0.0.4/msdos/Makefile b/libc-0.0.4/msdos/Makefile new file mode 100644 index 0000000..d94d733 --- /dev/null +++ b/libc-0.0.4/msdos/Makefile @@ -0,0 +1,36 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +ASRC=msdos.c +AOBJ= dos_start.o __mkargv.o dos__fconv.o dos_read.o dos_write.o \ + dos_open.o dos_close.o dos_unlink.o dos_lseek.o \ + dos_segalloc.o dos_setvect.o dos_getvect.o dos_isatty.o + +BSRC=i86.c +BOBJ= __set_es.o __peek_es.o __poke_es.o __deek_es.o __strchr_es.o + +OBJ=$(AOBJ) $(BOBJ) + +all: $(OBJ) + +libc.a: $(BOBJ) + ar r ../$(LIBC) $(BOBJ) + @touch libc.a + +libdos.a: $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a + +$(AOBJ): $(ASRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ASRC) + +$(BOBJ): $(BSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(BSRC) + diff --git a/libc-0.0.4/msdos/TODO b/libc-0.0.4/msdos/TODO new file mode 100644 index 0000000..b775dff --- /dev/null +++ b/libc-0.0.4/msdos/TODO @@ -0,0 +1,8 @@ +This is currently a very cutdown version of the syslib. + +This also currently does nothing about the difference between 'TEXT' and +'BINARY' modes but I think that this level of operation should be pure +binary, the 'TEXT' mode is more suited to stdio where an "fopen(f, "rb")" +is more reasonable and probably won't break on other OSs. + +-Robert. diff --git a/libc-0.0.4/msdos/i86.c b/libc-0.0.4/msdos/i86.c new file mode 100644 index 0000000..0613756 --- /dev/null +++ b/libc-0.0.4/msdos/i86.c @@ -0,0 +1,163 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +/* + * These functions will not normally be useful for Linux-8086. But they + * can be used and may be useful in the kernel. + */ + +#ifdef __AS386_16__ + +#ifdef L___set_es +unsigned int +__get_ds() +{ +#asm + mov ax,ds +#endasm +} + +unsigned int +__get_es() +{ +#asm + mov ax,es +#endasm +} + +void +__set_es(seg) +{ +#asm +#if __FIRST_ARG_IN_AX__ + mov es,ax +#else + mov bx,sp + mov es,[bx+2] +#endif +#endasm +} +#endif + +#ifdef L___peek_es +int +__peek_es(off) +unsigned int off; +{ +#asm +#if __FIRST_ARG_IN_AX__ + mov bx,ax +#else + mov bx,sp + mov bx,[bx+2] +#endif + seg es + mov al,[bx] + xor ah,ah +#endasm +} +#endif + +#ifdef L___poke_es +int +__poke_es(off, value) +unsigned int off; +int value; +{ +#asm +#if __FIRST_ARG_IN_AX__ + mov bx,sp + mov bx,[bx+2] + xchg ax,bx +#else + mov bx,sp + mov ax,[bx+4] + mov bx,[bx+2] +#endif + seg es + mov [bx],al + xor ah,ah +#endasm +} +#endif + +#ifdef L___deek_es +int +__deek_es(off) +unsigned int off; +{ +#asm +#if __FIRST_ARG_IN_AX__ + mov bx,ax +#else + mov bx,sp + mov bx,[bx+2] +#endif + seg es + mov ax,[bx] +#endasm +} +#endif + +#ifdef L___strchr_es +char * +__strchr_es(s, c) +char * s; +int c; +{ +#asm + mov bx,sp + push si +#if __FIRST_ARG_IN_AX__ + mov bx,[bx+2] + mov si,ax +#else + mov si,[bx+2] + mov bx,[bx+4] +#endif + xor ax,ax + +#ifdef PARANOID + cld +#endif + push ds + push es + pop ds + +in_loop: + lodsb + cmp al,bl + jz got_it + or al,al + jnz in_loop + pop ds + pop si + ret +got_it: + lea ax,[si-1] + pop ds + pop si + +#endasm +} +#endif + +#ifdef L___strchr_es +char * +__strnget_es(d, s, c) +char *d, *s; +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); +} +#endif + +#endif /* __AS386_16__ */ diff --git a/libc-0.0.4/msdos/msdos.c b/libc-0.0.4/msdos/msdos.c new file mode 100644 index 0000000..02c35db --- /dev/null +++ b/libc-0.0.4/msdos/msdos.c @@ -0,0 +1,540 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#if !__FIRST_ARG_IN_AX__ +#ifdef __AS386_16__ +#ifdef __MSDOS__ + +#include <dos.h> +#include <fcntl.h> +#include <errno.h> +int errno; + +#ifdef L_dos_start + +static char * argdef[2] = { "C" }; +char ** __argv =argdef; +char ** environ =argdef+1; + +int __argc =1; +void (*__cleanup)() = 0; + +#asm + .data +export ___envseg +___envseg: + .word 0 + +export ___psp +___psp: + .word 0 + + .text + +export _exit +export __exit +_exit: ! exit(rv) function + mov bx,sp + push [bx+2] ! Copy the `rv` for the exit fuctions. + mov bx,[___cleanup] ! Call exit, normally this is `__do_exit` + test bx,bx + je no_clean ! But it`s default is null + call bx +no_clean: + inc sp + inc sp +__exit: ! _exit(rv) + mov bx,sp + mov ax,[bx+2] + mov ah,#$4c + int #$21 +dos_1_exit: + int #$20 + + .text +export ___cstartup ! Crt0 startup +___cstartup: + mov ax,#$3000 ! Get DOS version + int $21 + cmp al,#2 ! DOS 2+ is Ok + jb dos_1_exit + + mov dx,cs ! Current CS + add dx,#__segoff ! This var generated by the linker + mov ds,dx ! Correct DS + + mov [___psp],es ! PSP segment + seg es + mov ax,[$2c] + mov [___envseg],ax ! Enviroment Segment + + ! Now need to free some RAM + seg es + mov bx,[2] ! Top of Ram + mov ax,ds + add ax,#4096 ! Top of 64k data seg + jc use_tor ! Oops, wrapped + cmp ax,bx + jnc use_tor ! Bigger than tor + mov bx,ax +use_tor: + mov ax,cs ! Work out how big the memseg is needed + sub bx,ax + mov ah,#$4A ! Set it + int $21 + jnc set_stack ! Good. + ! Ooops, problem.. + ! BX is now how big it can be so set that. + ! FIXME should check for BSS v Stack overlap + mov ah,#$4A + int $21 + +set_stack: ! Now set SS to the same as DS + sub bx,#__segoff ! And SP to the top of available memory. + mov cl,#4 + shl bx,cl + sub bx,#2 + mov ss,dx + mov sp,bx + +zap_bss: ! Clear the BSS + mov es,dx ! ES now data seg + mov di,#__edata + mov cx,#__end + sub cx,di + xor ax,ax + cld + rep + stosb + + call ___mkargv ! Fetch the arguments and enviroment + push [_environ] + push [___argv] + push [___argc] + + mov si,#auto_start ! Pointer to first autostart function +auto_run: + call [si] ! Call the function + inc si ! SI at next + inc si + jmp auto_run ! And round for the next. + +call_exit: ! Last item called by above. + pop bx ! Be tidy. + push ax ! At the end the last called was main() push it`s + call _exit ! return val and call exit(); +bad_exit: + jmp bad_exit ! Exit returned !! + + loc 2 + .word _main ! Segment 2 is the trailing pointers, main and the + .word call_exit ! routine to call exit. +data_start: + + .text + +#endasm + +__E_nosys() +{ +#asm + .text + +export sys_call5 +export sys_call4 +export sys_call3 +export sys_call2 +export sys_call1 +export sys_call0 +sys_call5: ! Trap the unemulated Linux86 syscalls +sys_call4: +sys_call3: +sys_call2: +sys_call1: +sys_call0: + +#endasm + errno = ENOSYS; + return -1; +} +#endif + +#ifdef L___mkargv + +extern char ** environ; +extern char ** __argv; +extern int __argc; + +__mkargv() +{ + int length, i, argc=1, s=0; + char *ptr, *p; + __set_es(__psp); /* Pointer to the args */ + length = __peek_es(0x80); /* Length of cmd line */ + if( length > 0 ) + { + ptr = (char*) sbrk(length+1); /* Allocate some space */ + + for(i=0; i<length; i++) /* Copy it in. */ + { + ptr[i] = __peek_es(0x81+i); + if( ptr[i] != ' ' && s == 0 ) { argc++; s=1; } + if( ptr[i] == ' ' && s == 1 ) s=0; + } + ptr[length]=0; + + p= __argv[0]; + __argv = (char**) sbrk((argc+1)*sizeof(char*)); + __argv[0] = p; /* FIXME: The real command can be found */ + __argc=argc; + + argc=1; s=0; + for(i=0; i<length; i++) + { + if( ptr[i] != ' ' && s == 0 ) { __argv[argc++] = ptr+i; s=1; } + if( ptr[i] == ' ' && s == 1 ) { ptr[i] = '\0'; s=0; } + } + __argv[argc] = 0; + } +} +#endif + +#ifdef L_dos__fconv +/* This function converts filenames from unix like to DOS. */ +char * +__fconv(fname) +char * fname; +{ +static char buf1[66], buf2[66], *str = 0; + register char *p, ch; + int dot = 0; + + if( strcmp("/dev/tty", fname) == 0 ) return "CON:"; + + if( str == buf1 ) str = buf2; else str = buf1; + + p = str; + if( strncmp("/mnt/", fname, 5) == 0 ) + { + strcpy(p, "A:"); p+=2; fname+=4; + } + /* + * POSS: + * open("/name/*", ...); looks for an environ var PATH_name=c:\x\y\z + */ + + while((ch = *fname++) && p < str+65) + { + if( ( ch >= 'a' && ch <= 'z' ) + || ( ch >= '0' && ch <= '9' ) + || ch == ':' || ch == '%' || ch == '-' || ch == '$' ) + ; + else if( ch >= 'A' && ch <= 'Z' ) + ch = ch-'A'+'a'; + else if( ch == '.' && dot == 0 ) + dot = 1; + else if( ch == '/' || ch == '\\' ) + { + dot = 0; ch = '\\'; + } + else ch = '_'; + + *p++ = ch; + } + *p++ = '\0'; + return str; +} +#endif + +#ifdef L_dos_read +int +read(fd, ptr, len) +int fd; +char *ptr; +unsigned len; +{ +#asm + mov bx,sp + mov cx,[bx+6] + mov dx,[bx+4] + mov bx,[bx+2] + mov ah,#$3f + int #$21 + jnc readok + mov ax,#-1 +readok: +#endasm +} +#endif + +#ifdef L_dos_write +int +write(fd, ptr, len) +int fd; +char *ptr; +unsigned len; +{ +#asm + mov bx,sp + mov cx,[bx+6] + mov dx,[bx+4] + mov bx,[bx+2] + mov ah,#$40 + int #$21 + jnc writeok + mov ax,#-1 +writeok: +#endasm +} +#endif + +#ifdef L_dos_open +int +open(fname, type, cmode) +char * fname; +int type; +int cmode; +{ + register char * nname = __fconv(fname); + int creat_mode = 0; + int rv; + + if( (cmode & 0222) == 0 ) creat_mode = 1; + + /* BzzzT. Assume these flags both mean the merge of them */ + /* BzzzT. Also ignore O_EXCL */ + if( type & (O_TRUNC|O_CREAT) ) + rv = __dos_creat(nname, creat_mode); + + else + /* Warn, this assumes the standard vals for O_RDWR, O_RDONLY, O_WRONLY */ + rv = __dos_open(nname, type&O_ACCMODE); + if( rv < 0 ) errno=ENOENT; + return rv; +} + +__dos_open(fname, mode) +{ +#asm + mov bx,sp + mov dx,[bx+2] ;ds:dx points to source string + mov al,[bx+4] ;access code + mov ah,#$3d ;ask for a open + int #$21 + jnc openok ;return handle if no error + mov ax,#-1 ;return -1 if error +openok: +#endasm +} + +__dos_creat(fname) +char * fname; +{ +#asm + mov bx,sp + mov dx,[bx+2] ;ds:dx points to source string + xor cx,cx ;normal attributes + mov ah,#$3c ;ask for a create + int #$21 + jnc creok ;return handle if no error + mov ax,#-1 ;return -1 if error +creok: +#endasm +} +#endif + +#ifdef L_dos_close +close(fd) +{ +#asm + mov bx,sp + mov bx,[bx+2] ;file handle + mov ah,#$3e ;ask for a close + int #$21 + mov ax,0 ;return 0 if no error + jnc closeok + mov ax,#-1 ;return -1 if error +closeok: +#endasm +} +#endif + +#ifdef L_dos_unlink +unlink(fname) +char * fname; +{ +#asm + mov bx,sp + push [bx+2] + call ___fconv + inc sp + inc sp + mov dx,ax ;ds:dx points to source string + mov ah,#$41 ;ask for a unlink + int #$21 + mov ax,0 ;assume no errors + jnc unlok + mov ax,#-1 ;return -1 if error +unlok: +#endasm +} +#endif + +#ifdef L_dos_lseek +long +lseek(fd, offset, mode) +int fd, mode; +long offset; +{ +#asm + mov bx,sp + mov al,[bx+8] ;mode of seek (0 to 2) + mov dx,[bx+4] ;cx:dx is long offset + mov cx,[bx+6] + mov bx,[bx+2] ;file handle + mov ah,#$42 + int #$21 ;do the lseek + jnc seekok + mov ax,#-1 ;return -1 if error + mov dx,ax +seekok: +#endasm +} +#endif + +#ifdef L_dos_segalloc +unsigned int +__segalloc(paracount) +unsigned int paracount; +{ +#asm + mov bx,sp + mov bx,[bx+2] + mov ah,#$48 + int $21 + jnc ok + mov ax,#0 +ok: +#endasm +} +#endif + +#ifdef L_dos_setvect +void +__setvect(i,j) +int i; +long j; +{ +#asm + mov bx,sp + mov ax,[bx+2] + mov dx,[bx+4] + mov bx,[bx+6] + push ds + test bx,bx + jnz got_seg + mov bx,cs +got_seg: + mov ds,bx + mov ah,#$25 + int $21 + pop ds +#endasm +} +#endif + +#ifdef L_dos_getvect +long +__getvect(vecno) +int vecno; +{ +#asm + mov bx,sp + mov ax,[bx+2] + mov ah,#$35 + push es + int #$21 + mov dx,es + mov ax,bx + pop es +#endasm +} +#endif + +#ifdef L_dos_isatty +isatty(fd) +int fd; +{ +#asm + mov bx,sp + mov bx,[bx+2] + mov ah,#$44 + mov al,#0 + int #$21 + xor ax,ax + test dx,#$80 + jz not_tty + inc ax +not_tty: +#endasm +} +#endif + +#endif /* __MSDOS__ */ +#endif /* __AS386_16__ */ +#endif /* !__FIRST_ARG_IN_AX__ */ + +/* +# Name No Args Flag, comment +CHDIR 12 1 +TIME 13 1 * No long return val, arg _must_ exist. +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 3 * Need more args & no ELKS +UMOUNT 22 1 . No ELKS +SETUID 23 1 +GETUID 24 1 * This gets both uid and euid +STIME 25 2 . No ELKS should be 1 LONG arg +PTRACE 26 X + +ALARM 27 2 ? No unused return. +FSTAT 28 2 +PAUSE 29 0 +UTIME 30 2 +STTY 31 2 . ELKS ain't got this and it'll probably change +GTTY 32 2 . ELKS ain't got this and it'll probably change +ACCESS 33 2 +NICE 34 1 +FTIME 35 1 . ELKS ain't got this. +SYNC 36 0 +KILL 37 2 +RENAME 38 2 +MKDIR 39 2 +RMDIR 40 1 +DUP 41 X - Using nasty fcntl function +PIPE 42 1 +TIMES 43 1 +PROF 44 X + +SETGID 46 1 +GETGID 47 1 * This gets both gid and egid +SIGNAL 48 2 + +ACCT 51 X + +PLOCK 53 X + +IOCTL 54 3 +FCNTL 55 3 +EXEC 59 2 ? +UMASK 60 1 +CHROOT 61 1 +SIGACTION 71 X +SIGSUSPEND 72 X +SIGPENDING 73 X +SIGPROCMASK 74 X +SIGRETURN 75 X +REBOOT 76 3 . No ELKS and the magic number will be diff. +*/ + diff --git a/libc-0.0.4/pwd/Config b/libc-0.0.4/pwd/Config new file mode 100644 index 0000000..b5aaad0 --- /dev/null +++ b/libc-0.0.4/pwd/Config @@ -0,0 +1 @@ +pwd: /etc/passwd managment diff --git a/libc-0.0.4/pwd/Makefile b/libc-0.0.4/pwd/Makefile new file mode 100644 index 0000000..df90f89 --- /dev/null +++ b/libc-0.0.4/pwd/Makefile @@ -0,0 +1,40 @@ +# Copyright (C) 1996 Nat Friedman <ndf@aleph1.mit.edu> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +ifeq ($(PLATFORM),i386-Linux) +CFLAGS+=$(WALL) +else # ifeq ($(PLATFORM),i86-ELKS) +CFLAGS=$(CCFLAGS) $(LIBDEFS) -ansi +endif + +PSRC=__getpwent.c pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c fgetpwent.c +POBJ=__getpwent.o pwent.o getpwnam.o getpwuid.o putpwent.o getpw.o fgetpwent.o + +all: $(POBJ) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ $< -c + +$(LIBC): $(POBJ) + ar r ../$(LIBC) $(POBJ) + @touch libc.a + +test: test_pwd.c libpwd.a + $(CC) $(CFLAGS) test_pwd.c -o test_pwd -L. -lpwd + +libpwd.a: $(POBJ) + ar r libpwd.a $(POBJ) + ranlib libpwd.a + +libpwd: libpwd.a + +clean: + rm -f $(POBJ) libc.a libpwd.a + + + + diff --git a/libc-0.0.4/pwd/__getpwent.c b/libc-0.0.4/pwd/__getpwent.c new file mode 100644 index 0000000..1dfc87e --- /dev/null +++ b/libc-0.0.4/pwd/__getpwent.c @@ -0,0 +1,152 @@ +/* + * __getpwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <pwd.h> + +#define __PWD_LINE_BUFFER_SIZE 256 + +struct passwd * +__getpwent(int passwd_fd) +{ + static char pwd_line[__PWD_LINE_BUFFER_SIZE]; + unsigned short curr_index; + + /* field_num is the current field number, 0 through 6 */ + unsigned short field_num; + + /* field_length is the length of the current field */ + unsigned short field_length; + + /* field_begin is a pointer to the first character of the current field */ + char * field_begin; + + /* endptr is used to error-check the call to strtol() */ + char * endptr; + + /* the only static passwd structure. we return a pointer to it */ + static struct passwd passwd; + + /* Gross, but small... */ + goto readline_start; + +readline_restart: + /* Advance to the end of the line */ + while (pwd_line[curr_index]!='\n' && + read(passwd_fd, &pwd_line[curr_index], 1)==1); + +readline_start: + /* Initialize ourselves at the beginning of the line */ + curr_index=field_num=field_length=0; + field_begin=pwd_line; + while (read(passwd_fd, &pwd_line[curr_index], 1)==1) + { + if (curr_index==0) + if (*pwd_line=='#' || *pwd_line==' ' || *pwd_line=='\n' || + *pwd_line=='\t') + goto readline_restart; + + field_length++; + if (pwd_line[curr_index]==':' || pwd_line[curr_index]=='\n') + { + pwd_line[curr_index]='\0'; + switch (field_num) + { + case 0: /* login */ + passwd.pw_name=field_begin; + break; + case 1: /* passwd */ + passwd.pw_passwd=field_begin; + break; + case 2: /* GID */ + case 3: /* UID */ + if (field_num==2) + passwd.pw_uid=strtol(field_begin, &endptr, 10); + else + passwd.pw_gid=strtol(field_begin, &endptr, 10); + if (endptr!=(pwd_line+curr_index)) /* there were invalid + characters */ + goto readline_restart; + + curr_index-=field_length; + break; + case 4: /* GECOS field */ + passwd.pw_gecos=field_begin; + break; + case 5: /* home directory */ + passwd.pw_dir=field_begin; + break; + case 6: /* shell */ + passwd.pw_shell=field_begin; + return &passwd; + break; + default: /* too many fields -- invalid line */ + goto readline_restart; + } + if (field_num!=2 && field_num!=3) + field_begin=pwd_line+curr_index+1; + field_num++; + field_length=0; + } + curr_index++; + if (curr_index>=__PWD_LINE_BUFFER_SIZE) + { + if (field_num<=3) + goto readline_start; + + if (*passwd.pw_gecos) + { + if (field_num==4) /* gecos.. least important */ + { + /* erase this field */ + curr_index-=field_length; + field_num++; + passwd.pw_gecos=field_begin-1; + /* read until the next delimiter */ + while ((read(passwd_fd, &pwd_line[curr_index], 1)==1) && + pwd_line[curr_index]!=':'); + + } + else if (field_num>4) /* move everything back to the gecos... */ + { + unsigned short shift; + if (field_num==5) + passwd.pw_dir=field_begin; + + shift=passwd.pw_dir-passwd.pw_gecos; + memcpy(passwd.pw_gecos, + passwd.pw_dir, pwd_line+curr_index-passwd.pw_dir); + passwd.pw_gecos--; + passwd.pw_dir=passwd.pw_gecos; + field_begin-=shift; + passwd.pw_shell-=shift; + curr_index-=shift; + } + } + else + goto readline_restart; + } + } + return NULL; +} + diff --git a/libc-0.0.4/pwd/fgetpwent.c b/libc-0.0.4/pwd/fgetpwent.c new file mode 100644 index 0000000..e12b890 --- /dev/null +++ b/libc-0.0.4/pwd/fgetpwent.c @@ -0,0 +1,35 @@ +/* + * fgetpwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <errno.h> +#include <stdio.h> +#include <pwd.h> + +struct passwd * +fgetpwent(FILE * file) +{ + if (file==NULL) + { + errno=EINTR; + return NULL; + } + + return __getpwent(fileno(file)); +} diff --git a/libc-0.0.4/pwd/getpw.c b/libc-0.0.4/pwd/getpw.c new file mode 100644 index 0000000..4f4e390 --- /dev/null +++ b/libc-0.0.4/pwd/getpw.c @@ -0,0 +1,51 @@ +/* + * getpw.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <sys/types.h> +#include <errno.h> +#include <stdio.h> +#include <pwd.h> + +int +getpw(uid_t uid, char *buf) +{ + struct passwd * passwd; + + if (buf==NULL) + { + errno=EINVAL; + return -1; + } + if ((passwd=getpwuid(uid))==NULL) + return -1; + + if (sprintf(buf, "%s:%s:%u:%u:%s:%s:%s", passwd->pw_name, passwd->pw_passwd, + passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, + passwd->pw_dir, passwd->pw_shell)<0) + { + errno=ENOBUFS; + return -1; + } + + return 0; +} + + + diff --git a/libc-0.0.4/pwd/getpwnam.c b/libc-0.0.4/pwd/getpwnam.c new file mode 100644 index 0000000..85dbc8e --- /dev/null +++ b/libc-0.0.4/pwd/getpwnam.c @@ -0,0 +1,52 @@ +/* + * getpwnam.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <pwd.h> + + +struct passwd * +getpwnam(const char * name) +{ + int passwd_fd; + struct passwd * passwd; + + if (name==NULL) + { + errno=EINVAL; + return NULL; + } + + if ((passwd_fd=open("/etc/passwd", O_RDONLY))<0) + return NULL; + + while ((passwd=__getpwent(passwd_fd))!=NULL) + if (!strcmp(passwd->pw_name, name)) + { + close(passwd_fd); + return passwd; + } + + close(passwd_fd); + return NULL; +} diff --git a/libc-0.0.4/pwd/getpwuid.c b/libc-0.0.4/pwd/getpwuid.c new file mode 100644 index 0000000..ffd58c1 --- /dev/null +++ b/libc-0.0.4/pwd/getpwuid.c @@ -0,0 +1,44 @@ +/* + * getpwuid.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <pwd.h> + +struct passwd * +getpwuid(uid_t uid) +{ + int passwd_fd; + struct passwd * passwd; + + if ((passwd_fd=open("/etc/passwd", O_RDONLY))<0) + return NULL; + + while ((passwd=__getpwent(passwd_fd))!=NULL) + if (passwd->pw_uid==uid) + { + close(passwd_fd); + return passwd; + } + + close (passwd_fd); + return NULL; +} diff --git a/libc-0.0.4/pwd/putpwent.c b/libc-0.0.4/pwd/putpwent.c new file mode 100644 index 0000000..a0035ea --- /dev/null +++ b/libc-0.0.4/pwd/putpwent.c @@ -0,0 +1,39 @@ +/* + * putpwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <errno.h> +#include <pwd.h> + +int +putpwent(const struct passwd * passwd, FILE * f) +{ + if (passwd == NULL || f == NULL) + { + errno=EINVAL; + return -1; + } + if (fprintf(f, "%s:%s:%u:%u:%s:%s:%s\n", passwd->pw_name, passwd->pw_passwd, + passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, + passwd->pw_dir, passwd->pw_shell)<0) + return -1; + + return 0; +} diff --git a/libc-0.0.4/pwd/pwent.c b/libc-0.0.4/pwd/pwent.c new file mode 100644 index 0000000..dc40a08 --- /dev/null +++ b/libc-0.0.4/pwd/pwent.c @@ -0,0 +1,62 @@ +/* + * pwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <pwd.h> +#include <fcntl.h> + +/* + * setpwent(), endpwent(), and getpwent() are included in the same object + * file, since one cannot be used without the other two, so it makes sense to + * link them all in together. + */ + +/* file descriptor for the password file currently open */ +static int pw_fd; + +void +setpwent(void) +{ + if (pw_fd!=-1) + close(pw_fd); + + pw_fd=open("/etc/passwd", O_RDONLY); +} + +void +endpwent(void) +{ + if (pw_fd!=-1) + close(pw_fd); + pw_fd=-1; +} + +struct passwd * +getpwent(void) +{ + if (pw_fd!=-1) + return __getpwent(pw_fd); + return NULL; +} + + + diff --git a/libc-0.0.4/pwd/test_pwd b/libc-0.0.4/pwd/test_pwd Binary files differnew file mode 100755 index 0000000..bac2f1e --- /dev/null +++ b/libc-0.0.4/pwd/test_pwd diff --git a/libc-0.0.4/pwd/test_pwd.c b/libc-0.0.4/pwd/test_pwd.c new file mode 100644 index 0000000..3279fb2 --- /dev/null +++ b/libc-0.0.4/pwd/test_pwd.c @@ -0,0 +1,91 @@ +/* + * test_pwd.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <pwd.h> + +int +main(int argc, char ** argv) +{ + struct passwd * passwd; + int test_uid; + + fprintf(stderr, "Beginning test of libc/pwd...\n"); + + fprintf(stderr, "=> Testing setpwent(), getpwent(), endpwent()...\n"); + fprintf(stderr, "-> setpwent()...\n"); + setpwent(); + fprintf(stderr, "-> getpwent()...\n"); + printf("********************************************************************************\n"); + while ((passwd=getpwent())!=NULL) + { + printf("pw_name\t\t: %s\n", passwd->pw_name); + printf("pw_passwd\t: %s\n", passwd->pw_passwd); + printf("pw_uid\t\t: %d\n", (int) passwd->pw_uid); + printf("pw_gid\t\t: %d\n", (int) passwd->pw_gid); + printf("pw_gecos\t: %s\n", passwd->pw_gecos); + printf("pw_dir\t\t: %s\n", passwd->pw_dir); + printf("pw_shell\t: %s\n", passwd->pw_shell); + printf("********************************************************************************\n"); + } + fprintf(stderr, "-> endpwent()...\n"); + endpwent(); + fprintf(stderr, "=> Test of setpwent(), getpwent(), endpwent() complete.\n"); + fprintf(stderr, "=> Testing getpwuid(), getpwnam()...\n"); + fprintf(stderr, "-> getpwuid()...\n"); + printf("********************************************************************************\n"); + for(test_uid=0;test_uid<100;test_uid++) + { + fprintf(stderr, "-> getpwuid(%d)...\n", test_uid); + passwd=getpwuid((uid_t) test_uid); + if (passwd!=NULL) + { + printf("pw_name\t\t: %s\n", passwd->pw_name); + printf("pw_passwd\t: %s\n", passwd->pw_passwd); + printf("pw_uid\t\t: %d\n", (int) passwd->pw_uid); + printf("pw_gid\t\t: %d\n", (int) passwd->pw_gid); + printf("pw_gecos\t: %s\n", passwd->pw_gecos); + printf("pw_dir\t\t: %s\n", passwd->pw_dir); + printf("pw_shell\t: %s\n", passwd->pw_shell); + } + printf("********************************************************************************\n"); + } + fprintf(stderr, "-> getpwnam()...\n"); + passwd=getpwnam("root"); + if (passwd==NULL) + { + printf(">NULL<\n"); + } + else + { + printf("pw_name\t\t: %s\n", passwd->pw_name); + printf("pw_passwd\t: %s\n", passwd->pw_passwd); + printf("pw_uid\t\t: %d\n", (int) passwd->pw_uid); + printf("pw_gid\t\t: %d\n", (int) passwd->pw_gid); + printf("pw_gecos\t: %s\n", passwd->pw_gecos); + printf("pw_dir\t\t: %s\n", passwd->pw_dir); + printf("pw_shell\t: %s\n", passwd->pw_shell); + } + return 0; +} + + diff --git a/libc-0.0.4/regexp/Config b/libc-0.0.4/regexp/Config new file mode 100644 index 0000000..bd644a6 --- /dev/null +++ b/libc-0.0.4/regexp/Config @@ -0,0 +1 @@ +regexp: Regular expression lib diff --git a/libc-0.0.4/regexp/Makefile b/libc-0.0.4/regexp/Makefile new file mode 100644 index 0000000..b330451 --- /dev/null +++ b/libc-0.0.4/regexp/Makefile @@ -0,0 +1,28 @@ + +TOP=.. +include $(TOP)/Make.defs + +OBJ=regexp.o regsub.o +LSRC=regexp.c regsub.c regerror.c + +try: try.o $(OBJ) + $(CC) $(CFLAGS) try.o $(OBJ) -o try + +# Regression test. +test: try tests + @echo 'No news is good news...' + try <tests + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +transfer: + -@rm -f ../include/regexp.h ../include/regmagic.h + cp -p regexp.h regmagic.h ../include/. + +regexp.o: regexp.c regexp.h regmagic.h +regsub.o: regsub.c regexp.h regmagic.h + +clean: + rm -f libc.a *.o core mon.out timer.t.h dMakefile dtr try timer diff --git a/libc-0.0.4/regexp/Makefile.org b/libc-0.0.4/regexp/Makefile.org new file mode 100644 index 0000000..a8be06e --- /dev/null +++ b/libc-0.0.4/regexp/Makefile.org @@ -0,0 +1,63 @@ +# Things you might want to put in ENV and LENV: +# -Dvoid=int compilers that don't do void +# -DCHARBITS=0377 compilers that don't do unsigned char +# -DSTATIC=extern compilers that don't like "static foo();" as forward decl +# -DSTRCSPN library does not have strcspn() +# -Dstrchr=index library does not have strchr() +# -DERRAVAIL have utzoo-compatible error() function and friends +# ENV=-DCHARBITS=0377 +# LENV=-DCHARBITS=0377 + +# Things you might want to put in TEST: +# -DDEBUG debugging hooks +# -I. regexp.h from current directory, not /usr/include +TEST=-I. + +# Things you might want to put in PROF: +# -Dstatic='/* */' make everything global so profiler can see it. +# -p profiler +PROF= + +CFLAGS=-O $(ENV) $(TEST) $(PROF) +LINTFLAGS=$(LENV) $(TEST) -ha +LDFLAGS=-i + +OBJ=regexp.o regsub.o +LSRC=regexp.c regsub.c regerror.c +DTR=README dMakefile regexp.3 regexp.h regexp.c regsub.c regerror.c \ + regmagic.h try.c timer.c tests + +try: try.o $(OBJ) + cc $(LDFLAGS) try.o $(OBJ) -o try + +# Making timer will probably require putting stuff in $(PROF) and then +# recompiling everything; the following is just the final stage. +timer: timer.o $(OBJ) + cc $(LDFLAGS) $(PROF) timer.o $(OBJ) -o timer + +timer.o: timer.c timer.t.h + +timer.t.h: tests + sed 's/ /","/g;s/\\/&&/g;s/.*/{"&"},/' tests >timer.t.h + +# Regression test. +r: try tests + @echo 'No news is good news...' + try <tests + +lint: timer.t.h + @echo 'Complaints about multiply-declared regerror() are legit.' + lint $(LINTFLAGS) $(LSRC) try.c + lint $(LINTFLAGS) $(LSRC) timer.c + +regexp.o: regexp.c regexp.h regmagic.h +regsub.o: regsub.c regexp.h regmagic.h + +clean: + rm -f *.o core mon.out timer.t.h dMakefile dtr try timer + +dtr: r makedtr $(DTR) + makedtr $(DTR) >dtr + +dMakefile: Makefile + sed '/^L*ENV=/s/ *-DERRAVAIL//' Makefile >dMakefile diff --git a/libc-0.0.4/regexp/README b/libc-0.0.4/regexp/README new file mode 100644 index 0000000..37d6f51 --- /dev/null +++ b/libc-0.0.4/regexp/README @@ -0,0 +1,84 @@ +This is a nearly-public-domain reimplementation of the V8 regexp(3) package. +It gives C programs the ability to use egrep-style regular expressions, and +does it in a much cleaner fashion than the analogous routines in SysV. + + Copyright (c) 1986 by University of Toronto. + Written by Henry Spencer. Not derived from licensed software. + + Permission is granted to anyone to use this software for any + purpose on any computer system, and to redistribute it freely, + subject to the following restrictions: + + 1. The author is not responsible for the consequences of use of + this software, no matter how awful, even if they arise + from defects in it. + + 2. The origin of this software must not be misrepresented, either + by explicit claim or by omission. + + 3. Altered versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +Barring a couple of small items in the BUGS list, this implementation is +believed 100% compatible with V8. It should even be binary-compatible, +sort of, since the only fields in a "struct regexp" that other people have +any business touching are declared in exactly the same way at the same +location in the struct (the beginning). + +This implementation is *NOT* AT&T/Bell code, and is not derived from licensed +software. Even though U of T is a V8 licensee. This software is based on +a V8 manual page sent to me by Dennis Ritchie (the manual page enclosed +here is a complete rewrite and hence is not covered by AT&T copyright). +The software was nearly complete at the time of arrival of our V8 tape. +I haven't even looked at V8 yet, although a friend elsewhere at U of T has +been kind enough to run a few test programs using the V8 regexp(3) to resolve +a few fine points. I admit to some familiarity with regular-expression +implementations of the past, but the only one that this code traces any +ancestry to is the one published in Kernighan & Plauger (from which this +one draws ideas but not code). + +Simplistically: put this stuff into a source directory, copy regexp.h into +/usr/include, inspect Makefile for compilation options that need changing +to suit your local environment, and then do "make r". This compiles the +regexp(3) functions, compiles a test program, and runs a large set of +regression tests. If there are no complaints, then put regexp.o, regsub.o, +and regerror.o into your C library, and regexp.3 into your manual-pages +directory. + +Note that if you don't put regexp.h into /usr/include *before* compiling, +you'll have to add "-I." to CFLAGS before compiling. + +The files are: + +Makefile instructions to make everything +regexp.3 manual page +regexp.h header file, for /usr/include +regexp.c source for regcomp() and regexec() +regsub.c source for regsub() +regerror.c source for default regerror() +regmagic.h internal header file +try.c source for test program +timer.c source for timing program +tests test list for try and timer + +This implementation uses nondeterministic automata rather than the +deterministic ones found in some other implementations, which makes it +simpler, smaller, and faster at compiling regular expressions, but slower +at executing them. In theory, anyway. This implementation does employ +some special-case optimizations to make the simpler cases (which do make +up the bulk of regular expressions actually used) run quickly. In general, +if you want blazing speed you're in the wrong place. Replacing the insides +of egrep with this stuff is probably a mistake; if you want your own egrep +you're going to have to do a lot more work. But if you want to use regular +expressions a little bit in something else, you're in luck. Note that many +existing text editors use nondeterministic regular-expression implementations, +so you're in good company. + +This stuff should be pretty portable, given appropriate option settings. +If your chars have less than 8 bits, you're going to have to change the +internal representation of the automaton, although knowledge of the details +of this is fairly localized. There are no "reserved" char values except for +NUL, and no special significance is attached to the top bit of chars. +The string(3) functions are used a fair bit, on the grounds that they are +probably faster than coding the operations in line. Some attempts at code +tuning have been made, but this is invariably a bit machine-specific. diff --git a/libc-0.0.4/regexp/README.rdb b/libc-0.0.4/regexp/README.rdb new file mode 100644 index 0000000..1c3bba6 --- /dev/null +++ b/libc-0.0.4/regexp/README.rdb @@ -0,0 +1,6 @@ + +I've applied the four bugfix patches I've found and made a couple of +very small changes (added malloc.h) and put in a new Makefile. +Otherwise this is as it was posted on by Henry Spencer to mod.sources. + +-Robert diff --git a/libc-0.0.4/regexp/patch.1 b/libc-0.0.4/regexp/patch.1 new file mode 100644 index 0000000..6126592 --- /dev/null +++ b/libc-0.0.4/regexp/patch.1 @@ -0,0 +1,32 @@ +Subject: bug in regexp(3), and fix +Newsgroups: mod.sources +Approved: jpn@panda.UUCP + +Mod.sources: Volume 3, Issue 105 +Submitted by: genrad!decvax!utzoo!henry + +Drat! Chris Siebenmann at CSRI just found a bug in my regexp(3) routines. +The problem is that the code for character classes does not check properly +for the possibility that it might be looking at the end of the string. By +simple bad luck none of my test cases hit this. To fix it, make the +following two changes to regexp.c: + +848c848 +< if (strchr(OPERAND(scan), *reginput) == NULL) +--- +> if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) +853c853 +< if (strchr(OPERAND(scan), *reginput) != NULL) +--- +> if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) + +and recompile. Also, add the following line to the "tests" file: + +[k] ab n - - + +My thanks to Chris for finding this. + + Henry Spencer @ U of Toronto Zoology + {allegra,ihnp4,linus,decvax}!utzoo!henry + + diff --git a/libc-0.0.4/regexp/patch.2 b/libc-0.0.4/regexp/patch.2 new file mode 100644 index 0000000..fcf4778 --- /dev/null +++ b/libc-0.0.4/regexp/patch.2 @@ -0,0 +1,27 @@ +Subject: 2nd bug fix for regexp(3), in regsub() +Newsgroups: mod.sources +Approved: jpn@panda.UUCP + +Mod.sources: Volume 4, Issue 33 +Submitted by: genrad!decvax!utzoo!henry + +I cringe with embarrassment! Another bug in regexp! In regsub.c, the +following line (line 72 in the original distribution): + + if (*(dst-1) == '\0') { /* strncpy hit NUL. */ + +should read + + if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */ + +This shows up as an occasional spurious complaint from regsub about +"damaged match string"... *if* the program invoking it, and the compiler +compiling it, happen to interact just right. It didn't show in any of +my tests because mine don't. + +My thanks to H}vard Eidnes for finding this. + + Henry Spencer @ U of Toronto Zoology + {allegra,ihnp4,linus,decvax}!utzoo!henry + + diff --git a/libc-0.0.4/regexp/patch.3 b/libc-0.0.4/regexp/patch.3 new file mode 100644 index 0000000..36bafd4 --- /dev/null +++ b/libc-0.0.4/regexp/patch.3 @@ -0,0 +1,46 @@ +Subject: regexp(3) improvement +Newsgroups: mod.sources +Approved: jpn@panda.UUCP + +Mod.sources: Volume 4, Issue 49 +Submitted by: utzoo!henry (Henry Spencer) + +One flaw of my regexp(3) as distributed is that there is no way to get +a literal `&' or '\n' (n a digit) past regsub(). The V8 manual page +made no mention of an escape convention. It turns out that this is a +deficiency in the documentation rather than the software. Accordingly, +the following update should be applied to my regexp(3) to preserve full +compatibility and to add this useful facility. + +In regsub.c, change the following (line numbers approximate only): + +67,69c67,71 +< if (no < 0) /* Ordinary character. */ +< *dst++ = c; +< else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { +--- +> if (no < 0) { /* Ordinary character. */ +> if (c == '\\' && (*src == '\\' || *src == '&')) +> c = *src++; +> *dst++ = c; +> } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { + +In regexp.3, add the following sentence to the end of the paragraph +describing regsub: + +To get a literal `&' or `\e\fIn\fR' into \fIdest\fR, prefix it with `\e'; +to get a literal `\e' preceding `&' or `\e\fIn\fR', prefix it with +another `\e'. + +And add the following two lines to the "tests" file: + +abcd abcd y &-\&-\\& abcd-&-\abcd +a(bc)d abcd y \1-\\1-\\\1 bc-\1-\bc + +My thanks to Mike Lutz at Rochester Institute of Technology for noticing +this issue and alerting me to it. + + Henry Spencer @ U of Toronto Zoology + {allegra,ihnp4,decvax,pyramid}!utzoo!henry + + diff --git a/libc-0.0.4/regexp/patch.4 b/libc-0.0.4/regexp/patch.4 new file mode 100644 index 0000000..4d8ea3a --- /dev/null +++ b/libc-0.0.4/regexp/patch.4 @@ -0,0 +1,65 @@ +Path: uunet!rs +From: rs@uunet.UU.NET (Rich Salz) +Newsgroups: comp.sources.unix +Subject: v10i097: Bug-fix for regexp() library +Message-ID: <789@uunet.UU.NET> +Date: 7 Aug 87 11:20:15 GMT +Organization: UUNET Communications Services, Arlington, VA +Lines: 46 +Approved: rs@uunet.UU.NET + +Submitted-by: seismo!ai.toronto.edu!utzoo!henry +Posting-number: Volume 10, Issue 97 +Archive-name: regexp.pch + +FURTHER NOTE by Rich $alz on Tue Apr 26 20:02:59 EDT 1988: + This is a patch for Henry's regexp posting that appeared in + volume 3 (first patch was volume3/regexp2; the naming + convention used by my predecessor). There is another + regexp library in volume 7 -- they're unreleated. + + The "fastgrep" posting appeards in volume 9. It also includes + Henry's volume3 posting and both sets of patches. + +[ Regexp was published by itself in volume 6, and also as part of the + "fastest grep around" earlier in this volume. --r$ ] + +Jeff Mc Carrell at Berkeley has found (gasp! choke! the horror! the horror!) +another bug in my regexp functions. One thing my test set did not include +was very large regular expressions. The bug is in the NEXT macro, which +digs out the offset to the next node of the regexp: a parenthesization +botch makes trouble if the offset is ever larger than 255. How humiliating. +Here is the fix to regexp.c: + +116c116 +< #define NEXT(p) (((*((p)+1)&0377)<<8) + *((p)+2)&0377) +--- +> #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) + +and here are some more lines for the "tests" file: + +[ -~]* abc y & abc +[ -~ -~]* abc y & abc +[ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~ -~ -~ -~]* abc y & abc + + +Just to let people know: there is some prospect of me coming out with +a second edition of my regexp stuff, including a number of improvements +that various people have suggested/contributed. However, it will not be +soon, because I'm very busy right now. I can't spare the time to sort +it all out, decide what belongs and what doesn't, write the missing bits +of code, and integrate it all. Sometime later this year, maybe. + + Henry Spencer @ U of Toronto Zoology + {allegra,ihnp4,decvax,pyramid}!utzoo!henry + + +-- + +Rich $alz "Anger is an energy" +Cronus Project, BBN Labs rsalz@bbn.com +Moderator, comp.sources.unix sources@uunet.uu.net diff --git a/libc-0.0.4/regexp/regerror.c b/libc-0.0.4/regexp/regerror.c new file mode 100644 index 0000000..63864c7 --- /dev/null +++ b/libc-0.0.4/regexp/regerror.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +void +regerror(s) +char *s; +{ +#ifdef ERRAVAIL + error("regexp: %s", s); +#else + fprintf(stderr, "regexp(3): %s", s); + exit(1); +#endif + /* NOTREACHED */ +} diff --git a/libc-0.0.4/regexp/regexp.3 b/libc-0.0.4/regexp/regexp.3 new file mode 100644 index 0000000..c0e29ea --- /dev/null +++ b/libc-0.0.4/regexp/regexp.3 @@ -0,0 +1,176 @@ +.TH REGEXP 3 local +.DA 30 Nov 1985 +.SH NAME +regcomp, regexec, regsub, regerror \- regular expression handler +.SH SYNOPSIS +.ft B +.nf +#include <regexp.h> + +regexp *regcomp(exp) +char *exp; + +int regexec(prog, string) +regexp *prog; +char *string; + +regsub(prog, source, dest) +regexp *prog; +char *source; +char *dest; + +regerror(msg) +char *msg; +.SH DESCRIPTION +These functions implement +.IR egrep (1)-style +regular expressions and supporting facilities. +.PP +.I Regcomp +compiles a regular expression into a structure of type +.IR regexp , +and returns a pointer to it. +The space has been allocated using +.IR malloc (3) +and may be released by +.IR free . +.PP +.I Regexec +matches a NUL-terminated \fIstring\fR against the compiled regular expression +in \fIprog\fR. +It returns 1 for success and 0 for failure, and adjusts the contents of +\fIprog\fR's \fIstartp\fR and \fIendp\fR (see below) accordingly. +.PP +The members of a +.I regexp +structure include at least the following (not necessarily in order): +.PP +.RS +char *startp[NSUBEXP]; +.br +char *endp[NSUBEXP]; +.RE +.PP +where +.I NSUBEXP +is defined (as 10) in the header file. +Once a successful \fIregexec\fR has been done using the \fIregexp\fR, +each \fIstartp\fR-\fIendp\fR pair describes one substring +within the \fIstring\fR, +with the \fIstartp\fR pointing to the first character of the substring and +the \fIendp\fR pointing to the first character following the substring. +The 0th substring is the substring of \fIstring\fR that matched the whole +regular expression. +The others are those substrings that matched parenthesized expressions +within the regular expression, with parenthesized expressions numbered +in left-to-right order of their opening parentheses. +.PP +.I Regsub +copies \fIsource\fR to \fIdest\fR, making substitutions according to the +most recent \fIregexec\fR performed using \fIprog\fR. +Each instance of `&' in \fIsource\fR is replaced by the substring +indicated by \fIstartp\fR[\fI0\fR] and +\fIendp\fR[\fI0\fR]. +Each instance of `\e\fIn\fR', where \fIn\fR is a digit, is replaced by +the substring indicated by +\fIstartp\fR[\fIn\fR] and +\fIendp\fR[\fIn\fR]. +.PP +.I Regerror +is called whenever an error is detected in \fIregcomp\fR, \fIregexec\fR, +or \fIregsub\fR. +The default \fIregerror\fR writes the string \fImsg\fR, +with a suitable indicator of origin, +on the standard +error output +and invokes \fIexit\fR(2). +.I Regerror +can be replaced by the user if other actions are desirable. +.SH "REGULAR EXPRESSION SYNTAX" +A regular expression is zero or more \fIbranches\fR, separated by `|'. +It matches anything that matches one of the branches. +.PP +A branch is zero or more \fIpieces\fR, concatenated. +It matches a match for the first, followed by a match for the second, etc. +.PP +A piece is an \fIatom\fR possibly followed by `*', `+', or `?'. +An atom followed by `*' matches a sequence of 0 or more matches of the atom. +An atom followed by `+' matches a sequence of 1 or more matches of the atom. +An atom followed by `?' matches a match of the atom, or the null string. +.PP +An atom is a regular expression in parentheses (matching a match for the +regular expression), a \fIrange\fR (see below), `.' +(matching any single character), `^' (matching the null string at the +beginning of the input string), `$' (matching the null string at the +end of the input string), a `\e' followed by a single character (matching +that character), or a single character with no other significance +(matching that character). +.PP +A \fIrange\fR is a sequence of characters enclosed in `[]'. +It normally matches any single character from the sequence. +If the sequence begins with `^', +it matches any single character \fInot\fR from the rest of the sequence. +If two characters in the sequence are separated by `\-', this is shorthand +for the full list of ASCII characters between them +(e.g. `[0-9]' matches any decimal digit). +To include a literal `]' in the sequence, make it the first character +(following a possible `^'). +To include a literal `\-', make it the first or last character. +.SH AMBIGUITY +If a regular expression could match two different parts of the input string, +it will match the one which begins earliest. +If both begin in the same place but match different lengths, or match +the same length in different ways, life gets messier, as follows. +.PP +In general, the possibilities in a list of branches are considered in +left-to-right order, the possibilities for `*', `+', and `?' are +considered longest-first, nested constructs are considered from the +outermost in, and concatenated constructs are considered leftmost-first. +The match that will be chosen is the one that uses the earliest +possibility in the first choice that has to be made. +If there is more than one choice, the next will be made in the same manner +(earliest possibility) subject to the decision on the first choice. +And so forth. +.PP +For example, `(ab|a)b*c' could match `abc' in one of two ways. +The first choice is between `ab' and `a'; since `ab' is earlier, and does +lead to a successful overall match, it is chosen. +Since the `b' is already spoken for, +the `b*' must match its last possibility\(emthe empty string\(emsince +it must respect the earlier choice. +.PP +In the particular case where no `|'s are present and there is only one +`*', `+', or `?', the net effect is that the longest possible +match will be chosen. +So `ab*', presented with `xabbbby', will match `abbbb'. +Note that if `ab*' is tried against `xabyabbbz', it +will match `ab' just after `x', due to the begins-earliest rule. +(In effect, the decision on where to start the match is the first choice +to be made, hence subsequent choices must respect it even if this leads them +to less-preferred alternatives.) +.SH SEE ALSO +egrep(1), expr(1) +.SH DIAGNOSTICS +\fIRegcomp\fR returns NULL for a failure +(\fIregerror\fR permitting), +where failures are syntax errors, exceeding implementation limits, +or applying `+' or `*' to a possibly-null operand. +.SH HISTORY +Both code and manual page were +written at U of T. +They are intended to be compatible with the Bell V8 \fIregexp\fR(3), +but are not derived from Bell code. +.SH BUGS +Empty branches and empty regular expressions are not portable to V8. +.PP +The restriction against +applying `*' or `+' to a possibly-null operand is an artifact of the +simplistic implementation. +.PP +Does not support \fIegrep\fR's newline-separated branches; +neither does the V8 \fIregexp\fR(3), though. +.PP +Due to emphasis on +compactness and simplicity, +it's not strikingly fast. +It does give special attention to handling simple cases quickly. diff --git a/libc-0.0.4/regexp/regexp.c b/libc-0.0.4/regexp/regexp.c new file mode 100644 index 0000000..860b485 --- /dev/null +++ b/libc-0.0.4/regexp/regexp.c @@ -0,0 +1,1213 @@ +/* + * regcomp and regexec -- regsub and regerror are elsewhere + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * Beware that some of this code is subtly aware of the way operator + * precedence is structured in regular expressions. Serious changes in + * regular-expression syntax might require a total rethink. + */ +#include <stdio.h> +#include <regexp.h> +#include <malloc.h> +#include <string.h> +#include "regmagic.h" + +/* + * The "internal use only" fields in regexp.h are present to pass info from + * compile to execute that permits the execute phase to run lots faster on + * simple cases. They are: + * + * regstart char that must begin a match; '\0' if none obvious + * reganch is the match anchored (at beginning-of-line only)? + * regmust string (pointer into program) that match must include, or NULL + * regmlen length of regmust string + * + * Regstart and reganch permit very fast decisions on suitable starting points + * for a match, cutting down the work a lot. Regmust permits fast rejection + * of lines that cannot possibly match. The regmust tests are costly enough + * that regcomp() supplies a regmust only if the r.e. contains something + * potentially expensive (at present, the only such thing detected is * or + + * at the start of the r.e., which can involve a lot of backup). Regmlen is + * supplied because the test in regexec() needs it and regcomp() is computing + * it anyway. + */ + +/* + * Structure for regexp "program". This is essentially a linear encoding + * of a nondeterministic finite-state machine (aka syntax charts or + * "railroad normal form" in parsing technology). Each node is an opcode + * plus a "next" pointer, possibly plus an operand. "Next" pointers of + * all nodes except BRANCH implement concatenation; a "next" pointer with + * a BRANCH on both ends of it is connecting two alternatives. (Here we + * have one of the subtle syntax dependencies: an individual BRANCH (as + * opposed to a collection of them) is never concatenated with anything + * because of operator precedence.) The operand of some types of node is + * a literal string; for others, it is a node leading into a sub-FSM. In + * particular, the operand of a BRANCH node is the first node of the branch. + * (NB this is *not* a tree structure: the tail of the branch connects + * to the thing following the set of BRANCHes.) The opcodes are: + */ + +/* definition number opnd? meaning */ +#define END 0 /* no End of program. */ +#define BOL 1 /* no Match "" at beginning of line. */ +#define EOL 2 /* no Match "" at end of line. */ +#define ANY 3 /* no Match any one character. */ +#define ANYOF 4 /* str Match any character in this string. */ +#define ANYBUT 5 /* str Match any character not in this string. */ +#define BRANCH 6 /* node Match this alternative, or the next... */ +#define BACK 7 /* no Match "", "next" ptr points backward. */ +#define EXACTLY 8 /* str Match this string. */ +#define NOTHING 9 /* no Match empty string. */ +#define STAR 10 /* node Match this (simple) thing 0 or more times. */ +#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ +#define OPEN 20 /* no Mark this point in input as start of #n. */ + /* OPEN+1 is number 1, etc. */ +#define CLOSE 30 /* no Analogous to OPEN. */ + +/* + * Opcode notes: + * + * BRANCH The set of branches constituting a single choice are hooked + * together with their "next" pointers, since precedence prevents + * anything being concatenated to any individual branch. The + * "next" pointer of the last BRANCH in a choice points to the + * thing following the whole choice. This is also where the + * final "next" pointer of each individual branch points; each + * branch starts with the operand node of a BRANCH node. + * + * BACK Normal "next" pointers all implicitly point forward; BACK + * exists to make loop structures possible. + * + * STAR,PLUS '?', and complex '*' and '+', are implemented as circular + * BRANCH structures using BACK. Simple cases (one character + * per match) are implemented with STAR and PLUS for speed + * and to minimize recursive plunges. + * + * OPEN,CLOSE ...are numbered at compile time. + */ + +/* + * A node is one char of opcode followed by two chars of "next" pointer. + * "Next" pointers are stored as two 8-bit pieces, high order first. The + * value is a positive offset from the opcode of the node containing it. + * An operand, if any, simply follows the node. (Note that much of the + * code generation knows about this implicit relationship.) + * + * Using two bytes for the "next" pointer is vast overkill for most things, + * but allows patterns to get big without disasters. + */ +#define OP(p) (*(p)) +#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) +#define OPERAND(p) ((p) + 3) + +/* + * See regmagic.h for one further detail of program structure. + */ + + +/* + * Utility definitions. + */ +#ifndef CHARBITS +#define UCHARAT(p) ((int)*(unsigned char *)(p)) +#else +#define UCHARAT(p) ((int)*(p)&CHARBITS) +#endif + +#define FAIL(m) { regerror(m); return(NULL); } +#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') +#define META "^$.[()|?+*\\" + +/* + * Flags to be passed up and down. + */ +#define HASWIDTH 01 /* Known never to match null string. */ +#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ +#define SPSTART 04 /* Starts with * or +. */ +#define WORST 0 /* Worst case. */ + +/* + * Global work variables for regcomp(). + */ +static char *regparse; /* Input-scan pointer. */ +static int regnpar; /* () count. */ +static char regdummy; +static char *regcode; /* Code-emit pointer; ®dummy = don't. */ +static long regsize; /* Code size. */ + +/* + * Forward declarations for regcomp()'s friends. + */ +#ifndef STATIC +#define STATIC static +#endif +STATIC char *reg(); +STATIC char *regbranch(); +STATIC char *regpiece(); +STATIC char *regatom(); +STATIC char *regnode(); +STATIC char *regnext(); +STATIC void regc(); +STATIC void reginsert(); +STATIC void regtail(); +STATIC void regoptail(); +#ifdef STRCSPN +STATIC int strcspn(); +#endif + +/* + - regcomp - compile a regular expression into internal code + * + * We can't allocate space until we know how big the compiled form will be, + * but we can't compile it (and thus know how big it is) until we've got a + * place to put the code. So we cheat: we compile it twice, once with code + * generation turned off and size counting turned on, and once "for real". + * This also means that we don't allocate space until we are sure that the + * thing really will compile successfully, and we never have to move the + * code and thus invalidate pointers into it. (Note that it has to be in + * one piece because free() must be able to free it all.) + * + * Beware that the optimization-preparation code in here knows about some + * of the structure of the compiled regexp. + */ +regexp * +regcomp(exp) +char *exp; +{ + register regexp *r; + register char *scan; + register char *longest; + register int len; + int flags; + + if (exp == NULL) + FAIL("NULL argument"); + + /* First pass: determine size, legality. */ + regparse = exp; + regnpar = 1; + regsize = 0L; + regcode = ®dummy; + regc(MAGIC); + if (reg(0, &flags) == NULL) + return(NULL); + + /* Small enough for pointer-storage convention? */ + if (regsize >= 32767L) /* Probably could be 65535L. */ + FAIL("regexp too big"); + + /* Allocate space. */ + r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); + if (r == NULL) + FAIL("out of space"); + + /* Second pass: emit code. */ + regparse = exp; + regnpar = 1; + regcode = r->program; + regc(MAGIC); + if (reg(0, &flags) == NULL) + return(NULL); + + /* Dig out information for optimizations. */ + r->regstart = '\0'; /* Worst-case defaults. */ + r->reganch = 0; + r->regmust = NULL; + r->regmlen = 0; + scan = r->program+1; /* First BRANCH. */ + if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ + scan = OPERAND(scan); + + /* Starting-point info. */ + if (OP(scan) == EXACTLY) + r->regstart = *OPERAND(scan); + else if (OP(scan) == BOL) + r->reganch++; + + /* + * If there's something expensive in the r.e., find the + * longest literal string that must appear and make it the + * regmust. Resolve ties in favor of later strings, since + * the regstart check works with the beginning of the r.e. + * and avoiding duplication strengthens checking. Not a + * strong reason, but sufficient in the absence of others. + */ + if (flags&SPSTART) { + longest = NULL; + len = 0; + for (; scan != NULL; scan = regnext(scan)) + if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { + longest = OPERAND(scan); + len = strlen(OPERAND(scan)); + } + r->regmust = longest; + r->regmlen = len; + } + } + + return(r); +} + +/* + - reg - regular expression, i.e. main body or parenthesized thing + * + * Caller must absorb opening parenthesis. + * + * Combining parenthesis handling with the base level of regular expression + * is a trifle forced, but the need to tie the tails of the branches to what + * follows makes it hard to avoid. + */ +static char * +reg(paren, flagp) +int paren; /* Parenthesized? */ +int *flagp; +{ + register char *ret; + register char *br; + register char *ender; + register int parno; + int flags; + + *flagp = HASWIDTH; /* Tentatively. */ + + /* Make an OPEN node, if parenthesized. */ + if (paren) { + if (regnpar >= NSUBEXP) + FAIL("too many ()"); + parno = regnpar; + regnpar++; + ret = regnode(OPEN+parno); + } else + ret = NULL; + + /* Pick up the branches, linking them together. */ + br = regbranch(&flags); + if (br == NULL) + return(NULL); + if (ret != NULL) + regtail(ret, br); /* OPEN -> first. */ + else + ret = br; + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + while (*regparse == '|') { + regparse++; + br = regbranch(&flags); + if (br == NULL) + return(NULL); + regtail(ret, br); /* BRANCH -> BRANCH. */ + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + } + + /* Make a closing node, and hook it on the end. */ + ender = regnode((paren) ? CLOSE+parno : END); + regtail(ret, ender); + + /* Hook the tails of the branches to the closing node. */ + for (br = ret; br != NULL; br = regnext(br)) + regoptail(br, ender); + + /* Check for proper termination. */ + if (paren && *regparse++ != ')') { + FAIL("unmatched ()"); + } else if (!paren && *regparse != '\0') { + if (*regparse == ')') { + FAIL("unmatched ()"); + } else + FAIL("junk on end"); /* "Can't happen". */ + /* NOTREACHED */ + } + + return(ret); +} + +/* + - regbranch - one alternative of an | operator + * + * Implements the concatenation operator. + */ +static char * +regbranch(flagp) +int *flagp; +{ + register char *ret; + register char *chain; + register char *latest; + int flags; + + *flagp = WORST; /* Tentatively. */ + + ret = regnode(BRANCH); + chain = NULL; + while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { + latest = regpiece(&flags); + if (latest == NULL) + return(NULL); + *flagp |= flags&HASWIDTH; + if (chain == NULL) /* First piece. */ + *flagp |= flags&SPSTART; + else + regtail(chain, latest); + chain = latest; + } + if (chain == NULL) /* Loop ran zero times. */ + (void) regnode(NOTHING); + + return(ret); +} + +/* + - regpiece - something followed by possible [*+?] + * + * Note that the branching code sequences used for ? and the general cases + * of * and + are somewhat optimized: they use the same NOTHING node as + * both the endmarker for their branch list and the body of the last branch. + * It might seem that this node could be dispensed with entirely, but the + * endmarker role is not redundant. + */ +static char * +regpiece(flagp) +int *flagp; +{ + register char *ret; + register char op; + register char *next; + int flags; + + ret = regatom(&flags); + if (ret == NULL) + return(NULL); + + op = *regparse; + if (!ISMULT(op)) { + *flagp = flags; + return(ret); + } + + if (!(flags&HASWIDTH) && op != '?') + FAIL("*+ operand could be empty"); + *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); + + if (op == '*' && (flags&SIMPLE)) + reginsert(STAR, ret); + else if (op == '*') { + /* Emit x* as (x&|), where & means "self". */ + reginsert(BRANCH, ret); /* Either x */ + regoptail(ret, regnode(BACK)); /* and loop */ + regoptail(ret, ret); /* back */ + regtail(ret, regnode(BRANCH)); /* or */ + regtail(ret, regnode(NOTHING)); /* null. */ + } else if (op == '+' && (flags&SIMPLE)) + reginsert(PLUS, ret); + else if (op == '+') { + /* Emit x+ as x(&|), where & means "self". */ + next = regnode(BRANCH); /* Either */ + regtail(ret, next); + regtail(regnode(BACK), ret); /* loop back */ + regtail(next, regnode(BRANCH)); /* or */ + regtail(ret, regnode(NOTHING)); /* null. */ + } else if (op == '?') { + /* Emit x? as (x|) */ + reginsert(BRANCH, ret); /* Either x */ + regtail(ret, regnode(BRANCH)); /* or */ + next = regnode(NOTHING); /* null. */ + regtail(ret, next); + regoptail(ret, next); + } + regparse++; + if (ISMULT(*regparse)) + FAIL("nested *?+"); + + return(ret); +} + +/* + - regatom - the lowest level + * + * Optimization: gobbles an entire sequence of ordinary characters so that + * it can turn them into a single node, which is smaller to store and + * faster to run. Backslashed characters are exceptions, each becoming a + * separate node; the code is simpler that way and it's not worth fixing. + */ +static char * +regatom(flagp) +int *flagp; +{ + register char *ret; + int flags; + + *flagp = WORST; /* Tentatively. */ + + switch (*regparse++) { + case '^': + ret = regnode(BOL); + break; + case '$': + ret = regnode(EOL); + break; + case '.': + ret = regnode(ANY); + *flagp |= HASWIDTH|SIMPLE; + break; + case '[': { + register int class; + register int classend; + + if (*regparse == '^') { /* Complement of range. */ + ret = regnode(ANYBUT); + regparse++; + } else + ret = regnode(ANYOF); + if (*regparse == ']' || *regparse == '-') + regc(*regparse++); + while (*regparse != '\0' && *regparse != ']') { + if (*regparse == '-') { + regparse++; + if (*regparse == ']' || *regparse == '\0') + regc('-'); + else { + class = UCHARAT(regparse-2)+1; + classend = UCHARAT(regparse); + if (class > classend+1) + FAIL("invalid [] range"); + for (; class <= classend; class++) + regc(class); + regparse++; + } + } else + regc(*regparse++); + } + regc('\0'); + if (*regparse != ']') + FAIL("unmatched []"); + regparse++; + *flagp |= HASWIDTH|SIMPLE; + } + break; + case '(': + ret = reg(1, &flags); + if (ret == NULL) + return(NULL); + *flagp |= flags&(HASWIDTH|SPSTART); + break; + case '\0': + case '|': + case ')': + FAIL("internal urp"); /* Supposed to be caught earlier. */ + break; + case '?': + case '+': + case '*': + FAIL("?+* follows nothing"); + break; + case '\\': + if (*regparse == '\0') + FAIL("trailing \\"); + ret = regnode(EXACTLY); + regc(*regparse++); + regc('\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + default: { + register int len; + register char ender; + + regparse--; + len = strcspn(regparse, META); + if (len <= 0) + FAIL("internal disaster"); + ender = *(regparse+len); + if (len > 1 && ISMULT(ender)) + len--; /* Back off clear of ?+* operand. */ + *flagp |= HASWIDTH; + if (len == 1) + *flagp |= SIMPLE; + ret = regnode(EXACTLY); + while (len > 0) { + regc(*regparse++); + len--; + } + regc('\0'); + } + break; + } + + return(ret); +} + +/* + - regnode - emit a node + */ +static char * /* Location. */ +regnode(op) +char op; +{ + register char *ret; + register char *ptr; + + ret = regcode; + if (ret == ®dummy) { + regsize += 3; + return(ret); + } + + ptr = ret; + *ptr++ = op; + *ptr++ = '\0'; /* Null "next" pointer. */ + *ptr++ = '\0'; + regcode = ptr; + + return(ret); +} + +/* + - regc - emit (if appropriate) a byte of code + */ +static void +regc(b) +char b; +{ + if (regcode != ®dummy) + *regcode++ = b; + else + regsize++; +} + +/* + - reginsert - insert an operator in front of already-emitted operand + * + * Means relocating the operand. + */ +static void +reginsert(op, opnd) +char op; +char *opnd; +{ + register char *src; + register char *dst; + register char *place; + + if (regcode == ®dummy) { + regsize += 3; + return; + } + + src = regcode; + regcode += 3; + dst = regcode; + while (src > opnd) + *--dst = *--src; + + place = opnd; /* Op node, where operand used to be. */ + *place++ = op; + *place++ = '\0'; + *place++ = '\0'; +} + +/* + - regtail - set the next-pointer at the end of a node chain + */ +static void +regtail(p, val) +char *p; +char *val; +{ + register char *scan; + register char *temp; + register int offset; + + if (p == ®dummy) + return; + + /* Find last node. */ + scan = p; + for (;;) { + temp = regnext(scan); + if (temp == NULL) + break; + scan = temp; + } + + if (OP(scan) == BACK) + offset = scan - val; + else + offset = val - scan; + *(scan+1) = (offset>>8)&0377; + *(scan+2) = offset&0377; +} + +/* + - regoptail - regtail on operand of first argument; nop if operandless + */ +static void +regoptail(p, val) +char *p; +char *val; +{ + /* "Operandless" and "op != BRANCH" are synonymous in practice. */ + if (p == NULL || p == ®dummy || OP(p) != BRANCH) + return; + regtail(OPERAND(p), val); +} + +/* + * regexec and friends + */ + +/* + * Global work variables for regexec(). + */ +static char *reginput; /* String-input pointer. */ +static char *regbol; /* Beginning of input, for ^ check. */ +static char **regstartp; /* Pointer to startp array. */ +static char **regendp; /* Ditto for endp. */ + +/* + * Forwards. + */ +STATIC int regtry(); +STATIC int regmatch(); +STATIC int regrepeat(); + +#ifdef DEBUG +int regnarrate = 0; +void regdump(); +STATIC char *regprop(); +#endif + +/* + - regexec - match a regexp against a string + */ +int +regexec(prog, string) +register regexp *prog; +register char *string; +{ + register char *s; + + /* Be paranoid... */ + if (prog == NULL || string == NULL) { + regerror("NULL parameter"); + return(0); + } + + /* Check validity of program. */ + if (UCHARAT(prog->program) != MAGIC) { + regerror("corrupted program"); + return(0); + } + + /* If there is a "must appear" string, look for it. */ + if (prog->regmust != NULL) { + s = string; + while ((s = strchr(s, prog->regmust[0])) != NULL) { + if (strncmp(s, prog->regmust, prog->regmlen) == 0) + break; /* Found it. */ + s++; + } + if (s == NULL) /* Not present. */ + return(0); + } + + /* Mark beginning of line for ^ . */ + regbol = string; + + /* Simplest case: anchored match need be tried only once. */ + if (prog->reganch) + return(regtry(prog, string)); + + /* Messy cases: unanchored match. */ + s = string; + if (prog->regstart != '\0') + /* We know what char it must start with. */ + while ((s = strchr(s, prog->regstart)) != NULL) { + if (regtry(prog, s)) + return(1); + s++; + } + else + /* We don't -- general case. */ + do { + if (regtry(prog, s)) + return(1); + } while (*s++ != '\0'); + + /* Failure. */ + return(0); +} + +/* + - regtry - try match at specific point + */ +static int /* 0 failure, 1 success */ +regtry(prog, string) +regexp *prog; +char *string; +{ + register int i; + register char **sp; + register char **ep; + + reginput = string; + regstartp = prog->startp; + regendp = prog->endp; + + sp = prog->startp; + ep = prog->endp; + for (i = NSUBEXP; i > 0; i--) { + *sp++ = NULL; + *ep++ = NULL; + } + if (regmatch(prog->program + 1)) { + prog->startp[0] = string; + prog->endp[0] = reginput; + return(1); + } else + return(0); +} + +/* + - regmatch - main matching routine + * + * Conceptually the strategy is simple: check to see whether the current + * node matches, call self recursively to see whether the rest matches, + * and then act accordingly. In practice we make some effort to avoid + * recursion, in particular by going through "ordinary" nodes (that don't + * need to know whether the rest of the match failed) by a loop instead of + * by recursion. + */ +static int /* 0 failure, 1 success */ +regmatch(prog) +char *prog; +{ + register char *scan; /* Current node. */ + char *next; /* Next node. */ + extern char *strchr(); + + scan = prog; +#ifdef DEBUG + if (scan != NULL && regnarrate) + fprintf(stderr, "%s(\n", regprop(scan)); +#endif + while (scan != NULL) { +#ifdef DEBUG + if (regnarrate) + fprintf(stderr, "%s...\n", regprop(scan)); +#endif + next = regnext(scan); + + switch (OP(scan)) { + case BOL: + if (reginput != regbol) + return(0); + break; + case EOL: + if (*reginput != '\0') + return(0); + break; + case ANY: + if (*reginput == '\0') + return(0); + reginput++; + break; + case EXACTLY: { + register int len; + register char *opnd; + + opnd = OPERAND(scan); + /* Inline the first character, for speed. */ + if (*opnd != *reginput) + return(0); + len = strlen(opnd); + if (len > 1 && strncmp(opnd, reginput, len) != 0) + return(0); + reginput += len; + } + break; + case ANYOF: + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) + return(0); + reginput++; + break; + case ANYBUT: + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) + return(0); + reginput++; + break; + case NOTHING: + break; + case BACK: + break; + case OPEN+1: + case OPEN+2: + case OPEN+3: + case OPEN+4: + case OPEN+5: + case OPEN+6: + case OPEN+7: + case OPEN+8: + case OPEN+9: { + register int no; + register char *save; + + no = OP(scan) - OPEN; + save = reginput; + + if (regmatch(next)) { + /* + * Don't set startp if some later + * invocation of the same parentheses + * already has. + */ + if (regstartp[no] == NULL) + regstartp[no] = save; + return(1); + } else + return(0); + } + break; + case CLOSE+1: + case CLOSE+2: + case CLOSE+3: + case CLOSE+4: + case CLOSE+5: + case CLOSE+6: + case CLOSE+7: + case CLOSE+8: + case CLOSE+9: { + register int no; + register char *save; + + no = OP(scan) - CLOSE; + save = reginput; + + if (regmatch(next)) { + /* + * Don't set endp if some later + * invocation of the same parentheses + * already has. + */ + if (regendp[no] == NULL) + regendp[no] = save; + return(1); + } else + return(0); + } + break; + case BRANCH: { + register char *save; + + if (OP(next) != BRANCH) /* No choice. */ + next = OPERAND(scan); /* Avoid recursion. */ + else { + do { + save = reginput; + if (regmatch(OPERAND(scan))) + return(1); + reginput = save; + scan = regnext(scan); + } while (scan != NULL && OP(scan) == BRANCH); + return(0); + /* NOTREACHED */ + } + } + break; + case STAR: + case PLUS: { + register char nextch; + register int no; + register char *save; + register int min; + + /* + * Lookahead to avoid useless match attempts + * when we know what character comes next. + */ + nextch = '\0'; + if (OP(next) == EXACTLY) + nextch = *OPERAND(next); + min = (OP(scan) == STAR) ? 0 : 1; + save = reginput; + no = regrepeat(OPERAND(scan)); + while (no >= min) { + /* If it could work, try it. */ + if (nextch == '\0' || *reginput == nextch) + if (regmatch(next)) + return(1); + /* Couldn't or didn't -- back up. */ + no--; + reginput = save + no; + } + return(0); + } + break; + case END: + return(1); /* Success! */ + break; + default: + regerror("memory corruption"); + return(0); + break; + } + + scan = next; + } + + /* + * We get here only if there's trouble -- normally "case END" is + * the terminating point. + */ + regerror("corrupted pointers"); + return(0); +} + +/* + - regrepeat - repeatedly match something simple, report how many + */ +static int +regrepeat(p) +char *p; +{ + register int count = 0; + register char *scan; + register char *opnd; + + scan = reginput; + opnd = OPERAND(p); + switch (OP(p)) { + case ANY: + count = strlen(scan); + scan += count; + break; + case EXACTLY: + while (*opnd == *scan) { + count++; + scan++; + } + break; + case ANYOF: + while (*scan != '\0' && strchr(opnd, *scan) != NULL) { + count++; + scan++; + } + break; + case ANYBUT: + while (*scan != '\0' && strchr(opnd, *scan) == NULL) { + count++; + scan++; + } + break; + default: /* Oh dear. Called inappropriately. */ + regerror("internal foulup"); + count = 0; /* Best compromise. */ + break; + } + reginput = scan; + + return(count); +} + +/* + - regnext - dig the "next" pointer out of a node + */ +static char * +regnext(p) +register char *p; +{ + register int offset; + + if (p == ®dummy) + return(NULL); + + offset = NEXT(p); + if (offset == 0) + return(NULL); + + if (OP(p) == BACK) + return(p-offset); + else + return(p+offset); +} + +#ifdef DEBUG + +STATIC char *regprop(); + +/* + - regdump - dump a regexp onto stdout in vaguely comprehensible form + */ +void +regdump(r) +regexp *r; +{ + register char *s; + register char op = EXACTLY; /* Arbitrary non-END op. */ + register char *next; + extern char *strchr(); + + + s = r->program + 1; + while (op != END) { /* While that wasn't END last time... */ + op = OP(s); + printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ + next = regnext(s); + if (next == NULL) /* Next ptr. */ + printf("(0)"); + else + printf("(%d)", (s-r->program)+(next-s)); + s += 3; + if (op == ANYOF || op == ANYBUT || op == EXACTLY) { + /* Literal string, where present. */ + while (*s != '\0') { + putchar(*s); + s++; + } + s++; + } + putchar('\n'); + } + + /* Header fields of interest. */ + if (r->regstart != '\0') + printf("start `%c' ", r->regstart); + if (r->reganch) + printf("anchored "); + if (r->regmust != NULL) + printf("must have \"%s\"", r->regmust); + printf("\n"); +} + +/* + - regprop - printable representation of opcode + */ +static char * +regprop(op) +char *op; +{ + register char *p; + static char buf[50]; + + (void) strcpy(buf, ":"); + + switch (OP(op)) { + case BOL: + p = "BOL"; + break; + case EOL: + p = "EOL"; + break; + case ANY: + p = "ANY"; + break; + case ANYOF: + p = "ANYOF"; + break; + case ANYBUT: + p = "ANYBUT"; + break; + case BRANCH: + p = "BRANCH"; + break; + case EXACTLY: + p = "EXACTLY"; + break; + case NOTHING: + p = "NOTHING"; + break; + case BACK: + p = "BACK"; + break; + case END: + p = "END"; + break; + case OPEN+1: + case OPEN+2: + case OPEN+3: + case OPEN+4: + case OPEN+5: + case OPEN+6: + case OPEN+7: + case OPEN+8: + case OPEN+9: + sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); + p = NULL; + break; + case CLOSE+1: + case CLOSE+2: + case CLOSE+3: + case CLOSE+4: + case CLOSE+5: + case CLOSE+6: + case CLOSE+7: + case CLOSE+8: + case CLOSE+9: + sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); + p = NULL; + break; + case STAR: + p = "STAR"; + break; + case PLUS: + p = "PLUS"; + break; + default: + regerror("corrupted opcode"); + break; + } + if (p != NULL) + (void) strcat(buf, p); + return(buf); +} +#endif + +/* + * The following is provided for those people who do not have strcspn() in + * their C libraries. They should get off their butts and do something + * about it; at least one public-domain implementation of those (highly + * useful) string routines has been published on Usenet. + */ +#ifdef STRCSPN +/* + * strcspn - find length of initial segment of s1 consisting entirely + * of characters not from s2 + */ + +static int +strcspn(s1, s2) +char *s1; +char *s2; +{ + register char *scan1; + register char *scan2; + register int count; + + count = 0; + for (scan1 = s1; *scan1 != '\0'; scan1++) { + for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ + if (*scan1 == *scan2++) + return(count); + count++; + } + return(count); +} +#endif diff --git a/libc-0.0.4/regexp/regexp.h b/libc-0.0.4/regexp/regexp.h new file mode 100644 index 0000000..73d6bf4 --- /dev/null +++ b/libc-0.0.4/regexp/regexp.h @@ -0,0 +1,21 @@ +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + */ +#define NSUBEXP 10 +typedef struct regexp { + char *startp[NSUBEXP]; + char *endp[NSUBEXP]; + char regstart; /* Internal use only. */ + char reganch; /* Internal use only. */ + char *regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + char program[1]; /* Unwarranted chumminess with compiler. */ +} regexp; + +extern regexp *regcomp(); +extern int regexec(); +extern void regsub(); +extern void regerror(); diff --git a/libc-0.0.4/regexp/regmagic.h b/libc-0.0.4/regexp/regmagic.h new file mode 100644 index 0000000..5acf447 --- /dev/null +++ b/libc-0.0.4/regexp/regmagic.h @@ -0,0 +1,5 @@ +/* + * The first byte of the regexp internal "program" is actually this magic + * number; the start node begins in the second byte. + */ +#define MAGIC 0234 diff --git a/libc-0.0.4/regexp/regsub.c b/libc-0.0.4/regexp/regsub.c new file mode 100644 index 0000000..5ca5676 --- /dev/null +++ b/libc-0.0.4/regexp/regsub.c @@ -0,0 +1,82 @@ +/* + * regsub + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + */ +#include <stdio.h> +#include <regexp.h> +#include "regmagic.h" + +#ifndef CHARBITS +#define UCHARAT(p) ((int)*(unsigned char *)(p)) +#else +#define UCHARAT(p) ((int)*(p)&CHARBITS) +#endif + +/* + - regsub - perform substitutions after a regexp match + */ +void +regsub(prog, source, dest) +regexp *prog; +char *source; +char *dest; +{ + register char *src; + register char *dst; + register char c; + register int no; + register int len; + extern char *strncpy(); + + if (prog == NULL || source == NULL || dest == NULL) { + regerror("NULL parm to regsub"); + return; + } + if (UCHARAT(prog->program) != MAGIC) { + regerror("damaged regexp fed to regsub"); + return; + } + + src = source; + dst = dest; + while ((c = *src++) != '\0') { + if (c == '&') + no = 0; + else if (c == '\\' && '0' <= *src && *src <= '9') + no = *src++ - '0'; + else + no = -1; + + if (no < 0) { /* Ordinary character. */ + if (c == '\\' && (*src == '\\' || *src == '&')) + c = *src++; + *dst++ = c; + } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { + len = prog->endp[no] - prog->startp[no]; + (void) strncpy(dst, prog->startp[no], len); + dst += len; + if (len != 0 && *(dst-1) == '\0') { + /* strncpy hit NUL. */ + regerror("damaged match string"); + return; + } + } + } + *dst++ = '\0'; +} diff --git a/libc-0.0.4/regexp/tests b/libc-0.0.4/regexp/tests new file mode 100644 index 0000000..e5bc16d --- /dev/null +++ b/libc-0.0.4/regexp/tests @@ -0,0 +1,127 @@ +abc abc y & abc +abc xbc n - - +abc axc n - - +abc abx n - - +abc xabcy y & abc +abc ababc y & abc +ab*c abc y & abc +ab*bc abc y & abc +ab*bc abbc y & abbc +ab*bc abbbbc y & abbbbc +ab+bc abbc y & abbc +ab+bc abc n - - +ab+bc abq n - - +ab+bc abbbbc y & abbbbc +ab?bc abbc y & abbc +ab?bc abc y & abc +ab?bc abbbbc n - - +ab?c abc y & abc +^abc$ abc y & abc +^abc$ abcc n - - +^abc abcc y & abc +^abc$ aabc n - - +abc$ aabc y & abc +^ abc y & +$ abc y & +a.c abc y & abc +a.c axc y & axc +a.*c axyzc y & axyzc +a.*c axyzd n - - +a[bc]d abc n - - +a[bc]d abd y & abd +a[b-d]e abd n - - +a[b-d]e ace y & ace +a[b-d] aac y & ac +a[-b] a- y & a- +a[b-] a- y & a- +a[b-a] - c - - +a[]b - c - - +a[ - c - - +a] a] y & a] +a[]]b a]b y & a]b +a[^bc]d aed y & aed +a[^bc]d abd n - - +a[^-b]c adc y & adc +a[^-b]c a-c n - - +a[^]b]c a]c n - - +a[^]b]c adc y & adc +ab|cd abc y & ab +ab|cd abcd y & ab +()ef def y &-\1 ef- +()* - c - - +*a - c - - +^* - c - - +$* - c - - +(*)b - c - - +$b b n - - +a\ - c - - +a\(b a(b y &-\1 a(b- +a\(*b ab y & ab +a\(*b a((b y & a((b +a\\b a\b y & a\b +abc) - c - - +(abc - c - - +((a)) abc y &-\1-\2 a-a-a +(a)b(c) abc y &-\1-\2 abc-a-c +a+b+c aabbabc y & abc +a** - c - - +a*? - c - - +(a*)* - c - - +(a*)+ - c - - +(a|)* - c - - +(a*|b)* - c - - +(a+|b)* ab y &-\1 ab-b +(a+|b)+ ab y &-\1 ab-b +(a+|b)? ab y &-\1 a-a +[^ab]* cde y & cde +(^)* - c - - +(ab|)* - c - - +)( - c - - + abc y & +abc n - - +a* y & +([abc])*d abbbcd y &-\1 abbbcd-c +([abc])*bcd abcd y &-\1 abcd-a +a|b|c|d|e e y & e +(a|b|c|d|e)f ef y &-\1 ef-e +((a*|b))* - c - - +abcd*efg abcdefg y & abcdefg +ab* xabyabbbz y & ab +ab* xayabbbz y & a +(ab|cd)e abcde y &-\1 cde-cd +[abhgefdc]ij hij y & hij +^(ab|cd)e abcde n x\1y xy +(abc|)ef abcdef y &-\1 ef- +(a|b)c*d abcd y &-\1 bcd-b +(ab|ab*)bc abc y &-\1 abc-a +a([bc]*)c* abc y &-\1 abc-bc +a([bc]*)(c*d) abcd y &-\1-\2 abcd-bc-d +a([bc]+)(c*d) abcd y &-\1-\2 abcd-bc-d +a([bc]*)(c+d) abcd y &-\1-\2 abcd-b-cd +a[bcd]*dcdcde adcdcde y & adcdcde +a[bcd]+dcdcde adcdcde n - - +(ab|a)b*c abc y &-\1 abc-ab +((a)(b)c)(d) abcd y \1-\2-\3-\4 abc-a-b-d +[a-zA-Z_][a-zA-Z0-9_]* alpha y & alpha +^a(bc+|b[eh])g|.h$ abh y &-\1 bh- +(bc+d$|ef*g.|h?i(j|k)) effgz y &-\1-\2 effgz-effgz- +(bc+d$|ef*g.|h?i(j|k)) ij y &-\1-\2 ij-ij-j +(bc+d$|ef*g.|h?i(j|k)) effg n - - +(bc+d$|ef*g.|h?i(j|k)) bcdd n - - +(bc+d$|ef*g.|h?i(j|k)) reffgz y &-\1-\2 effgz-effgz- +((((((((((a)))))))))) - c - - +(((((((((a))))))))) a y & a +multiple words of text uh-uh n - - +multiple words multiple words, yeah y & multiple words +(.*)c(.*) abcde y &-\1-\2 abcde-ab-de +\((.*), (.*)\) (a, b) y (\2, \1) (b, a) +[k] ab n - - +abcd abcd y &-\&-\\& abcd-&-\abcd +a(bc)d abcd y \1-\\1-\\\1 bc-\1-\bc +[ -~]* abc y & abc +[ -~ -~]* abc y & abc +[ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~ -~ -~]* abc y & abc +[ -~ -~ -~ -~ -~ -~ -~]* abc y & abc diff --git a/libc-0.0.4/regexp/timer.c b/libc-0.0.4/regexp/timer.c new file mode 100644 index 0000000..2d84a12 --- /dev/null +++ b/libc-0.0.4/regexp/timer.c @@ -0,0 +1,182 @@ +/* + * Simple timing program for regcomp(). + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * Usage: timer ncomp nexec nsub + * or + * timer ncomp nexec nsub regexp string [ answer [ sub ] ] + * + * The second form is for timing repetitions of a single test case. + * The first form's test data is a compiled-in copy of the "tests" file. + * Ncomp, nexec, nsub are how many times to do each regcomp, regexec, + * and regsub. The way to time an operation individually is to do something + * like "timer 1 50 1". + */ +#include <stdio.h> + +struct try { + char *re, *str, *ans, *src, *dst; +} tests[] = { +#include "timer.t.h" +{ NULL, NULL, NULL, NULL, NULL } +}; + +#include <regexp.h> + +int errreport = 0; /* Report errors via errseen? */ +char *errseen = NULL; /* Error message. */ + +char *progname; + +/* ARGSUSED */ +main(argc, argv) +int argc; +char *argv[]; +{ + int ncomp, nexec, nsub; + struct try one; + char dummy[512]; + + if (argc < 4) { + ncomp = 1; + nexec = 1; + nsub = 1; + } else { + ncomp = atoi(argv[1]); + nexec = atoi(argv[2]); + nsub = atoi(argv[3]); + } + + progname = argv[0]; + if (argc > 5) { + one.re = argv[4]; + one.str = argv[5]; + if (argc > 6) + one.ans = argv[6]; + else + one.ans = "y"; + if (argc > 7) { + one.src = argv[7]; + one.dst = "xxx"; + } else { + one.src = "x"; + one.dst = "x"; + } + errreport = 1; + try(one, ncomp, nexec, nsub); + } else + multiple(ncomp, nexec, nsub); + exit(0); +} + +void +regerror(s) +char *s; +{ + if (errreport) + errseen = s; + else + error(s, ""); +} + +#ifndef ERRAVAIL +error(s1, s2) +char *s1; +char *s2; +{ + fprintf(stderr, "regexp: "); + fprintf(stderr, s1, s2); + fprintf(stderr, "\n"); + exit(1); +} +#endif + +int lineno = 0; + +multiple(ncomp, nexec, nsub) +int ncomp, nexec, nsub; +{ + register int i; + extern char *strchr(); + + errreport = 1; + for (i = 0; tests[i].re != NULL; i++) { + lineno++; + try(tests[i], ncomp, nexec, nsub); + } +} + +try(fields, ncomp, nexec, nsub) +struct try fields; +int ncomp, nexec, nsub; +{ + regexp *r; + char dbuf[BUFSIZ]; + register int i; + + errseen = NULL; + r = regcomp(fields.re); + if (r == NULL) { + if (*fields.ans != 'c') + complain("regcomp failure in `%s'", fields.re); + return; + } + if (*fields.ans == 'c') { + complain("unexpected regcomp success in `%s'", fields.re); + free((char *)r); + return; + } + for (i = ncomp-1; i > 0; i--) { + free((char *)r); + r = regcomp(fields.re); + } + if (!regexec(r, fields.str)) { + if (*fields.ans != 'n') + complain("regexec failure in `%s'", ""); + free((char *)r); + return; + } + if (*fields.ans == 'n') { + complain("unexpected regexec success", ""); + free((char *)r); + return; + } + for (i = nexec-1; i > 0; i--) + (void) regexec(r, fields.str); + errseen = NULL; + for (i = nsub; i > 0; i--) + regsub(r, fields.src, dbuf); + if (errseen != NULL) { + complain("regsub complaint", ""); + free((char *)r); + return; + } + if (strcmp(dbuf, fields.dst) != 0) + complain("regsub result `%s' wrong", dbuf); + free((char *)r); +} + +complain(s1, s2) +char *s1; +char *s2; +{ + fprintf(stderr, "try: %d: ", lineno); + fprintf(stderr, s1, s2); + fprintf(stderr, " (%s)\n", (errseen != NULL) ? errseen : ""); +} diff --git a/libc-0.0.4/regexp/try.c b/libc-0.0.4/regexp/try.c new file mode 100644 index 0000000..71620c2 --- /dev/null +++ b/libc-0.0.4/regexp/try.c @@ -0,0 +1,238 @@ +/* + * Simple test program for regexp(3) stuff. Knows about debugging hooks. + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * Usage: try re [string [output [-]]] + * The re is compiled and dumped, regexeced against the string, the result + * is applied to output using regsub(). The - triggers a running narrative + * from regexec(). Dumping and narrative don't happen unless DEBUG. + * + * If there are no arguments, stdin is assumed to be a stream of lines with + * five fields: a r.e., a string to match it against, a result code, a + * source string for regsub, and the proper result. Result codes are 'c' + * for compile failure, 'y' for match success, 'n' for match failure. + * Field separator is tab. + */ +#include <stdio.h> +#include <regexp.h> + +#ifdef ERRAVAIL +char *progname; +extern char *mkprogname(); +#endif + +#ifdef DEBUG +extern int regnarrate; +#endif + +char buf[BUFSIZ]; + +int errreport = 0; /* Report errors via errseen? */ +char *errseen = NULL; /* Error message. */ +int status = 0; /* Exit status. */ + +/* ARGSUSED */ +main(argc, argv) +int argc; +char *argv[]; +{ + regexp *r; + int i; + +#ifdef ERRAVAIL + progname = mkprogname(argv[0]); +#endif + + if (argc == 1) { + multiple(); + exit(status); + } + + r = regcomp(argv[1]); + if (r == NULL) + error("regcomp failure", ""); +#ifdef DEBUG + regdump(r); + if (argc > 4) + regnarrate++; +#endif + if (argc > 2) { + i = regexec(r, argv[2]); + printf("%d", i); + for (i = 1; i < NSUBEXP; i++) + if (r->startp[i] != NULL && r->endp[i] != NULL) + printf(" \\%d", i); + printf("\n"); + } + if (argc > 3) { + regsub(r, argv[3], buf); + printf("%s\n", buf); + } + exit(status); +} + +void +regerror(s) +char *s; +{ + if (errreport) + errseen = s; + else + error(s, ""); +} + +#ifndef ERRAVAIL +error(s1, s2) +char *s1; +char *s2; +{ + fprintf(stderr, "regexp: "); + fprintf(stderr, s1, s2); + fprintf(stderr, "\n"); + exit(1); +} +#endif + +int lineno; + +regexp badregexp; /* Implicit init to 0. */ + +multiple() +{ + char rbuf[BUFSIZ]; + char *field[5]; + char *scan; + int i; + regexp *r; + extern char *strchr(); + + errreport = 1; + lineno = 0; + while (fgets(rbuf, sizeof(rbuf), stdin) != NULL) { + rbuf[strlen(rbuf)-1] = '\0'; /* Dispense with \n. */ + lineno++; + scan = rbuf; + for (i = 0; i < 5; i++) { + field[i] = scan; + if (field[i] == NULL) { + complain("bad testfile format", ""); + exit(1); + } + scan = strchr(scan, '\t'); + if (scan != NULL) + *scan++ = '\0'; + } + try(field); + } + + /* And finish up with some internal testing... */ + lineno = 9990; + errseen = NULL; + if (regcomp((char *)NULL) != NULL || errseen == NULL) + complain("regcomp(NULL) doesn't complain", ""); + lineno = 9991; + errseen = NULL; + if (regexec((regexp *)NULL, "foo") || errseen == NULL) + complain("regexec(NULL, ...) doesn't complain", ""); + lineno = 9992; + r = regcomp("foo"); + if (r == NULL) { + complain("regcomp(\"foo\") fails", ""); + return; + } + lineno = 9993; + errseen = NULL; + if (regexec(r, (char *)NULL) || errseen == NULL) + complain("regexec(..., NULL) doesn't complain", ""); + lineno = 9994; + errseen = NULL; + regsub((regexp *)NULL, "foo", rbuf); + if (errseen == NULL) + complain("regsub(NULL, ..., ...) doesn't complain", ""); + lineno = 9995; + errseen = NULL; + regsub(r, (char *)NULL, rbuf); + if (errseen == NULL) + complain("regsub(..., NULL, ...) doesn't complain", ""); + lineno = 9996; + errseen = NULL; + regsub(r, "foo", (char *)NULL); + if (errseen == NULL) + complain("regsub(..., ..., NULL) doesn't complain", ""); + lineno = 9997; + errseen = NULL; + if (regexec(&badregexp, "foo") || errseen == NULL) + complain("regexec(nonsense, ...) doesn't complain", ""); + lineno = 9998; + errseen = NULL; + regsub(&badregexp, "foo", rbuf); + if (errseen == NULL) + complain("regsub(nonsense, ..., ...) doesn't complain", ""); +} + +try(fields) +char **fields; +{ + regexp *r; + char dbuf[BUFSIZ]; + + errseen = NULL; + r = regcomp(fields[0]); + if (r == NULL) { + if (*fields[2] != 'c') + complain("regcomp failure in `%s'", fields[0]); + return; + } + if (*fields[2] == 'c') { + complain("unexpected regcomp success in `%s'", fields[0]); + free((char *)r); + return; + } + if (!regexec(r, fields[1])) { + if (*fields[2] != 'n') + complain("regexec failure in `%s'", ""); + free((char *)r); + return; + } + if (*fields[2] == 'n') { + complain("unexpected regexec success", ""); + free((char *)r); + return; + } + errseen = NULL; + regsub(r, fields[3], dbuf); + if (errseen != NULL) { + complain("regsub complaint", ""); + free((char *)r); + return; + } + if (strcmp(dbuf, fields[4]) != 0) + complain("regsub result `%s' wrong", dbuf); + free((char *)r); +} + +complain(s1, s2) +char *s1; +char *s2; +{ + fprintf(stderr, "try: %d: ", lineno); + fprintf(stderr, s1, s2); + fprintf(stderr, " (%s)\n", (errseen != NULL) ? errseen : ""); + status = 1; +} diff --git a/libc-0.0.4/stdio1/BUGS b/libc-0.0.4/stdio1/BUGS new file mode 100644 index 0000000..0e8e0db --- /dev/null +++ b/libc-0.0.4/stdio1/BUGS @@ -0,0 +1,15 @@ +Error checking is known to be wanting. However the author just wants to +get it working right now. + +fread() and fwrite() are not supported. open(), read(), write(), and close() +work very well for binary data. + +fopen() is the only way to open a file. None of the temp stuff is supported, +and frepon() is unsupported. + +GNU extensions are unsupported. + +Some printf specifications may not work. Read the code for details of what +IS supported. + +Other than that, this should be a perfectly normal stdio lib when it's finished. diff --git a/libc-0.0.4/stdio1/Config b/libc-0.0.4/stdio1/Config new file mode 100644 index 0000000..3b3b35f --- /dev/null +++ b/libc-0.0.4/stdio1/Config @@ -0,0 +1,3 @@ + + +stdio: Joel's stdio package altered by Nat diff --git a/libc-0.0.4/stdio1/NOTICE b/libc-0.0.4/stdio1/NOTICE new file mode 100644 index 0000000..25ca5b6 --- /dev/null +++ b/libc-0.0.4/stdio1/NOTICE @@ -0,0 +1,17 @@ +/* + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ diff --git a/libc-0.0.4/stdio1/README b/libc-0.0.4/stdio1/README new file mode 100644 index 0000000..5dc59aa --- /dev/null +++ b/libc-0.0.4/stdio1/README @@ -0,0 +1,13 @@ +I found that it was helpful to have the extern stuff actually defined in +one file as not external... + +Still trying to find the other problems + +Whether it is desireable to list stdio.h as a dependency is debateable + +-Joel + +I've made a horrible number of changes here, look in 'Reverse_Patch' for +how to go back ... + +-Robert diff --git a/libc-0.0.4/stdio1/TODO b/libc-0.0.4/stdio1/TODO new file mode 100644 index 0000000..481f6d9 --- /dev/null +++ b/libc-0.0.4/stdio1/TODO @@ -0,0 +1,33 @@ +Sun Jan 21 18:16:03 EST 1996 -- Nat Friedman +============================================ +I've made a load of changes to this code, but there's still a lot to be done. +- scanf, fscanf + + + + +input, file positioning, eof, declarations of functions, printf + +look for unsigned char references + +specifically +fix printf and figure out what's going on in there. +write idealgetline, scanf, other stuff +then deal with above stuff... + + +LATEST LIST: +printf, fprintf +scanf, fscanf +feof +seek support +error handling (not too hard since system calls only in a few places) +atexit stuff (close files; will need to add a linked list of files) +setvbuf if desired +check that fopen() and stdio_init() fill in ALL the fields +testing! + +rm NOTICE + + + diff --git a/libc-0.0.4/stdio1/__ffillbuf.c b/libc-0.0.4/stdio1/__ffillbuf.c new file mode 100644 index 0000000..e705cbf --- /dev/null +++ b/libc-0.0.4/stdio1/__ffillbuf.c @@ -0,0 +1,55 @@ +/* simplified linux __ffillbuf.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <unistd.h> +#include "stdio.h" + +/* this function makes the mistake of assuming the buffer really DOES +need to be filled. */ + +/* RDB: + * Added simple processing for EOF and errors + * As this is _only_ called from getc() the memory footprint is smaller + * if it pretends to be getc in the complex case. + */ + +int +__ffillbuf(stream) +FILE *stream; +{ + int stat; + + if( stream->fd < 0 || ferror(stream) ) return EOF; + + stat = read(stream->fd, (char *) stream->bufstart, stream->bufend - stream->bufstart); + if( stat > 0 ) + stream->bufread = stream->bufstart + stat; + else if( stat == 0 ) + { + stream->fc_eof = 1; + return EOF; + } + else + { + stream->fc_err = 1; + return EOF; + } + + stream->bufpos = stream->bufstart; + + return getc(stream); +} diff --git a/libc-0.0.4/stdio1/__stdio_init.c b/libc-0.0.4/stdio1/__stdio_init.c new file mode 100644 index 0000000..b49bb28 --- /dev/null +++ b/libc-0.0.4/stdio1/__stdio_init.c @@ -0,0 +1,66 @@ +/* simplified linux __stdio_init.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "stdio.h" + +/* + OK, Complete hackup here, I've removed the need for the init function. + Not also I've make the types into 'unsigned char' this is so it doesn't + return EOF when it really means '\377' + */ + +static unsigned char __stdinbuf[BUFSIZ], __stdoutbuf[BUFSIZ], __stderrbuf[80]; + +static FILE __the_stdin = { + 0, + __stdinbuf, + __stdinbuf, + __stdinbuf, + __stdinbuf+sizeof(__stdinbuf), + _IOLBF, + _MODE_READ, + 0, 0, + 0, 0, 1 +}; + +static FILE __the_stdout = { + 1, + __stdoutbuf, + __stdoutbuf, + __stdoutbuf, + __stdoutbuf+sizeof(__stdoutbuf), + _IOLBF, + _MODE_WRITE, + 0, 0, + 0, 0, 1 +}; + +static FILE __the_stderr = { + 2, + __stderrbuf, + __stderrbuf, + __stderrbuf, + __stderrbuf+sizeof(__stderrbuf), + _IOLBF, + _MODE_WRITE, + 0, 0, + 0, 0, 1 +}; + +FILE *stdin = &__the_stdin, + *stdout = &__the_stdout, + *stderr = &__the_stderr; diff --git a/libc-0.0.4/stdio1/fclose.c b/libc-0.0.4/stdio1/fclose.c new file mode 100644 index 0000000..7ec233e --- /dev/null +++ b/libc-0.0.4/stdio1/fclose.c @@ -0,0 +1,41 @@ +/* simplified linux fclose.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <unistd.h> +#include "stdio.h" + +int fclose (stream) +FILE *stream; +{ + /* only allow fclose() on what was fopen()ed. */ + /* + This isn't right, there's nothing wrong with fclosing stdin + but the next fopen/open will be given fd 0 and so become stdin + Of course you do have to be a little careful :-) + RDB + */ + + if ((stream == stdin) || (stream == stdout) || (stream == stderr)) return EOF; + + if (fflush(stream)) return EOF; + + if (close(stream->fd)) return EOF; + + free(stream->bufstart); + free(stream); + return 0; +} diff --git a/libc-0.0.4/stdio1/fcntl.h b/libc-0.0.4/stdio1/fcntl.h new file mode 100644 index 0000000..69fdb90 --- /dev/null +++ b/libc-0.0.4/stdio1/fcntl.h @@ -0,0 +1,72 @@ +#ifndef __FCNTL_H +#define __FCNTL_H + +/* + * Definitions taken from the i386 Linux kernel. + */ + +/* open/fcntl */ + +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK +#if 0 +#define O_SYNC 010000 /* Not supported */ +#define FASYNC 020000 /* Not supported */ +#endif + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get f_flags */ +#define F_SETFD 2 /* set f_flags */ +#define F_GETFL 3 /* more flags (cloexec) */ +#define F_SETFL 4 +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +/* for old implementation of bsd flock () */ +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#ifdef __KERNEL__ +#define F_POSIX 1 +#define F_FLOCK 2 +#endif /* __KERNEL__ */ + +#if 0 +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; +#endif + +#endif diff --git a/libc-0.0.4/stdio1/fflush.c b/libc-0.0.4/stdio1/fflush.c new file mode 100644 index 0000000..c9cdac7 --- /dev/null +++ b/libc-0.0.4/stdio1/fflush.c @@ -0,0 +1,36 @@ +/* simplified linux fflush.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <unistd.h> +#include "stdio.h" + +int fflush(stream) +FILE *stream; +{ + if (stream == 0) return 0; + if ((stream->file_mode == _MODE_WRITE) + ||(stream->file_mode == (_MODE_WRITE & _MODE_RDWR))){ + write(stream->fd, (char *) stream->bufstart, + stream->bufpos - stream->bufstart); + stream->bufpos = stream->bufstart; + } + return 0; +} +/* TODO: return EOF or 0; support NULL stream */ +/* The only place an error can come from is the write; you're not checking RDB + */ diff --git a/libc-0.0.4/stdio1/fgetc.c b/libc-0.0.4/stdio1/fgetc.c new file mode 100644 index 0000000..2c41062 --- /dev/null +++ b/libc-0.0.4/stdio1/fgetc.c @@ -0,0 +1,39 @@ +/* + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "stdio.h" + +/* + * Make this not dependent on getc() then we can: + #define getc(fp) fgetc(fp) + * if memory is _really_ tight. + */ + +int fgetc(stream) +FILE *stream; +{ + if( stream->ungetted ) + { + stream->ungetted = 0; + return stream->ungetchar; + } + if( stream->bufpos == stream->bufread ) + return __ffillbuf(stream); + else + return *stream->bufpos++; +} diff --git a/libc-0.0.4/stdio1/fgets.c b/libc-0.0.4/stdio1/fgets.c new file mode 100644 index 0000000..c085970 --- /dev/null +++ b/libc-0.0.4/stdio1/fgets.c @@ -0,0 +1,50 @@ +/* fgets.c for limited linux stdio + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "stdio.h" + +/* + RDB BZZZT! This should only read upto and including any newline! +*/ + +char *fgets(s, count, f) +char *s; +size_t count; +FILE *f; +{ + char *ret; + register size_t i; + register int ch; + + ret = s; + for(i=count; i>0; i--) + { + ch = getc(f); + if( ch == EOF ) + { + if(s==ret) return 0; + break; + } + *s++ = (char) ch; + if( ch == '\n' ) break; + } + *s = 0; + + if( ferror(f) ) return 0; + return ret; +} diff --git a/libc-0.0.4/stdio1/fopen.c b/libc-0.0.4/stdio1/fopen.c new file mode 100644 index 0000000..1265ff5 --- /dev/null +++ b/libc-0.0.4/stdio1/fopen.c @@ -0,0 +1,80 @@ +/* simplified linux fopen.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "stdio.h" +#include <malloc.h> + +FILE * fopen(name, openmode) +char *name; +char *openmode; +{ + FILE *new; + int openplus=0; + char basemode; + + basemode = openmode[0]; + while (openmode[0] != 0){ + switch(openmode[0]){ + case '+': openplus=1; break; + } + openmode++; + } + + new = malloc(sizeof(new)); + if( new == 0 ) return 0; + new->bufread = new->bufpos = new->bufstart = malloc(BUFSIZ); + if( new->bufstart == 0 ) { free(new) ; return 0; } + + new->bufend = new->bufstart + BUFSIZ; + new->buffer_mode = _IOFBF; + new->iotrans = 0; + new->fd = -1; + if (openplus){ + new->file_mode = _MODE_RDWR; + switch (basemode){ + case 'a': + new->fd = open(name, O_RDWR | O_APPEND | O_CREAT); + break; + case 'r': + new->fd = open(name, O_RDWR); + break; + case 'w': + new->fd = open(name, O_RDWR | O_TRUNC | O_CREAT); + break; + } + } else switch (basemode){ + case 'a': + new->fd = open(name, O_WRONLY | O_APPEND | O_CREAT); + new->file_mode = _MODE_WRITE; + break; + case 'r': + new->fd = open(name, O_RDONLY); + new->file_mode = _MODE_READ; + break; + case 'w': + new->fd = open(name, O_WRONLY | O_TRUNC | O_CREAT); + new->file_mode = _MODE_WRITE; + break; + } + if( new->fd < 0 ) + { + free(new->bufstart); + free(new); + return 0; + } + return new; +} diff --git a/libc-0.0.4/stdio1/fputc.c b/libc-0.0.4/stdio1/fputc.c new file mode 100644 index 0000000..939a721 --- /dev/null +++ b/libc-0.0.4/stdio1/fputc.c @@ -0,0 +1,53 @@ +/* simplified linux fputc.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "stdio.h" + +/* + * Make this not dependent on putc() then we can: + #define putc(c, fp) fputc(c, fp) + * if memory is _really_ tight. + */ + +#undef putc +#define putc(c, stream) \ + (((stream)->bufpos[0] = (c)), \ + ((stream)->bufpos++), \ + ((((stream)->bufpos == (stream)->bufend) \ + ||((stream)->buffer_mode == _IONBF) \ + ||(((stream)->buffer_mode == _IOLBF) \ + && ((stream)->bufpos != (stream)->bufstart) \ + && ((stream)->bufpos[-1] == '\n'))) \ + ? fflush(stream):0)) + +#define new_putc(c, stream) \ + ((unsigned char)( \ + ((stream)->bufpos>=(stream)->bufread) ? fputc((c), (stream)) \ + : *(stream)->bufpos++ = (c) \ + )) + +int +fputc(int c, FILE * stream) +{ +#ifdef __MSDOS__ + if( c == '\n' && stream->iotrans ) fputc('\r', stream); +#endif + return putc(c, stream); +} + + + diff --git a/libc-0.0.4/stdio1/fputs.c b/libc-0.0.4/stdio1/fputs.c new file mode 100644 index 0000000..41e2998 --- /dev/null +++ b/libc-0.0.4/stdio1/fputs.c @@ -0,0 +1,32 @@ +/* simplified linux fputs.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <unistd.h> +#include <string.h> +#include "stdio.h" + +int +fputs(__const char * string, FILE * stream) +{ + if (stream->buffer_mode != _IONBF){ + while (string[0] != 0){ + putc(string[0], stream); + string++; + } + } else write(stream->fd, string, strlen(string)); + return 0; +} diff --git a/libc-0.0.4/stdio1/idealgetline.c b/libc-0.0.4/stdio1/idealgetline.c new file mode 100644 index 0000000..7eacc9e --- /dev/null +++ b/libc-0.0.4/stdio1/idealgetline.c @@ -0,0 +1,67 @@ +/* idealgetline.c -- my idea of an ideal getline function for stdio + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* I actually intend to use this in 32 bit programs, unlike the other stuff + in this lib. IMHO GNU getline is broken. It is too hard to use. + + Just pass this function a FILE * and it will retrieve a line for you using + getc(). It will realloc() exactly the amount of memory needed, and will + generate error messages for non-ascii characters on stderr. + + This may not be your ideal. It probably generates far too many errors. + It doesn't work well for those who don't use English (but since + Linux-less-than-32 libc and kernels are each being produced by one + person in the US and one in the UK, this isn't a problem). It probably + is not what you (or I) want for interactive input. + + You're welcome to modify this routine to meet your needs. However, if + you change the semantics significantly, please change the name. + + (Maybe I should have put my own name on it so there will be no confusion + about who thought it was ideal). */ + +#include <stdio.h> +#include <malloc.h> + +char *idealgetline(f) +FILE *f; +{ + char c; + char *ret; + int size = 0, bufsize = 256; + + ret = malloc(256); + c = getc(f); + while ((c != EOF) && (c != '\n')){ + if ((c >= ' ') && (c <= 126)){ + ret[size] = c; + size++; + if (size == bufsize){ + bufsize += 256; + ret = realloc(ret, bufsize); + } + } else { + fprintf(stderr, "Unexpected character 0x%x encountered in input", c); + free(ret); + return 0; + } + } + ret[size] = '\0'; + size++; + return realloc(ret, size); +} diff --git a/bin86-0.3/bccfp/bccfp.tex b/libc-0.0.4/stdio1/libc.a index e69de29..e69de29 100644 --- a/bin86-0.3/bccfp/bccfp.tex +++ b/libc-0.0.4/stdio1/libc.a diff --git a/libc-0.0.4/stdio1/makefile b/libc-0.0.4/stdio1/makefile new file mode 100644 index 0000000..0723b97 --- /dev/null +++ b/libc-0.0.4/stdio1/makefile @@ -0,0 +1,36 @@ +TOP=.. +include $(TOP)/Make.defs +OBJ = __ffillbuf.o __stdio_init.o fflush.o fgetc.o fgets.o \ + fputc.o fputs.o puts.o printf.o fopen.o fclose.o scanf.o + +#missing functions from above: printf etc, scanf etc, idealgetline +#seek + +#fopen.c, fclose.c removed because of malloc() use + +CFLAGS+=$(WALL) + +ifeq ($(PLATFORM),i86-ELKS) +CFLAGS=$(CCFLAGS) $(DEFS) -ansi +endif + +all: $(OBJ) + +libc.a: $(OBJ) + ar r ../libc.a $(OBJ) + @touch libc.a + +$(OBJ): stdio.h + +test: test.o $(OBJ) + $(CC) -o test test.o $(OBJ) + +%.o: %.c + $(CC) $(CFLAGS) -o $@ $< -c + +clean: + rm -f *.o test + +transfer: + -@rm -f ../include/stdio.h + cp -p stdio.h ../include/. diff --git a/libc-0.0.4/stdio1/old_printf.c b/libc-0.0.4/stdio1/old_printf.c new file mode 100644 index 0000000..81d62ac --- /dev/null +++ b/libc-0.0.4/stdio1/old_printf.c @@ -0,0 +1,230 @@ +/* fprintf.c for limited Linux libc + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* Thanks Alan for writing the hard routine for me :-) + * Alan said that this works "most of the time". Something tells me I'm making + * it even worse! */ +/* The basic idea here is to make fprintf the core routine. printf obviously + can just call fprintf with stdout followed by all of its arguments. + sprintf() works using the fake file &the_sprintf. It's marked as fully + buffered, so that it will only write(2) when &the_sprintf->bufpos == + &the_sprintf->bufend, which I doubt will happen since &the_sprintf->bufend + = 0. The trick is that sprintf must set &the_sprintf->bufstart = + &the_sprintf->bufpos = its first argument. Not as orthagonal (is that + the right word?) as glibc's facilities for non-files, but this isn't a + library for people who have unlimited RAM budgets. (not like the libc + I use on linux/i586 enjoys an unlimited RAM budget either; I only have + 8 MB + + I'm not sure what the "correct" way to pass the variable arguments + from one function to the next is. Rather than pass the arguments + themselves, I'm passing a pointer to them. However, the following + explaination from Alan is probably a polite way of saying it will not + work on a 386 anyway. + Joel Weber + + [ I've migrated all of this code over to the ELKS stdarg that I wrote. + The accepted way to do it is for the wrapper function to accept a + variable number of arguments, use stdarg to make an argument pointer, + and then pass the argument pointer on to the core function, as I've + done here. This should definitely work on a 386, as the arguments + are still passed in the stack, and stack order is maintained. -Nat ] + */ + +/* + * This is NOT stunningly portable, but works + * for pretty dumb non ANSI compilers and is + * tight. Adjust the sizes to taste. + * + * Illegal format strings will break it. Only the + * following simple subset is supported + * + * %x - hex + * %d - decimal + * %s - string + * %c - char + * + * And the h/l length specifiers for %d/%x + * + * Alan Cox. + */ + +#include <stdarg.h> +#include "stdio.h" + +/* 17 to make sure that there's room for the trailing newline. + I'm not really sure if this is ideal... */ +static char nstring[17]="0123456789ABCDEF"; + +static unsigned char * +__numout(long i, int base) +{ + static unsigned char out[16]; + int n; + int flg = 0; + unsigned long val; + + if (i<0 && base==10) + { + flg = 1; + i = -i; + } + val = i; + + for (n = 0; n < 15; n++) + out[n] = ' '; + out[15] = '\0'; + n = 14; + do{ + out[n] = nstring[val % base]; + n--; + val /= base; + } + while(val); + if(flg) out[n--] = '-'; + return &out[n+1]; +} + +static int +internal_fprintf(FILE * stream, __const char * fmt, va_list ap) +{ + register int c; + int count = 0; + int type, base; + + while(c=*fmt++) + { + if(c!='%') + { + putc(c, stream); + count++; + } + else + { + type=1; + do { c=*fmt++; } while( c=='.' || (c>='0' && c<='9')); + if( c == 0 ) break; + if(c=='h') + { + c=*fmt++; + type = 0; + } + else if(c=='l') + { + c=*fmt++; + type = 2; + } + + switch(c) + { + case 'x': + case 'o': + case 'd': + if (c=='x') base=16; + if (c=='o') base=8; + if (c=='d') base=10; + { + long val=0; + switch(type) + { + case 0: + val=va_arg(ap, short); + break; + case 1: + val=va_arg(ap, int); + break; + case 2: + val=va_arg(ap, long); + break; + } + fputs((__const char *)__numout(val,base),stream); + } + break; + case 's': + { + char *cp; + cp=va_arg(ap, char *); + while(*cp) + putc(*cp++, stream); + break; + } + case 'c': + putc(va_arg(ap, int), stream); + break; + default: + putc(c, stream); + } + } + } + return count; +} + + +int +fprintf(FILE * stream, __const char * fmt, ...) +{ + va_list ap; + int retval; + va_start(ap, fmt); + retval=internal_fprintf(stream, fmt, ap); + va_end(ap); + return(retval); +} + +int +printf(__const char * fmt, ...) +{ + va_list ap; + int retval; + va_start(ap, fmt); + retval=internal_fprintf(stdout, fmt, ap); + va_end(ap); + return(retval); +} + +/* This is a strange way of doing sprintf, but it should work */ +int sprintf(char * s, __const char * fmt, ...) +{ + static FILE the_sprintf = { + -1, + 0, + 0, + 0, + 0, + _IOFBF, + _MODE_WRITE, + 0, 0, + 0, 0}; + va_list ap; + int retval; + + va_start(ap, fmt); + the_sprintf.bufstart = the_sprintf.bufpos = (unsigned char *) s; + the_sprintf.fc_err = 0; + + retval = internal_fprintf(&the_sprintf, fmt, ap); + /* null-terminate the string */ + putc('\0', &the_sprintf); + + va_end(ap); + return retval; +} + + + + + diff --git a/libc-0.0.4/stdio1/printf.c b/libc-0.0.4/stdio1/printf.c new file mode 100644 index 0000000..f2a39bd --- /dev/null +++ b/libc-0.0.4/stdio1/printf.c @@ -0,0 +1,649 @@ +/* fprintf.c for limited Linux libc + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* Thanks Alan for writing the hard routine for me :-) + * Alan said that this works "most of the time". Something tells me I'm making + * it even worse! */ +/* The basic idea here is to make fprintf the core routine. printf obviously + can just call fprintf with stdout followed by all of its arguments. + sprintf() works using the fake file &the_sprintf. It's marked as fully + buffered, so that it will only write(2) when &the_sprintf->bufpos == + &the_sprintf->bufend, which I doubt will happen since &the_sprintf->bufend + = 0. The trick is that sprintf must set &the_sprintf->bufstart = + &the_sprintf->bufpos = its first argument. Not as orthagonal (is that + the right word?) as glibc's facilities for non-files, but this isn't a + library for people who have unlimited RAM budgets. (not like the libc + I use on linux/i586 enjoys an unlimited RAM budget either; I only have + 8 MB + + I'm not sure what the "correct" way to pass the variable arguments + from one function to the next is. Rather than pass the arguments + themselves, I'm passing a pointer to them. However, the following + explaination from Alan is probably a polite way of saying it will not + work on a 386 anyway. + Joel Weber + + [ I've migrated all of this code over to the ELKS stdarg that I wrote. + The accepted way to do it is for the wrapper function to accept a + variable number of arguments, use stdarg to make an argument pointer, + and then pass the argument pointer on to the core function, as I've + done here. This should definitely work on a 386, as the arguments + are still passed in the stack, and stack order is maintained. -Nat ] + */ + +/* + * This is NOT stunningly portable, but works + * for pretty dumb non ANSI compilers and is + * tight. Adjust the sizes to taste. + * + * Illegal format strings will break it. Only the + * following simple subset is supported + * + * %x - hex + * %d - decimal + * %s - string + * %c - char + * + * And the h/l length specifiers for %d/%x + * + * Alan Cox. + */ + +#include <stdarg.h> +#include "stdio.h" + +/* 17 to make sure that there's room for the trailing newline. + I'm not really sure if this is ideal... */ +static char nstring[17]="0123456789ABCDEF"; + +static unsigned char * +__numout(long i, int base) +{ + static unsigned char out[16]; + int n; + int flg = 0; + unsigned long val; + + if (i<0 && base==10) + { + flg = 1; + i = -i; + } + val = i; + + for (n = 0; n < 15; n++) + out[n] = ' '; + out[15] = '\0'; + n = 14; + do{ + out[n] = nstring[val % base]; + n--; + val /= base; + } + while(val); + if(flg) out[n--] = '-'; + return &out[n+1]; +} + +int +fprintf(FILE * stream, __const char * fmt, ...) +{ + va_list ap; + int retval; + va_start(ap, fmt); + retval=internal_fprintf(stream, fmt, ap); + va_end(ap); + return(retval); +} + +int +printf(__const char * fmt, ...) +{ + va_list ap; + int retval; + va_start(ap, fmt); + retval=internal_fprintf(stdout, fmt, ap); + va_end(ap); + return(retval); +} + +/* This is a strange way of doing sprintf, but it should work */ +int sprintf(char * s, __const char * fmt, ...) +{ + static FILE the_sprintf = { + -1, + 0, + 0, + 0, + 0, + _IOFBF, + _MODE_WRITE, + 0, 0, + 0, 0}; + va_list ap; + int retval; + + va_start(ap, fmt); + the_sprintf.bufstart = the_sprintf.bufpos = (unsigned char *) s; + the_sprintf.fc_err = 0; + + retval = internal_fprintf(&the_sprintf, fmt, ap); + /* null-terminate the string */ + putc('\0', &the_sprintf); + + va_end(ap); + return retval; +} + + + + + +/* + * printf.c - This is the more complete fprintf() replacement for libc8086 + * Copyright (C) 1996 Steven Huang <sthuang@hns.com>. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +/* + * This decides if the little test main program gets included + */ +#undef TEST +/* + * This decides if printf() should act like standard. When undefined, + * - prints out "(err)" if a bad format is encountered + * - supports the %b (binary) format + */ +#define STANDARD + +/* + * Shut bcc up about 'const', which doesn't seem to be handled right + * by unproto. + */ +#ifdef __BCC__ +#define const +#endif + +#define BUF_SIZE 128 +#define OUTC(c) { putc(c, stream); n++; } +#define max(a, b) ((a > b) ? a : b) +/* + * if you change the ff, you need to change the order of characters in + * the string 'flagstr' defined in _printf() + */ +#define FLAG_PADZERO (1<<0) +#define FLAG_LEFTJUST (1<<1) +#define FLAG_SIGNED (1<<2) +#define FLAG_ALT (1<<3) +#define FLAG_SPACE (1<<4) + +static char *utoa(unsigned int val, char *buf, int radix) +/* + * Converts an integer to a variable-radix string representation + * + * Note: + * Does not perform sanity checking for 'radix' + * Assumes 'buf' has memory allocated to it + */ +{ + int divisor; + char *p = buf; + const char *digitstr = "0123456789abcdef"; + + for (divisor = 1; val / divisor >= radix; divisor *= radix); + do { + *p++ = digitstr[val / divisor]; + val %= divisor; + divisor /= radix; + } while (divisor >= 1); + *p = '\0'; + return(buf); +} + +static +internal_fprintf(FILE * stream, const char * fmt, char *args) + +/* static int _printf(FILE *stream, const char *fmt, char *args) */ +/* + * The one that does all the work. + * This is a fairly complete implementation of printf(), supporting + * everything EXCEPT: + * - floating point (eEDOUfg formats) + * - pointers (realizes them but doesn't understand how to print them) + * - short and long (h/l) modifiers (dunno what to do about them) + * It's even slightly faster than gcc's printf() on Linux. Can't beat + * HP-UX's printf() though ;) + * + * Supports: + * d, signed integer + * i + * o unsigned octal integer + * u unsigned integer + * x unsigned hex lowercase a-f + * X unsigned hex uppercase A-F + * c character + * s string (character pointer) + * p void pointer (ignores it) + * % % character + * n number of characters output so far + * + * Special feature: (no really, it's not a bug =) ) + * b prints an integer in binary form (i think this might come + * in handy *somewhere*) + * + * # alternate format for octal (leading 0) and hex (0x/0X) + * 0 leading zeroes for d, i, o, u, x, and X + * - left justify, overrides '0' + * ' ' (space) force a blank in front of positive numbers + * + force a sign in front of any number + * + * width.precision, including support for '*' (reads value from + * the parameter list (MUST BE INT)) + * + * h, short/long modifiers, recognized but ignored. + * l + * + * Warning: + * The way varargs is implemented in libc is evil. Don't think + * there's a better way, but misaligned or wrong parameters + * passed to printf() can break a lot of things. I've tried my + * best to handle errors in the format string, though. + * + * Each %something field cannot exceed 'BUF_SIZE' characters, + * which I set to 128 right now. %s fields are not subject to + * this limit. + * + * Note: + * The semicolon -looks- missing in a few places but that's + * because of the macro def of 'OUTC'. did it that way to + * save a few lines of source ;) + * + * Expects a 'char *' as varargs parameter, unlike libc8086's + * printf(), which takes a 'int *' then casts it to a 'char *'. + * Either has to change, but it should be trivial. + * + * This function aborts whenever it scans an illegal format, unlike + * gcc's libc which prints out the illegal format as if it's -not- + * a format string. The 'STANDARD' preprocessor flag controls if + * if just aborts (when defined) or prints out "(err)" (when undefined). + */ +{ + /* + * the "0-+# " and "dcs..." strings are listed in my idea of their + * frequency of use, with the most popular in front. not terribly + * important but strchr() might have an easier time that way. + * if you change the ordering of 'flagstr', make sure you update + * the #define FLAG_* stuff on top of this file too. + */ + char c, *s, *f; + const char *flagstr = "0-+# ", +#ifdef STANDARD + *typestr = "dcsixXuop"; +#else + *typestr = "dcsixXuopb"; +#endif + int n = 0, flags, width, actwidth, prec, bad = 0, neg, i; + static char buf[BUF_SIZE]; + + for (c = *fmt++; c && !bad;) { + if (c != '%') { /* just copy */ + OUTC(c); + c = *fmt++; + } + else { + c = *fmt++; /* chew the % sign */ + flags = width = prec = 0; + /* + * Parse the "0-+# " flags + */ + while ((f = strchr(flagstr, c)) != NULL) { + flags |= 1 << (f - flagstr); + c = *fmt++; + } + /* + * The '*' parameter says fetch width value from varargs + */ + if (c == '*') { + width = *(int *) args; + args += sizeof(int); + if (width < 0) { + width = abs(width); + flags |= FLAG_LEFTJUST; /* set '-' flag */ + } + c = *fmt++; + } + else + /* + * scan and convert the width parameter + */ + if (isdigit(c)) + while (isdigit(c)) { + width *= 10; + width += c - '0'; + c = *fmt++; + } + /* + * a '.' means there may be a precision parameter + */ + if (c == '.') { + c = *fmt++; + /* + * fetch precision value from varargs + */ + if (c == '*') { + prec = *(int *) args; + if (prec < 0) + prec = 0; + args += sizeof(int); + c = *fmt++; + } + else + /* + * scan and convert precision field + */ + if (isdigit(c)) + while (isdigit(c)) { + prec *= 10; + prec += c - '0'; + c = *fmt++; + } + } + /* + * short and long modifiers. ignored for the moment + */ + if (c == 'h') { + c = *fmt++; + } + else + if (c == 'l') { + c = *fmt++; + } + /* + * check if it's a valid type "dioux..." + */ + if (strchr(typestr, c) != NULL) { + neg = 0; + switch (c) { + case 'd': + case 'i': { + int val = *(int *) args; + args += sizeof(int); + neg = (val < 0); + val = abs(val); + actwidth = strlen(utoa(val, buf, 10)); } + /* + * if negative or '+'/' ' flags set + */ + if (neg || (flags & FLAG_SIGNED) || (flags & FLAG_SPACE)) + actwidth++; + break; + case 'u': { + unsigned int uval = *(unsigned int *) args; + args += sizeof(unsigned int); + actwidth = strlen(utoa(uval, buf, 10)); } + /* + * if '+'/' ' flags set + */ + if ((flags & FLAG_SIGNED) || (flags & FLAG_SPACE)) + actwidth++; + break; + case 'x': + case 'X': { + int val = *(int *) args; + args += sizeof(int); + actwidth = strlen(utoa(val, buf, 16)); } + if (flags & FLAG_ALT) + actwidth += 2; + break; + case 'o': { + int val = *(int *) args; + args += sizeof(int); + actwidth = strlen(utoa(val, buf, 8)); } + if (flags & FLAG_ALT) + actwidth++; + break; + case 's': + s = *(char **) args; + args += sizeof(char *); + actwidth = strlen(s); + break; + case 'c': + buf[0] = *(char *) args; + buf[1] = '\0'; + args += sizeof(char); + actwidth = 1; + break; + /* + * dunno how to handle pointers - what's the format of + * linux86 pointers?! right now just prints "(ptr)" + */ + case 'p': + strcpy(buf, "(ptr)"); + args += sizeof(void *); + actwidth = strlen(buf); + s = buf; /* pretend we're a string */ + c = 's'; + break; +#ifndef STANDARD + case 'b': { + int val = *(int *) args; + args += sizeof(int); + actwidth = strlen(utoa(val, buf, 2)); } + break; +#endif + } + /* + * strings behave differently to the width.precision + * parameters, so handle separately. besides, we avoid + * an extra 'memcpy' to 'buf' + */ + if (c == 's') { + if (prec == 0) + prec = actwidth; + width = max(width, prec); + /* + * pad to the left if not left justified + */ + if (!(flags & FLAG_LEFTJUST)) { + for (i = width; i > prec; i--) + OUTC(' '); + } + /* + * print out entire string if no precision specified, otherwise + * that's our upper limit + */ + if (prec == 0) + for (; *s; s++) + OUTC(*s) /* no semicolon here */ + else + for (i = 0; i < prec; i++) + OUTC(s[i]); + } + else { + /* + * precision is as wide as width if it's not specified and + * the leading zero '0' flag is set, and left-justify is + * -not- set. c standard says left justify overrides the + * leading 0. + */ + if (prec == 0 && (flags & FLAG_PADZERO) && !(flags & FLAG_LEFTJUST)) + prec = width; + /* + * expand width.precision to fit the actual width. printf + * width specifies the -minimum-, and aside from the + * precision of %s fields, there's no way to specify maximum + */ + prec = max(prec, actwidth); + width = max(width, prec); + /* + * pad to the left if we're not left justified + */ + if (!(flags & FLAG_LEFTJUST)) { + for (i = width; i > prec; i--) + OUTC(' '); + } + /* + * check if we might need to print the sign + */ + if (strchr("diu", c) != NULL) { + if (neg) /* print if negative */ + OUTC('-') /* yes, no ';' here =) */ + else + if (flags & FLAG_SIGNED) /* or '+' specified */ + OUTC('+') /* nor here */ + else + if (flags & FLAG_SPACE) /* or ' ' specified */ + OUTC(' ') /* nor here */ + } + /* + * the alternate '#' flag is set. doesn't affect all though + */ + if (flags & FLAG_ALT) { + switch (c) { + case 'o': + OUTC('0'); /* leading zero for octals */ + break; + case 'x': + case 'X': /* prints 0x or 0X */ + OUTC('0'); + OUTC(c); + break; + } + } + /* + * fill the precision field with either spaces or zeroes, + * depending if we're printing numbers + */ + if (strchr("diuxXo", c) != NULL) + for (i = prec; i > actwidth; i--) + OUTC('0') + else + for (i = prec; i > actwidth; i--) + OUTC(' '); + /* + * print the field, except for 'X', which we convert to caps + */ + if (c != 'X') + for (f = buf; *f; f++) + OUTC(*f) /* none here either */ + else + for (f = buf; *f; f++) + OUTC(toupper(*f)); + } + /* + * if we're left justified, we now need to pad spaces to the + * right so that width will be correct + */ + if (flags & FLAG_LEFTJUST) + for (i = width; i > prec; i--) + OUTC(' '); + } + else { + /* + * miscellaneous %thingies + */ + switch (c) { + case '%': /* %% -> % */ + OUTC('%'); + break; + case 'n': /* %n writes current output count */ + *(*(int **) args) = n; + args += sizeof(int *); + break; + default: /* oops, got a bad %thingy */ + bad = 1; + } + } + c = *fmt++; + } + } +#ifndef STANDARD + /* + * dunno what the standard wants if the format string is badly + * formed, so i print (err) if the debug flag is set + */ + if (bad) { + OUTC('('); + OUTC('e'); + OUTC('r'); + OUTC('r'); + OUTC(')'); + } +#endif + return(n); +} + +#ifdef TEST + +#include <time.h> + +int main() +{ + static unsigned char xbuf[128], *x; + char *fmt = "%s, %s %d, %.*d:%.*d\n"; + int rv1, rv2, i, dt1, dt2; + clock_t t1, t2; + + x = xbuf; + *(char **) x = "Sun"; + x += sizeof(char *); + *(char **) x = "Feb"; + x += sizeof(char *); + *(int *) x = 18; + x += sizeof(int); + *(int *) x = 2; + x += sizeof(int); + *(int *) x = 10; + x += sizeof(int); + *(int *) x = 2; + x += sizeof(int); + *(int *) x = 56; + x += sizeof(int); + t1 = clock(); + for (i = 0; i < 1000; i++) + rv1 = _printf(stdout, fmt, xbuf); + t2 = clock(); + dt1 = t2 - t1; + + t1 = clock(); + for (i = 0; i < 1000; i++) + rv2 = printf(fmt, "Sun", "Feb", 18, 2, 10, 2, 56); + t2 = clock(); + dt2 = t2 - t1; + + printf("\nrv1: %d, rv2: %d, dt1: %d, dt2: %d\n", rv1, rv2, dt1, dt2); + return(0); +} + +#endif diff --git a/libc-0.0.4/stdio1/puts.c b/libc-0.0.4/stdio1/puts.c new file mode 100644 index 0000000..d9bb8d0 --- /dev/null +++ b/libc-0.0.4/stdio1/puts.c @@ -0,0 +1,26 @@ +/* simplified linux puts.c + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include "stdio.h" + +int puts (string) +char *string; +{ + fputs(string, stdout); + putc('\n', stdout); + return 0; +} diff --git a/libc-0.0.4/stdio1/scanf.c b/libc-0.0.4/stdio1/scanf.c new file mode 100644 index 0000000..81900a1 --- /dev/null +++ b/libc-0.0.4/stdio1/scanf.c @@ -0,0 +1,151 @@ +/* scanf.c for limited Linux libc + Copyright (C) 1996 Joel N. Weber II <nemo@koa.iolani.honolulu.hi.us> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* This scanf code was derived from my printf code, which in turn was + * derived from Alan Cox's printk. It was tested by [no one so far...] + */ + +/* Disclaimer: I haven't even THOUGHT about testing this. If you do decide + * to be brave and test it, and it doesn't work, you have the following + * options: + * o Send me mail telling me it doesn't work, which I will ignore + * since I already knew that. + * o Fix it yourself + * o isolate the problem and send it to the list, and maybe + * I'll fix it + */ + +/* BTW, the above comment may be destroyed once this has been tested. It's + * not nessisary for my great great grandchildren to see it when they + * take Ancient Linux History... + */ + +/* Incidentally, if it doesn't work, it may well be because I never bothered + * to learn how to use scanf()...I briefly tried it for the usaco qualification + * round, but had some wierd problems...ask me after mid February...BTW the + * problems had nothing to do with scanf(); it was still broken (hopelessly) + * when I went to getchar(). + */ + +/* Note, too that the current version probably assumes some things with + * variable argument handling that it shouldn't. Don't expect this to + * work on a 386 in 32 bit mode, don't expect this to work on a Z80, + * or anything other than an 8086. In fact, don't expect it to even + * work on an 8086 ;-) + */ + +/* One of these days the headers will work painlessly... */ +/* #include <linuxmt/types.h> */ +/* #include <linuxmt/fcntl.h> */ +#include "stdio.h" + +/* note that we assume base == 10... */ +static int numin(int *num, int base, FILE *stream, int c) +{ + if ((c < '0') || (c > '9')) return 0; + *num = 0; + while ((c >= '0') && (c <= '9')) { + *num = *num * base + c - '0'; + c = getc(stream); + } + ungetc(c, stream); +} + +/* currently, the h/l specifications are ignored */ +static int internal_scanf(stream,fmt,a1) +FILE *stream; +char *fmt; +int *a1; +{ + unsigned char *p=(char *)a1; + char c; + int inc; + int count = 0; + + while(c=*fmt++) + { + do { + inc = getc(stream); + } while ((inc == ' ') || (inc == '\t') || (inc == '\n')); + + if ((c == '\n') || (c == '\t') || (c == ' ')) + ; + else if (c!='%') { + if (c != inc) { + ungetc(inc, stream); + return count; + } + } else { + int len=2; + c=*fmt++; + if(c=='h') c=*fmt++; + else if(c=='l') c=*fmt++; + + switch(c) + { + case 'x': + if (numin(p, 16, stream, inc)) count++; + else return count; + p+=2; + break; + case 'd': + if (numin(p, 10, stream, inc)) count++; + else return count; + p+=2; + break; + case 's': + { + char *cp=*((char **)p); + p+=sizeof(char *); + while(*cp) + putc(cp++, stream); + while ((inc != ' ') && (inc != '\t') + && (inc != '\n') && (inc != EOF)) { + *cp++ = inc; + inc = getc(stream); + } + ungetc(inc, stream); + break; + } + case 'c': + *p++ = inc; + p++; + break; + default: + putc('?', stream); + } + } + } + return count; +} + + +int fscanf(stream,fmt,a1) +FILE *stream; +char *fmt; +int a1; +{ + return internal_fscanf(stream,fmt,&a1); +} + +int scanf(fmt,a1) +char *fmt; +int a1; +{ + return internal_fscanf(stdout,fmt,&a1); +} diff --git a/libc-0.0.4/stdio1/stdio.h b/libc-0.0.4/stdio1/stdio.h new file mode 100644 index 0000000..4bd1989 --- /dev/null +++ b/libc-0.0.4/stdio1/stdio.h @@ -0,0 +1,135 @@ +/* simplified linux stdio.h + Copyright (C) 1995 Joel N. Weber II + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <fcntl.h> +#include <sys/types.h> +#include <malloc.h> + +#ifndef __STDIO_H +#define __STDIO_H + +/* when you add or change fields here, be sure to change the initialization + * in stdio_init and fopen */ +struct __stdio_file { + int fd; /* the file descriptor associated with the stream */ + unsigned char *bufstart; /* the start of the buffer */ + unsigned char *bufpos; /* the next byte to write to or read from */ + unsigned char *bufread; /* the end of data returned by last read() */ + unsigned char *bufend; /* the end of the buffer; ie the byte after the last + malloc()ed byte */ + int buffer_mode; +#define _IONBF 0xB111 /* no buffering */ +#define _IOLBF 0xB112 /* line buffering */ +#define _IOFBF 0xB113 /* full buffering */ + int file_mode; +#define _MODE_READ 0xB121 +#define _MODE_WRITE 0xB122 +#define _MODE_RDWR 0xB124 /* used when a file is readwrite and is ord with + what's in the buffer now */ + unsigned char ungetted, ungetchar; + /* ungetted = 1 if there's data unread; else 0 + ungetchar contains the character */ + int fc_eof:1; + int fc_err:1; /* eof and error conditions */ + int iotrans:1; /* Translate \n -> \r\n on MSDOS */ +}; + +#define EOF (-1) + +typedef struct __stdio_file FILE; + +#define BUFSIZ 256 + +extern FILE *stdin, *stdout, *stderr, *__stdsprintf; + +/* The following macros are used for all access to the buffers. If you + * know the file is unbuffered, however, you may write to it directly, as + * fputs.c does. However, be aware that sprintf assumes that by setting + * bufend to 0, no file writing will occur. Also, since NO streams use + * unbuffered mode by default and the function to change this behavior is + * not implemented yet, I'm considering disallowing raw access at the cost + * of having each byte of a string written individually. However, that + * IS what you're asking for with non-buffered mode. + * + * RDB: It's considered very bad form to use the raw read() & write() + * calls on the same files you use the stdio functions. + */ +#ifdef __MSDOS__ +#define putc(c, fp) fputc(c, fp) +#define getc(fp) fgetc(fp) +#else +#define putc(c, stream) \ + (((stream)->bufpos[0] = (c)), \ + ((stream)->bufpos++), \ + ((((stream)->bufpos == (stream)->bufend) \ + ||((stream)->buffer_mode == _IONBF) \ + ||(((stream)->buffer_mode == _IOLBF) \ + && ((stream)->bufpos != (stream)->bufstart) \ + && ((stream)->bufpos[-1] == '\n'))) \ + ? fflush(stream):0)) + +#define getc(stream) \ + ((stream)->ungetted ? (((stream)->ungetted = 0), ((stream)->ungetchar)) : \ + (((stream)->bufpos == (stream)->bufread)?__ffillbuf(stream): \ + (*(stream)->bufpos++))) + +#endif + +#define putchar(c) putc((c), stdout) +#define getchar() getc(stdin) +#define ungetc(c, stream) (((stream)->ungetted = 1), ((stream)->ungetchar = c)) + +#define ferror(fp) ((fp)->fc_err) +#define feof(fp) ((fp)->fc_eof) + +#define fileno(fp) ((fp)->fd) +/* declare functions; not like it makes much difference without ANSI */ +/* RDB: The return values _are_ important, especially if we ever use + 8086 'large' model + */ + +#ifndef __P +#define __P(x) () +#endif + +int setvbuf __P((FILE*, char*, int, size_t)); +int __ffillbuf __P((FILE*)); +void __stdio_init __P((void)); +int fclose __P((FILE*)); +int fflush __P((FILE*)); +int fgetc __P((FILE*)); +char *fgets __P((char*, size_t, FILE*)); +FILE *fopen __P((char*, char*)); + +int fputc __P((int, FILE*)); +int fputs __P((__const char*, FILE*)); +char *idealgetline __P((FILE*)); +int puts __P((char*)); + +int printf __P ((__const char *, ...)); +int fprintf __P ((FILE *, __const char *, ...)); +int sprintf __P ((char *, __const char *, ...)); + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#endif /* __STDIO_H */ +/* TODO: add scanf, fscanf */ diff --git a/libc-0.0.4/stdio1/test.sh b/libc-0.0.4/stdio1/test.sh new file mode 100755 index 0000000..9d872dc --- /dev/null +++ b/libc-0.0.4/stdio1/test.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +echo 'rm -f *.o test *.a' +rm -f *.o test *.a +echo 'make' +make +echo 'ar r libnat.a *.o' +ar r libnat.a *.o +echo 'ranlib libnat.a' +ranlib libnat.a +echo 'gcc test.c -I- -I../include -fno-builtin -o test.o -L./ -lnat' +gcc test.c -I- -I../include -fno-builtin -o test.o -L./ -lnat diff --git a/libc-0.0.4/stdio2/Config b/libc-0.0.4/stdio2/Config new file mode 100644 index 0000000..665045f --- /dev/null +++ b/libc-0.0.4/stdio2/Config @@ -0,0 +1,4 @@ +# + +stdio: Robert's stdio package + diff --git a/libc-0.0.4/stdio2/Funcs b/libc-0.0.4/stdio2/Funcs new file mode 100644 index 0000000..a177893 --- /dev/null +++ b/libc-0.0.4/stdio2/Funcs @@ -0,0 +1,43 @@ ++clearerr Stdio ++fclose Stdio ++fdopen Stdio ++feof Stdio ++ferror Stdio ++fflush Stdio ++fgetc Stdio ++fgets Stdio ++fileno Stdio ++fopen Stdio ++fprintf Stdio ++fputc Stdio ++fputs Stdio ++fread Stdio ++freopen Stdio ++fscanf Stdio ++fseek Stdio ++ftell Stdio ++fwrite Stdio ++getc Stdio ++getchar Stdio ++gets Stdio ++pclose Stdio Popen ++popen Stdio Popen ++printf Stdio ++putc Stdio ++putchar Stdio ++puts Stdio ++rewind Stdio ++scanf Stdio ++setbuf Stdio ++setbuffer Stdio ++sprintf Stdio ++sscanf Stdio ++ungetc Stdio ++vfprintf Stdio ++vfscanf Stdio ++vprintf Stdio ++vscanf Stdio ++vsprintf Stdio ++vsscanf Stdio +setlinebuf Stdio +setvbuf Stdio diff --git a/libc-0.0.4/stdio2/Makefile b/libc-0.0.4/stdio2/Makefile new file mode 100644 index 0000000..51c48c1 --- /dev/null +++ b/libc-0.0.4/stdio2/Makefile @@ -0,0 +1,39 @@ + +TOP=.. +include $(TOP)/Make.defs + +ASRC=stdio.c +AOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ + puts.o fread.o fwrite.o fopen.o fclose.o fseek.o rewind.o ftell.o \ + setbuffer.o ungetc.o + +PSRC=printf.c +POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o + +SSRC=scanf.c +SOBJ=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o + +OBJ= $(AOBJ) $(POBJ) $(SOBJ) + +all: $(OBJ) + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +transfer: + -@rm -f ../include/stdio.h + cp -p stdio.h ../include/. + +clean: + rm -f $(OBJ) libc.a + +$(AOBJ): $(ASRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ASRC) + +$(POBJ): $(PSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(PSRC) + +$(SOBJ): $(SSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(SSRC) + diff --git a/libc-0.0.4/stdio2/printf.c b/libc-0.0.4/stdio2/printf.c new file mode 100644 index 0000000..0d107a4 --- /dev/null +++ b/libc-0.0.4/stdio2/printf.c @@ -0,0 +1,362 @@ +/* + * This file based on printf.c from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ + +/* Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <stdarg.h> + +#include "stdio.h" + +#ifdef L_printf + +#ifdef __STDC__ +int printf(const char * fmt, ...) +#else +int printf(fmt) +__const char *fmt; +#endif +{ + va_list ptr; + int rv; + va_start(ptr, fmt); + rv = vfprintf(stdout,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_sprintf +#ifdef __STDC__ +int sprintf(char * sp, const char * fmt, ...) +#else +int sprintf(sp, fmt) +char * sp; +__const char *fmt; +#endif +{ +static FILE string[1] = +{ + {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; + + va_list ptr; + int rv; + va_start(ptr, fmt); + string->bufpos = sp; + rv = vfprintf(string,fmt,ptr); + va_end(ptr); + *(string->bufpos) = 0; + return rv; +} +#endif + +#ifdef L_fprintf +#ifdef __STDC__ +int fprintf(FILE * fp, const char * fmt, ...) +#else +int fprintf(fp, fmt) +FILE * fp; +__const char *fmt; +#endif +{ + va_list ptr; + int rv; + va_start(ptr, fmt); + rv = vfprintf(fp,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_vprintf +int vprintf(fmt, ap) +__const char *fmt; +va_list ap; +{ + return vfprintf(stdout,fmt,ap); +} +#endif + +#ifdef L_vsprintf +int vsprintf(sp, fmt, ap) +char * sp; +__const char *fmt; +va_list ap; +{ +static FILE string[1] = +{ + {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; + + int rv; + string->bufpos = sp; + rv = vfprintf(string,fmt,ap); + *(string->bufpos) = 0; + return rv; +} +#endif + +#ifdef L_vfprintf +static int +prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode) +register FILE *op; +register unsigned char *buf; +int ljustf; +register char sign; +char pad; +register int width; +int preci; +int buffer_mode; +/* + * Output the given field in the manner specified by the arguments. Return + * the number of characters output. + */ +{ + register int cnt = 0, len; + register unsigned char ch; + + len = strlen(buf); + + if (*buf == '-') + sign = *buf++; + else if (sign) + len++; + + if ((preci != -1) && (len > preci)) /* limit max data width */ + len = preci; + + if (width < len) /* flexible field width or width overflow */ + width = len; + + /* + * at this point: width = total field width len = actual data width + * (including possible sign character) + */ + cnt = width; + width -= len; + + while (width || len) + { + if (!ljustf && width) /* left padding */ + { + if (len && sign && (pad == '0')) + goto showsign; + ch = pad; + --width; + } + else if (len) + { + if (sign) + { + showsign:ch = sign; /* sign */ + sign = '\0'; + } + else + ch = *buf++; /* main field */ + --len; + } + else + { + ch = pad; /* right padding */ + --width; + } + putc(ch, op); + if( ch == '\n' && buffer_mode == _IOLBF ) fflush(op); + } + + return (cnt); +} + +int +vfprintf(op, fmt, ap) +FILE *op; +register __const char *fmt; +register va_list ap; +{ + register int i, cnt = 0, ljustf, lval; + int preci, dpoint, width; + char pad, sign, radix, hash; + register char *ptmp; + char tmp[64], *ltostr(), *ultostr(); + int buffer_mode; +#if FLOATS + double fx; +#endif + + /* This speeds things up a bit for unbuffered */ + buffer_mode = (op->mode&__MODE_BUF); + op->mode &= (~__MODE_BUF); + + while (*fmt) + { + if (*fmt == '%') + { + if( buffer_mode == _IONBF ) fflush(op); + ljustf = 0; /* left justify flag */ + sign = '\0'; /* sign char & status */ + pad = ' '; /* justification padding char */ + width = -1; /* min field width */ + dpoint = 0; /* found decimal point */ + preci = -1; /* max data width */ + radix = 10; /* number base */ + ptmp = tmp; /* pointer to area to print */ + hash = 0; + lval = (sizeof(int)==sizeof(long)); /* long value flaged */ + fmtnxt: + i = 0; + for(;;) + { + ++fmt; + if(*fmt < '0' || *fmt > '9' ) break; + i = (i * 10) + (*fmt - '0'); + if (dpoint) + preci = i; + else if (!i && (pad == ' ')) + { + pad = '0'; + goto fmtnxt; + } + else + width = i; + } + + switch (*fmt) + { + case '\0': /* early EOS */ + --fmt; + goto charout; + + case '-': /* left justification */ + ljustf = 1; + goto fmtnxt; + + case ' ': + case '+': /* leading sign flag */ + sign = *fmt; + goto fmtnxt; + + case '*': /* parameter width value */ + i = va_arg(ap, int); + if (dpoint) + preci = i; + else + width = i; + goto fmtnxt; + + case '.': /* secondary width field */ + dpoint = 1; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'd': /* Signed decimal */ + case 'i': + ptmp = ltostr((long) ((lval) + ? va_arg(ap, long) + : va_arg(ap, short)), + 10); + goto printit; + + case 'b': /* Unsigned binary */ + radix = 2; + goto usproc; + + case 'o': /* Unsigned octal */ + radix = 8; + goto usproc; + + case 'p': /* Pointer */ + lval = (sizeof(char*) == sizeof(long)); + pad = '0'; + width = 6; + preci = 8; + /* fall thru */ + + case 'x': /* Unsigned hexadecimal */ + case 'X': + radix = 16; + /* fall thru */ + + case 'u': /* Unsigned decimal */ + usproc: + ptmp = ultostr((unsigned long) ((lval) + ? va_arg(ap, unsigned long) + : va_arg(ap, unsigned short)), + radix); + if( hash && radix == 8 ) { width = strlen(ptmp)+1; pad='0'; } + goto printit; + + case '#': + hash=1; + goto fmtnxt; + +#if FLOATS + case 'e': /* float */ + case 'f': + case 'g': + case 'E': + case 'G': + fx = va_arg(ap, double); + fp_print(fx, *fmt, preci, ptmp); + preci = -1; + goto printit; +#endif + + case 'c': /* Character */ + ptmp[0] = va_arg(ap, int); + ptmp[1] = '\0'; + goto nopad; + + case 's': /* String */ + ptmp = va_arg(ap, char*); + nopad: + sign = '\0'; + pad = ' '; + printit: + cnt += prtfld(op, ptmp, ljustf, + sign, pad, width, preci, buffer_mode); + break; + + default: /* unknown character */ + goto charout; + } + } + else + { + charout: + putc(*fmt, op); /* normal char out */ + ++cnt; + if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op); + } + ++fmt; + } + op->mode |= buffer_mode; + if( buffer_mode == _IONBF ) fflush(op); + if( buffer_mode == _IOLBF ) op->bufwrite = op->bufstart; + return (cnt); +} +#endif diff --git a/libc-0.0.4/stdio2/scanf.c b/libc-0.0.4/stdio2/scanf.c new file mode 100644 index 0000000..c43320d --- /dev/null +++ b/libc-0.0.4/stdio2/scanf.c @@ -0,0 +1,511 @@ +#include <stdio.h> +#include <ctype.h> +#include <stdarg.h> +#include <string.h> + +#ifdef L_scanf +#ifdef __STDC__ +int scanf(const char * fmt, ...) +#else +int scanf(fmt) +__const char *fmt; +#endif +{ + va_list ptr; + int rv; + va_start(ptr, fmt); + rv = vfscanf(stdin,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_sscanf +#ifdef __STDC__ +int sscanf(char * sp, const char * fmt, ...) +#else +int sscanf(sp, fmt) +char * sp; +__const char *fmt; +#endif +{ +static FILE string[1] = +{ + {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_READ} +}; + + va_list ptr; + int rv; + va_start(ptr, fmt); + string->bufpos = sp; + rv = vfscanf(string,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_fscanf +#ifdef __STDC__ +int fscanf(FILE * fp, const char * fmt, ...) +#else +int fscanf(fp, fmt) +FILE * fp; +__const char *fmt; +#endif +{ + va_list ptr; + int rv; + va_start(ptr, fmt); + rv = vfscanf(fp,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_vscanf +int vscanf(fmt, ap) +__const char *fmt; +va_list ap; +{ + return vfscanf(stdin,fmt,ap); +} +#endif + +#ifdef L_vsscanf +int vsscanf(sp, fmt, ap) +char * sp; +__const char *fmt; +{ +static FILE string[1] = +{ + {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_READ} +}; + + string->bufpos = sp; + return vfscanf(string,fmt,ap); +} +#endif + +#ifdef L_vfscanf +/* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/ + +#define skip() while(isspace(c)) { if ((c=getc(fp))<1) goto done; } + +#if FLOATS +/* fp scan actions */ +#define F_NADA 0 /* just change state */ +#define F_SIGN 1 /* set sign */ +#define F_ESIGN 2 /* set exponent's sign */ +#define F_INT 3 /* adjust integer part */ +#define F_FRAC 4 /* adjust fraction part */ +#define F_EXP 5 /* adjust exponent part */ +#define F_QUIT 6 + +#define NSTATE 8 +#define FS_INIT 0 /* initial state */ +#define FS_SIGNED 1 /* saw sign */ +#define FS_DIGS 2 /* saw digits, no . */ +#define FS_DOT 3 /* saw ., no digits */ +#define FS_DD 4 /* saw digits and . */ +#define FS_E 5 /* saw 'e' */ +#define FS_ESIGN 6 /* saw exp's sign */ +#define FS_EDIGS 7 /* saw exp's digits */ + +#define FC_DIG 0 +#define FC_DOT 1 +#define FC_E 2 +#define FC_SIGN 3 + +/* given transition,state do what action? */ +int fp_do[][NSTATE] = { + {F_INT,F_INT,F_INT, + F_FRAC,F_FRAC, + F_EXP,F_EXP,F_EXP}, /* see digit */ + {F_NADA,F_NADA,F_NADA, + F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT}, /* see '.' */ + {F_QUIT,F_QUIT, + F_NADA,F_QUIT,F_NADA, + F_QUIT,F_QUIT,F_QUIT}, /* see e/E */ + {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT, + F_ESIGN,F_QUIT,F_QUIT}, /* see sign */ +}; +/* given transition,state what is new state? */ +int fp_ns[][NSTATE] = { + {FS_DIGS,FS_DIGS,FS_DIGS, + FS_DD,FS_DD, + FS_EDIGS,FS_EDIGS,FS_EDIGS}, /* see digit */ + {FS_DOT,FS_DOT,FS_DD, + }, /* see '.' */ + {0,0, + FS_E,0,FS_E, + }, /* see e/E */ + {FS_SIGNED,0,0,0,0, + FS_ESIGN,0,0}, /* see sign */ +}; +/* which states are valid terminators? */ +int fp_sval[NSTATE] = { + 0,0,1,0,1,0,0,1 +}; +#endif + +vfscanf(fp, fmt, ap) +register FILE *fp; +register char *fmt; +va_list ap; + +{ + register long n; + register int c, width, lval, cnt = 0; + int store, neg, base, wide1, endnull, rngflag, c2; + register unsigned char *p; + unsigned char delim[128], digits[17], *q; +#if FLOATS + long frac, expo; + int eneg, fraclen, fstate, trans; + double fx, fp_scan(); +#endif + + if (!*fmt) + return (0); + + c = getc(fp); + while (c > 0) + { + store = 0; + if (*fmt == '%') + { + n = 0; + width = -1; + wide1 = 1; + base = 10; + lval = (sizeof(long) == sizeof(int)); + store = 1; + endnull = 1; + neg = -1; + + strcpy(delim, "\011\012\013\014\015 "); + strcpy(digits, "0123456789ABCDEF"); + + if (fmt[1] == '*') + { + endnull = store = 0; + ++fmt; + } + + while (isdigit(*++fmt))/* width digit(s) */ + { + if (width == -1) + width = 0; + wide1 = width = (width * 10) + (*fmt - '0'); + } + --fmt; + fmtnxt: + ++fmt; + switch (tolower(*fmt)) /* tolower() is a MACRO! */ + { + case '*': + endnull = store = 0; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'i': /* any-base numeric */ + base = 0; + goto numfmt; + + case 'b': /* unsigned binary */ + base = 2; + goto numfmt; + + case 'o': /* unsigned octal */ + base = 8; + goto numfmt; + + case 'x': /* unsigned hexadecimal */ + base = 16; + goto numfmt; + + case 'd': /* SIGNED decimal */ + neg = 0; + /* FALL-THRU */ + + case 'u': /* unsigned decimal */ + numfmt:skip(); + + if (isupper(*fmt)) + lval = 1; + + if (!base) + { + base = 10; + neg = 0; + if (c == '%') + { + base = 2; + goto skip1; + } + else if (c == '0') + { + c = getc(fp); + if (c < 1) + goto savnum; + if ((c != 'x') + && (c != 'X')) + { + base = 8; + digits[8] = '\0'; + goto zeroin; + } + base = 16; + goto skip1; + } + } + + if ((neg == 0) && (base == 10) + && ((neg = (c == '-')) || (c == '+'))) + { + skip1: + c = getc(fp); + if (c < 1) + goto done; + } + + digits[base] = '\0'; + p = ((unsigned char *) + strchr(digits, toupper(c))); + + if ((!c || !p) && width) + goto done; + + while (p && width-- && c) + { + n = (n * base) + (p - digits); + c = getc(fp); + zeroin: + p = ((unsigned char *) + strchr(digits, toupper(c))); + } + savnum: + if (store) + { + if (neg == 1) + n = -n; + if (lval) + *va_arg(ap, long*) = n; + else + *va_arg(ap, short*) = n; + ++cnt; + } + break; + +#if FLOATS + case 'e': /* float */ + case 'f': + case 'g': + skip(); + + if (isupper(*fmt)) + lval = 1; + + fstate = FS_INIT; + neg = 0; + eneg = 0; + n = 0; + frac = 0; + expo = 0; + fraclen = 0; + + while (c && width--) + { + if (c >= '0' && c <= '9') + trans = FC_DIG; + else if (c == '.') + trans = FC_DOT; + else if (c == '+' || c == '-') + trans = FC_SIGN; + else if (tolower(c) == 'e') + trans = FC_E; + else + goto fdone; + + switch (fp_do[trans][fstate]) + { + case F_SIGN: + neg = (c == '-'); + break; + case F_ESIGN: + eneg = (c == '-'); + break; + case F_INT: + n = 10 * n + (c - '0'); + break; + case F_FRAC: + frac = 10 * frac + (c - '0'); + fraclen++; + break; + case F_EXP: + expo = 10 * expo + (c - '0'); + break; + case F_QUIT: + goto fdone; + } + fstate = fp_ns[trans][fstate]; + c = getc(fp); + } + + fdone: + if (!fp_sval[fstate]) + goto done; + if (store) + { + fx = fp_scan(neg, eneg, n, frac, expo, fraclen); + if (lval) + *va_arg(ap, double *) = fx; + else + *va_arg(ap, float *) = fx; + ++cnt; + } + break; +#endif + + case 'c': /* character data */ + width = wide1; + lval = endnull = 0; + delim[0] = '\0'; + goto strproc; + + case '[': /* string w/ delimiter set */ + + /* get delimiters */ + p = delim; + + if (*++fmt == '^') + { + fmt++; + lval = 0; + } + else + lval = 1; + + rngflag = 2; + if ((*fmt == ']') || (*fmt == '-')) + { + *p++ = *fmt++; + rngflag = 0; + } + + while (*fmt != ']') + { + if (*fmt == '\0') + goto done; + switch (rngflag) + { + case 1: + c2 = *(p - 2); + if (c2 <= *fmt) + { + p -= 2; + while (c2 < *fmt) + *p++ = c2++; + rngflag = 2; + break; + } + /* fall thru intentional */ + + case 0: + rngflag = (*fmt == '-'); + break; + + case 2: + rngflag = 0; + } + + *p++ = *fmt++; + } + + *p = '\0'; + goto strproc; + + case 's': /* string data */ + lval = 0; + skip(); + strproc: + /* process string */ + p = va_arg(ap, unsigned char *); + + /* if the 1st char fails, match fails */ + if (width) + { + q = ((unsigned char *) + strchr(delim, c)); + if ((c < 1) || lval == (q==0)) + { + if (endnull) + *p = '\0'; + goto done; + } + } + + for (;;) /* FOREVER */ + { + if (store) + *p++ = c; + if (((c = getc(fp)) < 1) || + (--width == 0)) + break; + + q = ((unsigned char *) + strchr(delim, c)); + if (lval == (q==0)) + break; + } + + if (store) + { + if (endnull) + *p = '\0'; + ++cnt; + } + break; + + case '\0': /* early EOS */ + --fmt; + /* FALL THRU */ + + default: + goto cmatch; + } + } + else if (isspace(*fmt)) /* skip whitespace */ + { + skip(); + } + else + { /* normal match char */ + cmatch: + if (c != *fmt) + break; + c = getc(fp); + } + + if (!*++fmt) + break; + } + + done: /* end of scan */ + if ((c == EOF) && (cnt == 0)) + return (EOF); + + if( c != EOF ) + ungetc(c, fp); + return (cnt); +} + +#endif diff --git a/libc-0.0.4/stdio2/stdio.c b/libc-0.0.4/stdio2/stdio.c new file mode 100644 index 0000000..575a8f9 --- /dev/null +++ b/libc-0.0.4/stdio2/stdio.c @@ -0,0 +1,738 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. + */ + +#include <stdio.h> + +#include <fcntl.h> +#include <sys/types.h> +#include <malloc.h> +#include <errno.h> + +extern FILE *__IO_list; /* For fflush at exit */ + +#ifndef __AS386_16__ +#define Inline_init __io_init_vars() +#else +#define Inline_init +#endif + +#ifdef L__stdio_init + +FILE *__IO_list = 0; /* For fflush at exit */ + +static char bufin[BUFSIZ]; +static char bufout[BUFSIZ]; + +#define buferr (stderr->unbuf) /* Stderr is unbuffered */ + +FILE stdin[1] = +{ + {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} +}; + +FILE stdout[1] = +{ + {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +FILE stderr[1] = +{ + {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), + 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +/* Call the stdio initiliser; it's main job it to call atexit */ + +#ifndef __AS386_16__ +#define STATIC +#else +#define STATIC static + +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .word ___io_init_vars ! Pointer to the autorun function + .word no_op ! Space filler cause segs are padded to 4 bytes. + .text ! So the function after is also in the correct seg. +#endasm +#endif + +STATIC int +__stdio_close_all() +{ + FILE *fp; + fflush(stdout); + fflush(stderr); + for (fp = __IO_list; fp; fp = fp->next) + { + fflush(fp); + close(fp->fd); + /* Note we're not de-allocating the memory */ + /* There doesn't seem to be much point :-) */ + fp->fd = -1; + } +} + +STATIC void +__io_init_vars() +{ +#ifndef __AS386_16__ + static int first_time = 1; + if( !first_time ) return ; first_time = 1; +#endif + if (isatty(1)) + stdout->mode |= _IOLBF; + atexit(__stdio_close_all); +} +#endif + +#ifdef L_fputc +int +fputc(ch, fp) +int ch; +FILE *fp; +{ + register int v; + Inline_init; + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return EOF; + + /* Can't write or 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 (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) + return EOF; +#endif + + /* Buffer is full */ + if (fp->bufpos >= fp->bufend && fflush(fp)) + return EOF; + + /* Right! Do it! */ + *(fp->bufpos++) = ch; + fp->mode |= __MODE_WRITING; + + /* Unbuffered or Line buffered and end of line */ + if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) + && fflush(fp)) + return EOF; + + /* Can the macro handle this by itself ? */ + if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) + fp->bufwrite = fp->bufstart; /* Nope */ + else + fp->bufwrite = fp->bufend; /* Yup */ + + /* Correct return val */ + return (unsigned char) ch; +} +#endif + +#ifdef L_fgetc +int +fgetc(fp) +FILE *fp; +{ + int ch; + + if (fp->mode & __MODE_WRITING) + fflush(fp); + + try_again: + /* Can't read or there's been an EOF or error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Nothing in the buffer - fill it up */ + if (fp->bufpos >= fp->bufread) + { + fp->bufpos = fp->bufread = fp->bufstart; + ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); + if (ch == 0) + return EOF; + fp->bufread += ch; + fp->mode |= __MODE_READING; + fp->mode &= ~__MODE_UNGOT; + } + ch = *(fp->bufpos++); + +#if __MODE_IOTRAN + /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ + if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) + goto try_again; +#endif + + return ch; +} +#endif + +#ifdef L_fflush +int +fflush(fp) +FILE *fp; +{ + int len, cc; + if (fp == NULL) /* On NULL flush the lot. */ + { + if (fflush(stdin)) + return EOF; + if (fflush(stdout)) + return EOF; + if (fflush(stderr)) + return EOF; + + for (fp = __IO_list; fp; fp = fp->next) + if (fflush(fp)) + return EOF; + + return 0; + } + + /* If there's output data pending */ + if (fp->mode & __MODE_WRITING) + { + len = fp->bufpos - fp->bufstart; + + if (len) + { + /* + * The loop is so we don't get upset by signals + */ + do + { + cc = write(fp->fd, fp->bufstart, len); + } + while (cc == -1 && errno == EINTR); + /* + * I think the following test is _too_ stringent, but it's not + * serious If it is found to be a problem then if cc>0 we can do + * a memcpy to put the buffer in a state for a retry. Or even do + * the retry ourselves. + */ + if (cc != len) + { + fp->mode |= __MODE_ERR; + return EOF; + } + } + } + /* If there's data in the buffer sychronise the file positions */ + else if (fp->mode & __MODE_READING) + { + /* Humm, I think this means sync the file like fpurge() ... */ + /* Anyway the user isn't supposed to call this function when reading */ + + len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ + /* If it's a file, make it good */ + if (len > 0 && lseek(fp->fd, -len, 1) < 0) + { + /* Hummm - Not certain here, I don't think this is reported */ + /* + * fp->mode |= __MODE_ERR; return EOF; + */ + } + } + + /* All done, no problem */ + fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT)); + fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; + return 0; +} +#endif + +#ifdef L_fgets +/* Nothing special here ... */ +char * +fgets(s, count, f) +char *s; +size_t count; +FILE *f; +{ + char *ret; + register size_t i; + register int ch; + + ret = s; + for (i = count; i > 0; i--) + { + ch = getc(f); + if (ch == EOF) + { + if (s == ret) + return 0; + break; + } + *s++ = (char) ch; + if (ch == '\n') + break; + } + *s = 0; + + if (ferror(f)) + return 0; + return ret; +} +#endif + +#ifdef L_gets +char * +gets(str) /* BAD function; DON'T use it! */ +char *str; +{ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register char *p = str; + register int c; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ +} +#endif + +#ifdef L_fputs +int +fputs(str, fp) +char *str; +FILE *fp; +{ + register int n = 0; + while (*str) + { + if (putc(*str++, fp) == EOF) + return (EOF); + ++n; + } + return (n); +} +#endif + +#ifdef L_puts +int +puts(str) +char *str; +{ + register int n; + + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +} +#endif + +#ifdef L_fread +/* + * fread will often be used to read in large chunks of data calling read() + * directly can be a big win in this case. Beware also fgetc calls this + * function to fill the buffer. + * + * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what + * fgetc wants) + */ +int +fread(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + int len, v; + unsigned bytes, got = 0; + Inline_init; + + v = fp->mode; + + /* Want to do this to bring the file pointer up to date */ + if (v & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an EOF or error then return zero */ + if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufread - fp->bufpos; + if (len >= bytes) /* Enough buffered */ + { + memcpy(buf, fp->bufpos, (unsigned) bytes); + fp->bufpos += bytes; + return bytes; + } + else if (len > 0) /* Some buffered */ + { + memcpy(buf, fp->bufpos, len); + got = len; + } + + /* Need more; do it with a direct read */ + len = read(fp->fd, buf + got, (unsigned) (bytes - got)); + + /* Possibly for now _or_ later */ + if (len < 0) + { + fp->mode |= __MODE_ERR; + len = 0; + } + else if (len == 0) + fp->mode |= __MODE_EOF; + + return (got + len) / size; +} +#endif + +#ifdef L_fwrite +/* + * Like fread, fwrite will often be used to write out large chunks of + * data; calling write() directly can be a big win in this case. + * + * But first we check to see if there's space in the buffer. + * + * Again this ignores __MODE__IOTRAN. + */ +int +fwrite(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + register int v; + int len; + unsigned bytes, put; + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return 0; + + /* Can't write or there's been an EOF or error then return 0 */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufend - fp->bufpos; + + /* Flush the buffer if not enough room */ + if (bytes > len) + if (fflush(fp)) + return 0; + + len = fp->bufend - fp->bufpos; + if (bytes <= len) /* It'll fit in the buffer ? */ + { + fp->mode |= __MODE_WRITING; + memcpy(fp->bufpos, buf, bytes); + fp->bufpos += bytes; + + /* If we're not fully buffered */ + if (v & (_IOLBF | _IONBF)) + fflush(fp); + + return nelm; + } + else + /* Too big for the buffer */ + { + put = write(fp->fd, buf, bytes); + if (put < 0) + { + fp->mode |= __MODE_ERR; + put = 0; + } + } + + return put / size; +} +#endif + +#ifdef L_rewind +void +rewind(fp) +FILE * fp; +{ + fseek(fp, (long)0, 0); + clearerr(fp); +} +#endif + +#ifdef L_fseek +int +fseek(fp, offset, ref) +FILE *fp; +long offset; +int ref; +{ + /* Use fflush to sync the pointers */ + /* + * TODO: if __MODE_READING and no ungetc ever done can just move + * pointer + */ + + if (fflush(fp) == EOF) + return EOF; + if (lseek(fp->fd, offset, ref) < 0) + return EOF; + return 0; +} +#endif + +#ifdef L_ftell +long ftell(fp) +FILE * fp; +{ + long rv; + if (fflush(fp) == EOF) + return EOF; + return lseek(fp->fd, 0L, SEEK_CUR); +} +#endif + +#ifdef L_fopen +/* + * This Fopen is all three of fopen, fdopen and freopen. The macros in + * stdio.h show the other names. + */ +FILE * +__fopen(fname, fd, fp, mode) +char *fname; +int fd; +FILE *fp; +char *mode; +{ + int open_mode = 0; +#if __MODE_IOTRAN + int do_iosense = 1; +#endif + int fopen_mode = 0; + FILE *nfp = 0; + + /* If we've got an fp close the old one (freopen) */ + if (fp) + { + /* Careful, don't de-allocate it */ + fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); + fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); + fclose(fp); + } + + /* decode the new open mode */ + while (*mode) + switch (*mode++) + { + case 'r': + fopen_mode |= __MODE_READ; + break; + case 'w': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_TRUNC); + break; + case 'a': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_APPEND); + break; + case '+': + fopen_mode |= __MODE_RDWR; + break; +#if __MODE_IOTRAN + case 'b': /* Binary */ + fopen_mode &= ~__MODE_IOTRAN; + do_iosense=0; + break; + case 't': /* Text */ + fopen_mode |= __MODE_IOTRAN; + do_iosense=0; + break; +#endif + } + + /* Add in the read/write options to mode for open() */ + switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) + { + case 0: + return 0; + case __MODE_READ: + open_mode |= O_RDONLY; + break; + case __MODE_WRITE: + open_mode |= O_WRONLY; + break; + default: + open_mode |= O_RDWR; + break; + } + + /* Allocate the (FILE) before we do anything irreversable */ + if (fp == 0) + { + nfp = malloc(sizeof(FILE)); + if (nfp == 0) + return 0; + } + + /* Open the file itself */ + if (fname) + fd = open(fname, open_mode, 0666); + if (fd < 0) /* Grrrr */ + { + if (nfp) + free(nfp); + return 0; + } + + /* If this isn't freopen create a (FILE) and buffer for it */ + if (fp == 0) + { + fp = nfp; + fp->next = __IO_list; + __IO_list = fp; + + fp->mode = __MODE_FREEFIL; + if( isatty(fd) ) + { + fp->mode |= _IOLBF; +#if __MODE_IOTRAN + if( do_iosense ) fopen_mode |= __MODE_IOTRAN; +#endif + } + else + fp->mode |= _IOFBF; + fp->bufstart = malloc(BUFSIZ); + if (fp->bufstart == 0) /* Oops, no mem */ + { /* Humm, full buffering with a two(!) byte + * buffer. */ + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + } + else + { + fp->bufend = fp->bufstart + BUFSIZ; + fp->mode |= __MODE_FREEBUF; + } + } + + /* Ok, file's ready clear the buffer and save important bits */ + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fp->mode |= fopen_mode; + fp->fd = fd; + + return fp; +} +#endif + +#ifdef L_fclose +int +fclose(fp) +FILE *fp; +{ + int rv = 0; + + if (fp == 0) + { + errno = EINVAL; + return EOF; + } + if (fflush(fp)) + return EOF; + + if (close(fp->fd)) + rv = EOF; + fp->fd = -1; + + if (fp->mode & __MODE_FREEBUF) + { + free(fp->bufstart); + fp->mode &= ~__MODE_FREEBUF; + fp->bufstart = fp->bufend = 0; + } + + if (fp->mode & __MODE_FREEFIL) + { + FILE *prev = 0, *ptr; + fp->mode = 0; + + for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next) + ; + if (ptr == fp) + { + if (prev == 0) + __IO_list = fp->next; + else + prev->next = fp->next; + } + free(fp); + } + else + fp->mode = 0; + + return rv; +} +#endif + +#ifdef L_setbuffer +void +setbuffer(fp, buf, size) +FILE * fp; +char * buf; +int size; +{ + fflush(fp); + if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart); + fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); + + if( buf == 0 ) + { + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + } + else + { + fp->bufstart = buf; + fp->bufend = buf+size; + fp->mode |= _IOFBF; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; +} +#endif + +#ifdef L_ungetc +int +ungetc(c, fp) +int c; +FILE *fp; +{ + if (fp->mode & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) + return EOF; + + if( fp->bufpos > fp->bufstart ) + return *--fp->bufpos = (unsigned char) c; + else if( fp->bufread == fp->bufstart ) + return *fp->bufread++ = (unsigned char) c; + else + return EOF; +} +#endif + diff --git a/libc-0.0.4/stdio2/stdio.c.old b/libc-0.0.4/stdio2/stdio.c.old new file mode 100644 index 0000000..2c06b8d --- /dev/null +++ b/libc-0.0.4/stdio2/stdio.c.old @@ -0,0 +1,730 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. + */ + +#include <stdio.h> + +#include <fcntl.h> +#include <sys/types.h> +#include <malloc.h> +#include <errno.h> + +extern FILE *__IO_list; /* For fflush at exit */ + +#ifndef __AS386_16__ +#define Inline_init __io_init_vars() +#else +#define Inline_init +#endif + +#ifdef L__stdio_init + +FILE *__IO_list = 0; /* For fflush at exit */ + +static char bufin[BUFSIZ]; +static char bufout[BUFSIZ]; + +#define buferr (stderr->unbuf) /* Stderr is unbuffered */ + +FILE stdin[1] = +{ + {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} +}; + +FILE stdout[1] = +{ + {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +FILE stderr[1] = +{ + {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), + 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +/* Call the stdio initiliser; it's main job it to call atexit */ + +#ifndef __AS386_16__ +#define STATIC +#else +#define STATIC static + +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .word ___io_init_vars ! Pointer to the autorun function + .word no_op ! Space filler cause segs are padded to 4 bytes. + .text ! So the function after is also in the correct seg. +#endasm +#endif + +STATIC int +__stdio_close_all() +{ + FILE *fp; + fflush(stdout); + fflush(stderr); + for (fp = __IO_list; fp; fp = fp->next) + { + fflush(fp); + close(fp->fd); + /* Note we're not de-allocating the memory */ + /* There doesn't seem to be much point :-) */ + fp->fd = -1; + } +} + +STATIC void +__io_init_vars() +{ +#ifndef __AS386_16__ + static int first_time = 1; + if( !first_time ) return ; first_time = 1; +#endif + if (isatty(1)) + stdout->mode |= _IOLBF; + atexit(__stdio_close_all); +} +#endif + +#ifdef L_fputc +int +fputc(ch, fp) +int ch; +FILE *fp; +{ + register int v; + Inline_init; + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return EOF; + + /* Can't write or 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 (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) + return EOF; +#endif + + /* Buffer is full */ + if (fp->bufpos >= fp->bufend && fflush(fp)) + return EOF; + + /* Right! Do it! */ + *(fp->bufpos++) = ch; + fp->mode |= __MODE_WRITING; + + /* Unbuffered or Line buffered and end of line */ + if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) + && fflush(fp)) + return EOF; + + /* Can the macro handle this by itself ? */ + if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) + fp->bufwrite = fp->bufstart; /* Nope */ + else + fp->bufwrite = fp->bufend; /* Yup */ + + /* Correct return val */ + return (unsigned char) ch; +} +#endif + +#ifdef L_fgetc +int +fgetc(fp) +FILE *fp; +{ + int ch; + + if (fp->mode & __MODE_WRITING) + fflush(fp); + + try_again: + /* Can't read or there's been an EOF or error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Nothing in the buffer - fill it up */ + if (fp->bufpos >= fp->bufread) + { + fp->bufpos = fp->bufread = fp->bufstart; + ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); + if (ch == 0) + return EOF; + fp->bufread += ch; + fp->mode |= __MODE_READING; + fp->mode &= ~__MODE_UNGOT; + } + ch = *(fp->bufpos++); + +#if __MODE_IOTRAN + /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ + if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) + goto try_again; +#endif + + return ch; +} +#endif + +#ifdef L_fflush +int +fflush(fp) +FILE *fp; +{ + int len, cc; + if (fp == NULL) /* On NULL flush the lot. */ + { + if (fflush(stdin)) + return EOF; + if (fflush(stdout)) + return EOF; + if (fflush(stderr)) + return EOF; + + for (fp = __IO_list; fp; fp = fp->next) + if (fflush(fp)) + return EOF; + + return 0; + } + + /* If there's output data pending */ + if (fp->mode & __MODE_WRITING) + { + len = fp->bufpos - fp->bufstart; + + if (len) + { + /* + * The loop is so we don't get upset by signals + */ + do + { + cc = write(fp->fd, fp->bufstart, len); + } + while (cc == -1 && errno == EINTR); + /* + * I think the following test is _too_ stringent, but it's not + * serious If it is found to be a problem then if cc>0 we can do + * a memcpy to put the buffer in a state for a retry. Or even do + * the retry ourselves. + */ + if (cc != len) + { + fp->mode |= __MODE_ERR; + return EOF; + } + } + } + /* If there's data in the buffer sychronise the file positions */ + else if (fp->mode & __MODE_READING) + { + /* Humm, I think this means sync the file like fpurge() ... */ + /* Anyway the user isn't supposed to call this function when reading */ + + len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ + /* If it's a file, make it good */ + if (len > 0 && lseek(fp->fd, -len, 1) < 0) + { + /* Hummm - Not certain here, I don't think this is reported */ + /* + * fp->mode |= __MODE_ERR; return EOF; + */ + } + } + + /* All done, no problem */ + fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT)); + fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; + return 0; +} +#endif + +#ifdef L_fgets +/* Nothing special here ... */ +char * +fgets(s, count, f) +char *s; +size_t count; +FILE *f; +{ + char *ret; + register size_t i; + register int ch; + + ret = s; + for (i = count; i > 0; i--) + { + ch = getc(f); + if (ch == EOF) + { + if (s == ret) + return 0; + break; + } + *s++ = (char) ch; + if (ch == '\n') + break; + } + *s = 0; + + if (ferror(f)) + return 0; + return ret; +} +#endif + +#ifdef L_gets +char * +gets(str) /* BAD function; DON'T use it! */ +char *str; +{ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register char *p = str; + register int c; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ +} +#endif + +#ifdef L_fputs +int +fputs(str, fp) +char *str; +FILE *fp; +{ + register int n = 0; + while (*str) + { + if (putc(*str++, fp) == EOF) + return (EOF); + ++n; + } + return (n); +} +#endif + +#ifdef L_puts +int +puts(str) +char *str; +{ + register int n; + + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +} +#endif + +#ifdef L_fread +/* + * fread will often be used to read in large chunks of data calling read() + * directly can be a big win in this case. Beware also fgetc calls this + * function to fill the buffer. + * + * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what + * fgetc wants) + */ +int +fread(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + int len, v; + unsigned bytes, got = 0; + Inline_init; + + v = fp->mode; + + /* Want to do this to bring the file pointer up to date */ + if (v & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an EOF or error then return zero */ + if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufread - fp->bufpos; + if (len >= bytes) /* Enough buffered */ + { + memcpy(buf, fp->bufpos, (unsigned) bytes); + fp->bufpos += bytes; + return bytes; + } + else if (len > 0) /* Some buffered */ + { + memcpy(buf, fp->bufpos, len); + got = len; + } + + /* Need more; do it with a direct read */ + len = read(fp->fd, buf + got, (unsigned) (bytes - got)); + + /* Possibly for now _or_ later */ + if (len < 0) + { + fp->mode |= __MODE_ERR; + len = 0; + } + else if (len == 0) + fp->mode |= __MODE_EOF; + + return (got + len) / size; +} +#endif + +#ifdef L_fwrite +/* + * Like fread, fwrite will often be used to write out large chunks of + * data; calling write() directly can be a big win in this case. + * + * But first we check to see if there's space in the buffer. + * + * Again this ignores __MODE__IOTRAN. + */ +int +fwrite(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + register int v; + int len; + unsigned bytes, put; + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return 0; + + /* Can't write or there's been an EOF or error then return 0 */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufend - fp->bufpos; + + /* Flush the buffer if not enough room */ + if (bytes > len) + if (fflush(fp)) + return 0; + + len = fp->bufend - fp->bufpos; + if (bytes <= len) /* It'll fit in the buffer ? */ + { + fp->mode |= __MODE_WRITING; + memcpy(fp->bufpos, buf, bytes); + fp->bufpos += bytes; + + /* If we're not fully buffered */ + if (v & (_IOLBF | _IONBF)) + fflush(fp); + + return nelm; + } + else + /* Too big for the buffer */ + { + put = write(fp->fd, buf, bytes); + if (put < 0) + { + fp->mode |= __MODE_ERR; + put = 0; + } + } + + return put / size; +} +#endif + +#ifdef L_rewind +void +rewind(fp) +FILE * fp; +{ + fseek(fp, (long)0, 0); + clearerr(fp); +} +#endif + +#ifdef L_fseek +int +fseek(fp, offset, ref) +FILE *fp; +long offset; +int ref; +{ + /* Use fflush to sync the pointers */ + /* + * TODO: if __MODE_READING and no ungetc ever done can just move + * pointer + */ + + if (fflush(fp) == EOF) + return EOF; + if (lseek(fp->fd, offset, ref) < 0) + return EOF; + return 0; +} +#endif + +#ifdef L_ftell +long ftell(fp) +FILE * fp; +{ + long rv; + if (fflush(fp) == EOF) + return EOF; + return lseek(fp->fd, 0L, SEEK_CUR); +} +#endif + +#ifdef L_fopen +/* + * This Fopen is all three of fopen, fdopen and freopen. The macros in + * stdio.h show the other names. + */ +FILE * +__fopen(fname, fd, fp, mode) +char *fname; +int fd; +FILE *fp; +char *mode; +{ + int open_mode = 0; +#ifdef __MSDOS__ + int fopen_mode = __MODE_IOTRAN; /* default to 'text' file on DOS */ +#else + int fopen_mode = 0; +#endif + int nfd = -1; + FILE *nfp = 0; + + /* If we've got an fp close the old one (freopen) */ + if (fp) + { + /* Careful, don't de-allocate it */ + fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); + fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); + fclose(fp); + } + + /* decode the new open mode */ + while (*mode) + switch (*mode++) + { + case 'r': + fopen_mode |= __MODE_READ; + break; + case 'w': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_TRUNC); + break; + case 'a': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_APPEND); + break; + case '+': + fopen_mode |= __MODE_RDWR; + break; +#if __MODE_IOTRAN + case 'b': /* Binary */ + fopen_mode &= ~__MODE_IOTRAN; + break; + case 't': /* Text */ + fopen_mode |= __MODE_IOTRAN; + break; +#endif + } + + /* Add in the read/write options to mode for open() */ + switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) + { + case 0: + return 0; + case __MODE_READ: + open_mode |= O_RDONLY; + break; + case __MODE_WRITE: + open_mode |= O_WRONLY; + break; + default: + open_mode |= O_RDWR; + break; + } + + /* Allocate the (FILE) before we do anything irreversable */ + if (fp == 0) + { + nfp = malloc(sizeof(FILE)); + if (nfp == 0) + return 0; + } + + /* Open the file itself */ + if (fname) + nfd = fd = open(fname, open_mode, 0666); + if (fd < 0) /* Grrrr */ + { + if (nfp) + free(nfp); + return 0; + } + + /* If this isn't freopen create a (FILE) and buffer for it */ + if (fp == 0) + { + fp = nfp; + fp->next = __IO_list; + __IO_list = fp; + + fp->mode = __MODE_FREEFIL; + fp->bufstart = malloc(BUFSIZ); + if (fp->bufstart == 0) /* Oops, no mem */ + { /* Humm, full buffering with a two(!) byte + * buffer. */ + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IOFBF; + } + else + { + fp->bufend = fp->bufstart + BUFSIZ; + fp->mode |= (__MODE_FREEBUF | _IOFBF); + } + } + + /* Ok, file's ready clear the buffer and save important bits */ + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fp->mode |= fopen_mode; + fp->fd = fd; + + return fp; +} +#endif + +#ifdef L_fclose +int +fclose(fp) +FILE *fp; +{ + int rv = 0; + + if (fp == 0) + { + errno = EINVAL; + return EOF; + } + if (fflush(fp)) + return EOF; + + if (close(fp->fd)) + rv = EOF; + fp->fd = -1; + + if (fp->mode & __MODE_FREEBUF) + { + free(fp->bufstart); + fp->mode &= ~__MODE_FREEBUF; + fp->bufstart = fp->bufend = 0; + } + + if (fp->mode & __MODE_FREEFIL) + { + FILE *prev = 0, *ptr; + fp->mode = 0; + + for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next) + ; + if (ptr == fp) + { + if (prev == 0) + __IO_list = fp->next; + else + prev->next = fp->next; + } + free(fp); + } + else + fp->mode = 0; + + return rv; +} +#endif + +#ifdef L_setbuffer +void +setbuffer(fp, buf, size) +FILE * fp; +char * buf; +int size; +{ + fflush(fp); + if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart); + fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); + + if( buf == 0 ) + { + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + } + else + { + fp->bufstart = buf; + fp->bufend = buf+size; + fp->mode |= _IOFBF; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; +} +#endif + +#ifdef L_ungetc +int +ungetc(c, fp) +int c; +FILE *fp; +{ + if (fp->mode & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) + return EOF; + + if( fp->bufpos > fp->bufstart ) + return *--fp->bufpos = (unsigned char) c; + else if( fp->bufread == fp->bufstart ) + return *fp->bufread++ = (unsigned char) c; + else + return EOF; +} +#endif + diff --git a/libc-0.0.4/stdio2/stdio.h b/libc-0.0.4/stdio2/stdio.h new file mode 100644 index 0000000..ba70b1d --- /dev/null +++ b/libc-0.0.4/stdio2/stdio.h @@ -0,0 +1,125 @@ + +#ifndef __STDIO_H +#define __STDIO_H + +#include <features.h> +#include <sys/types.h> + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#define _IOFBF 0x00 /* full buffering */ +#define _IOLBF 0x01 /* line buffering */ +#define _IONBF 0x02 /* no buffering */ +#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ + +#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ +#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ + +#define __MODE_READ 0x10 /* Opened in read only */ +#define __MODE_WRITE 0x20 /* Opened in write only */ +#define __MODE_RDWR 0x30 /* Opened in read/write */ + +#define __MODE_READING 0x40 /* Buffer has pending read data */ +#define __MODE_WRITING 0x80 /* Buffer has pending write data */ + +#define __MODE_EOF 0x100 /* EOF status */ +#define __MODE_ERR 0x200 /* Error status */ +#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ + +#ifdef __MSDOS__ +#define __MODE_IOTRAN 0x1000 /* MSDOS nl <-> cr,nl translation */ +#else +#define __MODE_IOTRAN 0 +#endif + +/* when you add or change fields here, be sure to change the initialization + * in stdio_init and fopen */ +struct __stdio_file { + unsigned char *bufpos; /* the next byte to write to or read from */ + unsigned char *bufread; /* the end of data returned by last read() */ + unsigned char *bufwrite; /* highest address writable by macro */ + unsigned char *bufstart; /* the start of the buffer */ + unsigned char *bufend; /* the end of the buffer; ie the byte after the last + malloc()ed byte */ + + int fd; /* the file descriptor associated with the stream */ + int mode; + + char unbuf[8]; /* The buffer for 'unbuffered' streams */ + + struct __stdio_file * next; +}; + +#define EOF (-1) +#ifndef NULL +#define NULL (0) +#endif + +typedef struct __stdio_file FILE; + +#define BUFSIZ (256) + +extern FILE stdin[1]; +extern FILE stdout[1]; +extern FILE stderr[1]; + +#ifdef __MSDOS__ +#define putc(c, fp) fputc(c, fp) +#define getc(fp) fgetc(fp) +#else +#define putc(c, stream) \ + (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream)) \ + : (unsigned char) (*(stream)->bufpos++ = (c)) ) + +#define getc(stream) \ + (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \ + (*(stream)->bufpos++)) +#endif + +#define putchar(c) putc((c), stdout) +#define getchar() getc(stdin) + +#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) +#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) +#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0) +#define fileno(fp) ((fp)->fd) + +/* declare functions; not like it makes much difference without ANSI */ +/* RDB: The return values _are_ important, especially if we ever use + 8086 'large' model + */ + +/* These two call malloc */ +#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) +extern int setvbuf __P((FILE*, char*, int, size_t)); + +/* These don't */ +#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) +extern void setbuffer __P((FILE*, char*, int)); + +extern int fgetc __P((FILE*)); +extern int fputc __P((int, FILE*)); + +extern int fclose __P((FILE*)); +extern int fflush __P((FILE*)); +extern char *fgets __P((char*, size_t, FILE*)); +extern FILE *__fopen __P((char*, int, FILE*, char*)); + +#define fopen(__file, __mode) __fopen((__file), -1, (FILE*)0, (__mode)) +#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode)) +#define fdopen(__file, __mode) __fopen((char*)0, (__file), (FILE*)0, (__mode)) + +extern int fputs __P((char*, FILE*)); +extern int puts __P((char*)); + +extern int printf __P ((__const char*, ...)); +extern int fprintf __P ((FILE*, __const char*, ...)); +extern int sprintf __P ((char*, __const char*, ...)); + +#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos) + +#endif /* __STDIO_H */ diff --git a/libc-0.0.4/string/Config b/libc-0.0.4/string/Config new file mode 100644 index 0000000..b712dcf --- /dev/null +++ b/libc-0.0.4/string/Config @@ -0,0 +1 @@ +string: String and memory manipulation diff --git a/libc-0.0.4/string/Makefile b/libc-0.0.4/string/Makefile new file mode 100644 index 0000000..d9c1f46 --- /dev/null +++ b/libc-0.0.4/string/Makefile @@ -0,0 +1,31 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +SSRC=string.c +SOBJ=strlen.o strcat.o strcpy.o strcmp.o strncat.o strncpy.o strncmp.o \ + strchr.o strrchr.o strdup.o memcpy.o memccpy.o memchr.o memset.o \ + memcmp.o memmove.o movedata.o + +OBJ=$(SOBJ) strpbrk.o strsep.o strstr.o strtok.o strcspn.o \ + strspn.o strcasecmp.o strncasecmp.o + +all: $(OBJ) + +$(LIBC): $(OBJ) + ar r ../$(LIBC) $(OBJ) + @touch libc.a + +transfer: + -@rm -f ../include/string.h + cp -p string.h ../include/. + +clean: + rm -f $(OBJ) libc.a + +$(SOBJ): $(SSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(SSRC) + diff --git a/libc-0.0.4/string/strcasecmp.c b/libc-0.0.4/string/strcasecmp.c new file mode 100644 index 0000000..0e7b038 --- /dev/null +++ b/libc-0.0.4/string/strcasecmp.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <ctype.h> + +int +strcasecmp(s, d) +char *s; +char *d; +{ + for(;;) + { + if( *s != *d ) + { + if( tolower(*s) != tolower(*d) ) + return *s - *d; + } + else if( *s == '\0' ) break; + s++; d++; + } + return 0; +} + diff --git a/libc-0.0.4/string/strcspn.c b/libc-0.0.4/string/strcspn.c new file mode 100644 index 0000000..619c8be --- /dev/null +++ b/libc-0.0.4/string/strcspn.c @@ -0,0 +1,32 @@ +/* strcspn.c */ + +/* from Schumacher's Atari library, improved */ + +#include <string.h> + +size_t strcspn(string, set) +register char *string; +char *set; +/* + * Return the length of the sub-string of <string> that consists + * entirely of characters not found in <set>. The terminating '\0' + * in <set> is not considered part of the match set. If the first + * character if <string> is in <set>, 0 is returned. + */ +{ + register char *setptr; + char *start; + + start = string; + while (*string) + { + setptr = set; + do + if (*setptr == *string) + goto break2; + while (*setptr++); + ++string; + } +break2: + return string - start; +} diff --git a/libc-0.0.4/string/string.c b/libc-0.0.4/string/string.c new file mode 100644 index 0000000..fad6690 --- /dev/null +++ b/libc-0.0.4/string/string.c @@ -0,0 +1,667 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <malloc.h> + +#ifdef __AS386_16__ +#if __FIRST_ARG_IN_AX__ +#define BCC_AX_ASM /* BCC Assembler that can cope with arg in AX */ +#else +#define BCC_AX_ASM +#define BCC_ASM /* Use 16 bit BCC assembler */ +#endif + +#define PARANOID /* Include extra code for cld and ES register */ +#endif + +/* This is a basic string package; it includes the most used functions + + strlen strcat strcpy strcmp strncat strncpy strncmp strchr strrchr strdup + memcpy memccpy memchr memset memcmp memmove + + These functions are in seperate files. + strpbrk.o strsep.o strstr.o strtok.o strcspn.o + strspn.o strcasecmp.o strncasecmp.o + */ + +/********************** Function strlen ************************************/ + +#ifdef L_strlen +size_t strlen(str) +const char * str; +{ +#ifdef BCC_AX_ASM +#asm +#if !__FIRST_ARG_IN_AX__ + mov bx,sp +#endif + push di + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif ! This is almost the same as memchr, but it can + ! stay as a special. + +#if __FIRST_ARG_IN_AX__ + mov di,ax +#else + mov di,[bx+2] +#endif + mov cx,#-1 + xor ax,ax + repne + scasb + not cx + dec cx + mov ax,cx + +#ifdef PARANOID + pop es +#endif + pop di +#endasm +#else + register char * p =(char *) str; + while(*p) p++; + return p-str; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function strcat ************************************/ + +#ifdef L_strcat +char * strcat(d, s) +char *d; +const char * s; +{ + (void) strcpy(d+strlen(d), s); + return d; +} +#endif + +/********************** Function strcpy ************************************/ + +#ifdef L_strcpy +char * strcpy(d, s) +char *d; +const char * s; +{ + /* This is probably the quickest on an 8086 but a CPU with a cache will + * prefer to do this in one pass */ + return memcpy(d, s, strlen(s)+1); +} +#endif + +/********************** Function strcmp ************************************/ + +#ifdef L_strcmp +int strcmp(d, s) +const char *d; +const char * s; +{ + /* There are a number of ways to do this and it really does depend on the + types of strings given as to which is better, nevertheless the Glib + method is quite reasonable so we'll take that */ + +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push di + push si + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es +#endif + +#if __FIRST_ARG_IN_AX__ + mov di,ax ; dest + mov si,[bx+2] ; source +#else + mov di,[bx+2] ; dest + mov si,[bx+4] ; source +#endif +sc_1: + lodsb + scasb + jne sc_2 ; If bytes are diff skip out. + testb al,al + jne sc_1 ; If this byte in str1 is nul the strings are equal + xor ax,ax ; so return zero + jmp sc_3 +sc_2: + sbb ax,ax ; Collect correct val (-1,1). + orb al,#1 +sc_3: + +#ifdef PARANOID + pop es +#endif + pop si + pop di +#endasm +#else /* ifdef BCC_AX_ASM */ + register char *s1=(char *)d, *s2=(char *)s, c1,c2; + while((c1= *s1++) == (c2= *s2++) && c1 ); + return c1 - c2; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function strncat ************************************/ + +#ifdef L_strncat +char * strncat(d, s, l) +char *d, *s; +size_t l; +{ + register char *s1=d+strlen(d), *s2; + + s2 = memchr(s, l, 0); + if( s2 ) + memcpy(s1, s, s2-s+1); + else + { + memcpy(s1, s, l); + s1[l] = '\0'; + } + return d; +} +#endif + +/********************** Function strncpy ************************************/ + +#ifdef L_strncpy +char * strncpy(d, s, l) /* FIXME need the fast version of this */ +char *d, *s; +size_t l; +{ + register char *s1=d, *s2=s; + while(l > 0) + { + l--; + if( (*s1++ = *s2++) == '\0') + break; + } + + /* This _is_ correct strncpy is supposed to zap */ + for(; l>0; l--) *s1++ = '\0'; + return d; +} +#endif + +/********************** Function strncmp ************************************/ + +#ifdef L_strncmp +int strncmp(d, s, l) +const char *d, *s; +size_t l; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push si + push di + +#ifdef PARANOID + push es + push ds ! Im not sure if this is needed, so just in case. + pop es + cld +#endif + +#if __FIRST_ARG_IN_AX__ + mov si,ax + mov di,[bx+2] + mov cx,[bx+4] +#else + mov si,[bx+2] ! Fetch + mov di,[bx+4] + mov cx,[bx+6] +#endif + + inc cx +lp1: + dec cx + je lp2 + lodsb + scasb + jne lp3 + testb al,al + jne lp1 +lp2: + xor ax,ax + jmp lp4 +lp3: + sbb ax,ax + or al,#1 +lp4: + +#ifdef PARANOID + pop es +#endif + pop di + pop si +#endasm +#else + register char c1=0, c2=0; + while(l-- >0) + if( (c1= *d++) != (c2= *s++) || c1 == '\0' ) + break; + return c1-c2; +#endif +} +#endif + +/********************** Function strchr ************************************/ + +#ifdef L_strchr +char * +strchr(s, c) +char * s; +int c; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push si +#if __FIRST_ARG_IN_AX__ + mov bx,[bx+2] + mov si,ax +#else + mov si,[bx+2] + mov bx,[bx+4] +#endif + xor ax,ax + +#ifdef PARANOID + cld +#endif + +in_loop: + lodsb + cmp al,bl + jz got_it + or al,al + jnz in_loop + pop si + ret +got_it: + lea ax,[si-1] + pop si + +#endasm +#else /* ifdef BCC_AX_ASM */ + register char ch; + for(;;) + { + if( (ch= *s) == c ) return s; + if( ch == 0 ) return 0; + s++; + } +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function strrchr ************************************/ + +#ifdef L_strrchr +char * strrchr(s, c) +char * s; +int c; +{ + register char * prev = 0; + register char * p = s; + /* For null it's just like strlen */ + if( c == '\0' ) return p+strlen(p); + + /* everything else just step along the string. */ + while( (p=strchr(p, c)) != 0 ) + { + prev = p; p++; + } + return prev; +} +#endif + +/********************** Function strdup ************************************/ + +#ifdef L_strdup +char * strdup(s) +char * s; +{ + register size_t len; + register char * p; + + len = strlen(s)+1; + p = (char *) malloc(s); + if(p) memcpy(p, s, len); /* Faster than strcpy */ + return p; +} +#endif + +/********************** Function memcpy ************************************/ + +#ifdef L_memcpy +void * +memcpy(d, s, l) +void *d; +const void *s; +size_t l; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push di + push si + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es +#endif + +#if __FIRST_ARG_IN_AX__ + mov di,ax ; dest + mov si,[bx+2] ; source + mov cx,[bx+4] ; count +#else + mov di,[bx+2] ; dest + mov si,[bx+4] ; source + mov cx,[bx+6] ; count + + mov ax,di +#endif + ; If di is odd mov 1 byte before doing word move + ; this will speed slightly but + ; NB 8086 has no problem with mis-aligned access. + + shr cx,#1 ; Do this faster by doing a mov word + rep + movsw + adc cx,cx ; Retrieve the leftover 1 bit from cflag. + rep + movsb + +#ifdef PARANOID + pop es +#endif + pop si + pop di +#endasm +#else /* ifdef BCC_AX_ASM */ + register char *s1=d, *s2=(char *)s; + for( ; l>0; l--) *((unsigned char*)s1++) = *((unsigned char*)s2++); + return d; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function memccpy ************************************/ + +#ifdef L_memccpy +void * memccpy(d, s, c, l) /* Do we need a fast one ? */ +void *s, *d; +int c; +size_t l; +{ + register char *s1=d, *s2=s; + while(l-- > 0) + if((*s1++ = *s2++) == c ) + return s1; + return 0; +} +#endif + +/********************** Function memchr ************************************/ + +#ifdef L_memchr +void * memchr(str, c, l) +const void * str; +int c; +size_t l; +{ +#ifdef BCC_ASM +#asm + mov bx,sp + push di + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif + + mov di,[bx+2] + mov ax,[bx+4] + mov cx,[bx+6] + test cx,cx + je is_z ! Zero length, do not find. + + repne ! Scan + scasb + jne is_z ! Not found, ret zero + dec di ! Adjust ptr + mov ax,di ! return + jmp xit +is_z: + xor ax,ax +xit: + +#ifdef PARANOID + pop es +#endif + pop di +#endasm +#else /* ifdef BCC_ASM */ + register char *p=(char *)str; + while(l-- > 0) + { + if(*p == c) return p; + p++; + } + return 0; +#endif /* ifdef BCC_ASM */ +} +#endif + +/********************** Function memset ************************************/ + +#ifdef L_memset +void * memset(str, c, l) +void * str; +int c; +size_t l; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push di + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif + +#if __FIRST_ARG_IN_AX__ + mov di,ax ; Fetch + mov ax,[bx+2] + mov cx,[bx+4] +#else + mov di,[bx+2] ; Fetch + mov ax,[bx+4] + mov cx,[bx+6] +#endif + +; How much difference does this alignment make ? +; I don`t think it`s significant cause most will already be aligned. + +; test cx,cx ; Zero size - skip +; je xit +; +; test di,#1 ; Line it up +; je s_1 +; stosb +; dec cx +;s_1: + + mov ah,al ; Replicate byte + shr cx,#1 ; Do this faster by doing a sto word + rep ; Bzzzzz ... + stosw + adc cx,cx ; Retrieve the leftover 1 bit from cflag. + + rep ; ... z + stosb + +xit: + mov ax,[bx+2] +#ifdef PARANOID + pop es +#endif + pop di +#endasm +#else /* ifdef BCC_AX_ASM */ + register char *s1=str; + while(l-->0) *s1++ = c; + return str; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function memcmp ************************************/ + +#ifdef L_memcmp +int memcmp(s, d, l) +const void *s, *d; +size_t l; +{ +#ifdef BCC_ASM +#asm + mov bx,sp + push di + push si + +#ifdef PARANOID + push es + push ds ! Im not sure if this is needed, so just in case. + pop es + cld +#endif + + mov si,[bx+2] ! Fetch + mov di,[bx+4] + mov cx,[bx+6] + xor ax,ax + + rep ! Bzzzzz + cmpsb + je xit ! All the same! + sbb ax,ax + sbb ax,#-1 ! choose +/-1 +xit: +#ifdef PARANOID + pop es +#endif + pop si + pop di +#endasm +#else /* ifdef BCC_ASM */ + register const char *s1=d, *s2=s; + register char c1=0, c2=0; + while(l-- > 0) + if( (c1= *s1++) != (c2= *s2++) ) + break; + return c1-c2; +#endif /* ifdef BCC_ASM */ +} +#endif + +/********************** Function memmove ************************************/ + +#ifdef L_memmove +void * +memmove(d, s, l) +void *d, *s; +size_t l; +{ + register char *s1=d, *s2=s; + /* This bit of sneakyness c/o Glibc, it assumes the test is unsigned */ + if( s1-s2 >= l ) return memcpy(d,s,l); + + /* This reverse copy only used if we absolutly have to */ + s1+=l; s2+=l; + while(l-- >0) + *(--s1) = *(--s2); + return d; +} +#endif + +/********************** Function movedata ***********************************/ + +#ifdef L_movedata + +/* NB There isn't any C version of this function ... */ + +#ifdef BCC_AX_ASM +void +__movedata(srcseg, srcoff, destseg, destoff, len) +unsigned int srcseg, srcoff, destseg, destoff, len; +{ +#asm + push bp + mov bp,sp + push si + push di + push ds +#ifdef PARANOID + push es + cld +#endif + + ! sei ! Are we _really_ paranoid ? + +#if !__FIRST_ARG_IN_AX__ + mov ds,[bp+4] ! Careful, [bp+xx] is SS based. + mov si,[bp+6] + mov es,[bp+8] + mov di,[bp+10] + mov cx,[bp+12] +#else + mov ds,ax + mov si,[bp+4] + mov es,[bp+6] + mov di,[bp+8] + mov cx,[bp+10] +#endif + rep + movsb + + ! cli ! Are we _really_ paranoid ? + +#ifdef PARANOID + pop es +#endif + pop ds + pop di + pop si + pop bp +#endasm +} +#endif + +#endif + +/********************** THE END ********************************************/ + diff --git a/libc-0.0.4/string/string.h b/libc-0.0.4/string/string.h new file mode 100644 index 0000000..8be8eff --- /dev/null +++ b/libc-0.0.4/string/string.h @@ -0,0 +1,52 @@ + +#ifndef __STRING_H +#define __STRING_H +#include <features.h> +#include <stddef.h> + +/* Basic string functions */ +extern size_t strlen __P ((__const char* __str)); + +extern char * strcat __P ((char*, __const char*)); +extern char * strcpy __P ((char*, __const char*)); +extern int strcmp __P ((__const char*, __const char*)); + +extern char * strncat __P ((char*, char*, size_t)); +extern char * strncpy __P ((char*, char*, size_t)); +extern int strncmp __P ((__const char*, __const char*, size_t)); + +extern char * strchr __P ((char*, int)); +extern char * strrchr __P ((char*, int)); +extern char * strdup __P ((char*)); + +/* Basic mem functions */ +extern void * memcpy __P ((void*, __const void*, size_t)); +extern void * memccpy __P ((void*, void*, int, size_t)); +extern void * memchr __P ((__const void*, __const int, size_t)); +extern void * memset __P ((void*, int, size_t)); +extern int memcmp __P ((__const void*, __const void*, size_t)); + +extern void * memmove __P ((void*, void*, size_t)); + +/* Minimal (very!) locale support */ +#define strcoll strcmp +#define strxfrm strncpy + +/* BSDisms */ +#define index strchr +#define rindex strrchr + +/* Other common BSD functions */ +extern int strcasecmp __P ((char*, char*)); +extern int strncasecmp __P ((char*, char*, size_t)); +char *strpbrk __P ((char *, char *)); +char *strsep __P ((char **, char *)); +char *strstr __P ((char *, char *)); +char *strtok __P ((char *, char *)); +size_t strcspn __P ((char *, char *)); +size_t strspn __P ((char *, char *)); + +/* Linux silly hour */ +char *strfry __P ((char *)); + +#endif diff --git a/libc-0.0.4/string/strncasecmp.c b/libc-0.0.4/string/strncasecmp.c new file mode 100644 index 0000000..561f72a --- /dev/null +++ b/libc-0.0.4/string/strncasecmp.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <ctype.h> + +int +strncasecmp(s, d, l) +char *s; +char *d; +size_t l; +{ + while(l>0) + { + if( *s != *d ) + { + if( tolower(*s) != tolower(*d) ) + return *s - *d; + } + else + if( *s == '\0' ) return 0; + s++; d++; l--; + } + return 0; +} + diff --git a/libc-0.0.4/string/strpbrk.c b/libc-0.0.4/string/strpbrk.c new file mode 100644 index 0000000..3fc27ec --- /dev/null +++ b/libc-0.0.4/string/strpbrk.c @@ -0,0 +1,21 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> + +/* This uses strchr, strchr should be in assembler */ + +char *strpbrk(str, set) +register char *str; +char *set; +{ + while (*str != '\0') + if (strchr(set, *str) == 0) + ++str; + else + return (char *) str; + + return 0; +} diff --git a/bin86-0.3/as/det_endian.c b/libc-0.0.4/string/strsep.c index 50b5bdc..21aa1bb 100644 --- a/bin86-0.3/as/det_endian.c +++ b/libc-0.0.4/string/strsep.c @@ -1,6 +1,5 @@ -/* Determine the "endianness" of the CPU. - Copyright (C) 1991, 1992 Free Software Foundation, Inc. - Contributed by Torbjorn Granlund (tege@sics.se). +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -17,18 +16,23 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <stdio.h> +#include <string.h> -main () +char * +strsep(pp, delim) +char **pp; +char *delim; { - unsigned long int i; - - if (sizeof (i) != 4) - puts ("#error \"Not a 32-bit machine!\""); - - i = (((((('4' << 8) + '3') << 8) + '2') << 8) + '1'); - - printf ("#define __BYTE_ORDER %.4s\n", (char *) &i); - - exit (0); + char *p, *q; + + if (!(p = *pp)) + return 0; + if (q = strpbrk (p, delim)) + { + *pp = q + 1; + *q = '\0'; + } + else + *pp = 0; + return p; } diff --git a/libc-0.0.4/string/strspn.c b/libc-0.0.4/string/strspn.c new file mode 100644 index 0000000..2094caa --- /dev/null +++ b/libc-0.0.4/string/strspn.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Return the length of the maximum initial segment + of S which contains only characters in ACCEPT. */ +size_t +strspn(s, accept) +char *s; +char *accept; +{ + register char *p; + register char *a; + register size_t count = 0; + + for (p = s; *p != '\0'; ++p) + { + for (a = accept; *a != '\0'; ++a) + if (*p == *a) + break; + if (*a == '\0') + return count; + else + ++count; + } + + return count; +} diff --git a/libc-0.0.4/string/strstr.c b/libc-0.0.4/string/strstr.c new file mode 100644 index 0000000..aafcaf9 --- /dev/null +++ b/libc-0.0.4/string/strstr.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> + +#if 1 +/* We've now got a nice fast strchr and memcmp use them */ + +char * +strstr(s1, s2) +char *s1; char *s2; +{ + register int l = strlen(s2); + register char * p = s1; + + if( l==0 ) return p; + + while (p = strchr(p, *s2)) + { + if( memcmp(p, s2, l) == 0 ) + return p; + p++; + } + return (char *) 0; +} + +#else +/* This is a nice simple self contained strstr, + now go and work out why the GNU one is faster :-) */ + +char *strstr(str1, str2) +char *str1, *str2; +{ + register char *Sptr, *Tptr; + int len = strlen(str1) -strlen(str2) + 1; + + if (*str2) + for (; len > 0; len--, str1++){ + if (*str1 != *str2) + continue; + + for (Sptr = str1, Tptr = str2; *Tptr != '\0'; Sptr++, Tptr++) + if (*Sptr != *Tptr) + break; + + if (*Tptr == '\0') + return (char*) str1; + } + + return (char*)0; +} +#endif diff --git a/libc-0.0.4/string/strtok.c b/libc-0.0.4/string/strtok.c new file mode 100644 index 0000000..27d8f25 --- /dev/null +++ b/libc-0.0.4/string/strtok.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + + +static char *olds = 0; + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the last string strtok() was called with is + used. For example: + char s[] = "-abc=-def"; + x = strtok(s, "-"); // x = "abc" + x = strtok(NULL, "=-"); // x = "def" + x = strtok(NULL, "="); // x = NULL + // s = "abc\0-def\0" +*/ +char * +strtok(s, delim) +register char *s; +register char *delim; +{ + char *token; + + if (s == 0) + { + if (olds == 0) + { + return 0; + } + else + s = olds; + } + + /* Scan leading delimiters. */ + s += strspn(s, delim); + if (*s == '\0') + { + olds = 0; + return 0; + } + + /* Find the end of the token. */ + token = s; + s = strpbrk(token, delim); + if (s == 0) + /* This token finishes the string. */ + olds = 0; + else + { + /* Terminate the token and make OLDS point past it. */ + *s = '\0'; + olds = s + 1; + } + return token; +} diff --git a/libc-0.0.4/syscall/Config b/libc-0.0.4/syscall/Config new file mode 100644 index 0000000..472e74b --- /dev/null +++ b/libc-0.0.4/syscall/Config @@ -0,0 +1 @@ +syscall: Linux-8086 system call routines diff --git a/libc-0.0.4/syscall/Makefile b/libc-0.0.4/syscall/Makefile new file mode 100644 index 0000000..6a2b9bb --- /dev/null +++ b/libc-0.0.4/syscall/Makefile @@ -0,0 +1,45 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +LSRC=syslibc.c +LOBJ=__cstartup.o time.o lseek.o getpid.o getppid.o \ + getuid.o geteuid.o getgid.o getegid.o \ + dup2.o dup.o abort.o wait.o waitpid.o sleep.o + +ESRC=execve.c +EOBJ=execve.o execl.o execv.o execle.o + +DSRC=dirent.c +DOBJ=opendir.o closedir.o readdir.o + +OBJ=$(LOBJ) $(DOBJ) $(EOBJ) signal.o setjmp.o execve.o + +all: mksyscall syscall.dat $(OBJ) + sh mksyscall + +clean: + sh mksyscall clean + rm -f libc.a syscall.c syscall.mak call_tab.v defn_tab.v $(OBJ) + +libdos.a: setjmp.o + ar r ../libc.a setjmp.o + @touch libc.a + +libc.a: mksyscall syscall.dat $(OBJ) + sh mksyscall libc.a + ar r ../libc.a $(OBJ) + @touch libc.a + +$(LOBJ): $(LSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(LSRC) + +$(DOBJ): $(DSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(DSRC) + +$(EOBJ): $(ESRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(ESRC) + diff --git a/libc-0.0.4/syscall/TODO b/libc-0.0.4/syscall/TODO new file mode 100644 index 0000000..90085d9 --- /dev/null +++ b/libc-0.0.4/syscall/TODO @@ -0,0 +1,7 @@ +It appears that a 386 version of the syscall libs is also wanted ... + +SYSV IPC, there's and __ipc syscall and the hardware can manage messages and +semaphores. + +Idea, for RPC syscall, seperate all the FD related calls from the system ones +IIRC all the single FD related ones have the FD in arg0 diff --git a/libc-0.0.4/syscall/dirent.c b/libc-0.0.4/syscall/dirent.c new file mode 100644 index 0000000..c484956 --- /dev/null +++ b/libc-0.0.4/syscall/dirent.c @@ -0,0 +1,84 @@ + +#include <errno.h> +#include <sys/types.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <dirent.h> +#include <malloc.h> + +#ifdef L_opendir +DIR * +opendir(dname) +char *dname; +{ + struct stat st; + int fd; + DIR *p; + + if (stat(dname, &st) < 0) + return 0; + + if (!S_ISDIR(st.st_mode)) + { + errno = ENOTDIR; + return 0; + } + if ((fd = open(dname, O_RDONLY)) < 0) + return 0; + + p = malloc(sizeof(DIR)); + if (p == 0) + { + close(fd); + return 0; + } + + p->dd_buf = malloc(sizeof(struct dirent)); + if (p->dd_buf == 0) + { + free(p); + close(fd); + return 0; + } + p->dd_fd = fd; + p->dd_loc = p->dd_size = 0; + + return p; +} +#endif + +#ifdef L_closedir +int +closedir(dirp) +DIR *dirp; +{ + int fd; + fd = dirp->dd_fd; + free(dirp->dd_buf); + free(dirp); + return close(fd); +} +#endif + +#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 diff --git a/libc-0.0.4/syscall/execve.c b/libc-0.0.4/syscall/execve.c new file mode 100644 index 0000000..aee7182 --- /dev/null +++ b/libc-0.0.4/syscall/execve.c @@ -0,0 +1,114 @@ + +#include <errno.h> + +extern char ** environ; + +#ifdef L_execl +int +execl(fname, arg0) +char * fname, *arg0; +{ + return execve(fname, &arg0, environ); +} +#endif + +#ifdef L_execv +int +execv(fname, argv) +char * fname, **argv; +{ + return execve(fname, argv, environ); +} +#endif + +#ifdef L_execle +int +execle(fname, arg0) +char *fname, *arg0; +{ + char ** envp = &arg0; + while(*envp) envp++; + return execve(fname, &arg0, envp+1); +} +#endif + +#ifdef L_execve +int +execve(fname, argv, envp) +char * fname; +char ** argv; +char ** envp; +{ + char **p; + int argv_len=0, argv_count=0; + int envp_len=0, envp_count=0; + int stack_bytes; + unsigned short * pip; + char * pcp, * stk_ptr, *baseoff; + int rv; + + /* How much space for argv */ + for(p=argv; p && *p && argv_len >= 0; p++) + { + argv_count++; argv_len += strlen(*p)+1; + } + + /* How much space for envp */ + for(p=envp; p && *p && envp_len >= 0; p++) + { + envp_count++; envp_len += strlen(*p)+1; + } + + /* tot it all up */ + stack_bytes = 2 /* argc */ + + argv_count * 2 + 2 /* argv */ + + argv_len + + envp_count * 2 + 2 /* envp */ + + envp_len; + + /* Allocate it */ + if( argv_len < 0 || envp_len < 0 || stack_bytes <= 0 + || (int)(stk_ptr = (char*)sbrk(stack_bytes)) == -1) + { + errno = ENOMEM; + return -1; + } + +/* Sanity check + printf("Argv = (%d,%d), Envp=(%d,%d), stack=%d\n", + argv_count, argv_len, envp_count, envp_len, stack_bytes); +*/ + + /* Now copy in the strings */ + pip=(unsigned short *) stk_ptr; + pcp=stk_ptr+2*(1+argv_count+1+envp_count+1); + + /* baseoff = stk_ptr + stack_bytes; */ + baseoff = stk_ptr; + *pip++ = argv_count; + for(p=argv; p && *p; p++) + { + int l; + *pip++ = pcp-baseoff; + l = strlen(*p)+1; + memcpy(pcp, *p, l); + pcp += l; + } + *pip++ = 0; + + for(p=envp; p && *p; p++) + { + int l; + *pip++ = pcp-baseoff; + l = strlen(*p)+1; + memcpy(pcp, *p, l); + pcp += l; + } + *pip++ = 0; + + rv = __exec(fname, stk_ptr, stack_bytes); + /* FIXME: This will probably have to interpret '#!' style exe's */ + sbrk(-stack_bytes); + return rv; +} +#endif diff --git a/libc-0.0.4/syscall/getinfo.c b/libc-0.0.4/syscall/getinfo.c new file mode 100644 index 0000000..a5ab89a --- /dev/null +++ b/libc-0.0.4/syscall/getinfo.c @@ -0,0 +1,32 @@ + +#define PERM_GETINFO 0x100 +#define PERM_GETGROUP 0x200 + +struct { + int pid; + int ppid; + int uid; + int gid; + int euid; + int egid; +} + __info_safe; + +getgroups(count, locn) +int count; +void * locn; +{ + if( count < 0 ) {errno = EINVAL; return -1; } + return __permissions(PERM_GETGROUP, count, locn); +} + +getpid() +{ + __permissions(PERM_GETINFO, 6, &__info_safe); + return __info_safe.pid; +} + +getppid() +{ + return __permissions(PERM_GETITEM(1) /*, 0, 0 */); +} diff --git a/libc-0.0.4/syscall/mksyscall b/libc-0.0.4/syscall/mksyscall new file mode 100644 index 0000000..1d2b27e --- /dev/null +++ b/libc-0.0.4/syscall/mksyscall @@ -0,0 +1,303 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. +# +# This script generates the 'simple' system calls. +# +# Each call is put into it's own object file, if the semantics of the +# call are not correct UNIX then the 4th field in the dat file has a +# marker and the function is generated with a __ prefix. +# +# +# Different levels of squeeze +# 0 = each is complete +# 1 = Short codes calling common function + +COMPACT=1 + +rm -f syscall.c syscall.mak call_tab.v defn_tab.v + +tr '[A-Z]' '[a-z]' < syscall.dat | \ +awk -v COMPACT=$COMPACT 'BEGIN{ + print "# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>" > "syscall.mak"; + print "# This file is part of the Linux-8086 C library and is distributed" > "syscall.mak"; + print "# under the GNU Library General Public License." > "syscall.mak"; + print "# " > "syscall.mak"; + print "# This file is automatically generated\n" > "syscall.mak" + + print "/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>"; + print " * This file is part of the Linux-8086 C library and is distributed"; + print " * under the GNU Library General Public License."; + print " * "; + print " * This file is automatically generated */\n" + obj="OBJ="; + + print "/* Standard start */\n\n" + printf("#ifndef __MSDOS__\n"); + printf("#ifdef __AS386_16__\n"); + printf("#asm\n"); + printf(" .text\n"); + printf(" .even\n"); + printf("#endasm\n\n"); + + { + obj=obj "__syscall.o __syscall4.o "; + print "/* Shared system call code */\n" + printf("#ifdef L___syscall\n", funcname); + printf("#asm\n"); + printf("#if __FIRST_ARG_IN_AX__\n"); + + printf("export sys_call3\nsys_call3:\n"); + printf(" mov bx,sp\n"); + printf(" mov cx,[bx+2]\n"); + printf(" mov bx,[bx+4]\n"); + # ax=arg1 bx=arg3 cx=arg2 dx=arg0 + printf(" xchg ax,bx\n"); + # ax=arg3 bx=arg1 cx=arg2 dx=arg0 + printf(" xchg ax,dx\n"); + # ax=arg0 bx=arg1 cx=arg2 dx=arg3 + printf(" jmp sys_call0\n\n"); + + printf("export sys_call2\nsys_call2:\n"); + printf(" mov bx,sp\n"); + printf(" mov cx,[bx+2]\n"); + printf(" mov bx,ax\n"); + printf(" mov ax,dx\n"); + printf(" jmp sys_call0\n\n"); + + printf("export sys_call1\nsys_call1:\n"); + printf(" mov bx,ax\n"); + printf(" mov ax,dx\n"); + printf("#else\n"); + printf("export sys_call3\nsys_call3:\n"); + printf(" mov bx,sp\n"); + printf(" mov dx,[bx+6]\n"); + printf(" mov cx,[bx+4]\n"); + printf(" mov bx,[bx+2]\n"); + printf(" jmp sys_call0\n\n"); + + printf("export sys_call2\nsys_call2:\n"); + printf(" mov bx,sp\n"); + printf(" mov cx,[bx+4]\n"); + printf(" mov bx,[bx+2]\n"); + printf(" jmp sys_call0\n\n"); + + printf("export sys_call1\nsys_call1:\n"); + printf(" mov bx,sp\n"); + printf(" mov bx,[bx+2]\n"); + printf("#endif\n\n"); + + printf("export sys_call0\nsys_call0:\n"); + printf(" int $80\n"); + printf(" test ax,ax\n"); + printf(" jge syscall_ok\n"); + printf(" neg ax\n"); + printf(" mov [_errno],ax\n"); + printf(" mov ax,#-1\n"); + printf("syscall_ok:\n"); + printf(" ret\n"); + printf("#endasm\n"); + printf("#endif\n\n"); + + print "/* Shared system call code, syscalls with 4/5 args */\n" + printf("#ifdef L___syscall4\n", funcname); + printf("#asm\n"); + printf("#if __FIRST_ARG_IN_AX__\n"); + + printf("export sys_call4\nsys_call4:\n"); + printf("export sys_call5\nsys_call5:\n"); + printf(" mov bx,sp\n"); + printf(" push si\n"); + printf(" mov si,[bx+8]\n"); + printf(" push di\n"); + printf(" mov di,[bx+6]\n"); + printf(" mov cx,[bx+2]\n"); + printf(" mov bx,[bx+4]\n"); + # ax=arg1 bx=arg3 cx=arg2 dx=arg0 + printf(" xchg ax,bx\n"); + # ax=arg3 bx=arg1 cx=arg2 dx=arg0 + printf(" xchg ax,dx\n"); + # ax=arg0 bx=arg1 cx=arg2 dx=arg3 + printf("#else\n"); + printf("export sys_call4\nsys_call4:\n"); + printf("export sys_call5\nsys_call5:\n"); + printf(" mov bx,sp\n"); + printf(" push si\n"); + printf(" mov si,[bx+10]\n"); + printf(" push di\n"); + printf(" mov di,[bx+8]\n"); + printf(" mov dx,[bx+6]\n"); + printf(" mov cx,[bx+4]\n"); + printf(" mov bx,[bx+2]\n"); + printf("#endif\n\n"); + + printf(" int $80\n"); + printf(" pop di\n"); + printf(" pop si\n"); + printf(" test ax,ax\n"); + printf(" jge syscall_ok\n"); + printf(" neg ax\n"); + printf(" mov [_errno],ax\n"); + printf(" mov ax,#-1\n"); + printf("syscall_ok:\n"); + printf(" ret\n"); + printf("#endasm\n"); + printf("#endif\n\n"); + } +} +/^[ ]*#/ { next; } +/^[ ]*$/ { next; } +{ + if( $2 > max_call ) max_call = $2; + if( !($2 in calltab) ) + callwas[$2] = " /* " $1 " */"; + + if( $3 == "x" || $3 == "" ) next; + else if( $4 == "-" ) next; + else if( $4 == "*" ) funcname="__" $1; + else funcname=$1; + + calltab[$2] = $1; + + if( length(obj) > 60 ) + { + printf("%s\t\\\n", obj) > "syscall.mak"; + obj=" "; + } + obj=obj funcname ".o "; + + printf "/* CALL %s */\n\n", $0; + + printf("#ifdef L_%s\n", funcname); + printf("#asm\n", funcname); + printf("export _%s\n", funcname); + printf("_%s:\n", funcname); + + # Inline assembler max to 5 args (10 bytes) + if( $3 != 4 && $3 != 5 && ( COMPACT || $3 > 5 )) + { + if( $3 == 0 ) + { + printf(" mov ax,#%d\n", $2); + } + else + { + printf("#if __FIRST_ARG_IN_AX__\n"); + printf(" mov dx,#%d\n", $2); + printf("#else\n"); + printf(" mov ax,#%d\n", $2); + printf("#endif\n"); + } + printf(" br sys_call%d\n", $3); + } + else + { + if( $3 >= 1 ) + printf("#if __FIRST_ARG_IN_AX__\n"); + if( $3 >= 2 ) + printf(" mov bx,sp\n"); + if( $3 >= 5 ) + printf(" push si\n"); + if( $3 >= 5 ) + printf(" mov si,[bx+8]\n"); + if( $3 >= 4 ) + printf(" push di\n"); + if( $3 >= 4 ) + printf(" mov di,[bx+6]\n"); + if( $3 >= 3 ) + printf(" mov dx,[bx+4]\n"); + if( $3 >= 2 ) + printf(" mov cx,[bx+2]\n"); + if( $3 >= 1 ) + printf(" mov bx,ax\n"); + if( $3 >= 1 ) + printf("#else\n"); + if( $3 >= 1 ) + printf(" mov bx,sp\n"); + if( $3 >= 5 ) + printf(" push si\n"); + if( $3 >= 5 ) + printf(" mov si,[bx+10]\n"); + if( $3 >= 4 ) + printf(" push di\n"); + if( $3 >= 4 ) + printf(" mov di,[bx+8]\n"); + if( $3 >= 3 ) + printf(" mov dx,[bx+6]\n"); + if( $3 >= 2 ) + printf(" mov cx,[bx+4]\n"); + if( $3 >= 1 ) + printf(" mov bx,[bx+2]\n"); + if( $3 >= 1 ) + printf("#endif\n"); + + printf(" mov ax,#%d\n", $2); + + printf(" int $80\n"); + + if( $3 >= 4 ) + printf(" pop di\n"); + if( $3 >= 5 ) + printf(" pop si\n"); + + printf(" test ax,ax\n"); + printf(" jl syscall_err\n"); + printf(" ret\n"); + printf("syscall_err:\n"); + printf(" neg ax\n"); + printf(" mov [_errno],ax\n"); + printf(" mov ax,#-1\n"); + printf(" ret\n"); + } + printf("#endasm\n"); + printf("#endif\n\n"); +} +END{ + + for(i=0; i<=max_call; i++) + if( i in calltab ) + { + printf("#ifndef sys_%s\n", calltab[i]) > "defn_tab.v"; + printf("#define sys_%s sys_enosys\n", calltab[i]) > "defn_tab.v"; + printf("#endif\n\n") > "defn_tab.v"; + } + + for(i=0; i<=max_call; i++) + if( i in calltab ) + printf("/* %3d */ sys_%s,\n", i, calltab[i]) > "call_tab.v"; + else + printf("/* %3d */ sys_enosys,%s\n", i, callwas[i]) > "call_tab.v"; + + printf("#endif /* __AS386_16__ */\n\n"); + printf("#endif /* __MSDOS__ */\n\n"); + printf("%s\n", obj) > "syscall.mak"; + printf "\n" > "syscall.mak"; + +}' > syscall.c + +cat >> syscall.mak <<\! + +TOP=.. +include $(TOP)/Make.defs + +all: $(OBJ) + +libc.a: $(OBJ) + ar r ../libc.a $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a + +$(OBJ): syscall.dat mksyscall + $(CC) $(CFLAGS) -c -DL_$* -o $@ syscall.c +! + +rv=$? +if [ "$rv" != 0 ] +then exit $rv +fi + +export MAKELEVEL +MAKELEVEL=0 +exec make -f syscall.mak $1 diff --git a/libc-0.0.4/syscall/setjmp.c b/libc-0.0.4/syscall/setjmp.c new file mode 100644 index 0000000..52c3ff1 --- /dev/null +++ b/libc-0.0.4/syscall/setjmp.c @@ -0,0 +1,50 @@ + +#include <setjmp.h> + +#if __AS386_16__ + +int +setjmp(env) +jmp_buf env; +{ +#asm + pop cx ! PC +#if __FIRST_ARG_IN_AX__ + mov bx,ax +#else + mov bx,sp + mov bx,[bx] ! TOS is prt -> env +#endif + mov [bx+0],cx ! PC + mov [bx+2],sp ! This registers are all that may be constant. + mov [bx+4],bp + mov [bx+6],si ! Is saving these the "right thing" ? + mov [bx+8],di + xor ax,ax + jmp cx +#endasm +} + +void +longjmp(env, rv) +jmp_buf env; +int rv; +{ +#asm + pop cx ! pc +#if __FIRST_ARG_IN_AX__ + mov bx,ax ! env-> +#else + pop bx ! env-> +#endif + pop ax ! rv + mov cx,[bx+0] ! PC + mov sp,[bx+2] + mov bp,[bx+4] + mov si,[bx+6] + mov di,[bx+8] + jmp cx +#endasm +} + +#endif diff --git a/libc-0.0.4/syscall/signal.c b/libc-0.0.4/syscall/signal.c new file mode 100644 index 0000000..dbeac4a --- /dev/null +++ b/libc-0.0.4/syscall/signal.c @@ -0,0 +1,94 @@ + +#ifndef __MSDOS__ +#ifdef __AS386_16__ + +#include <errno.h> +#include <signal.h> + +typedef __sighandler_t Sig; + +extern int __signal __P((int, __sighandler_t)); +static Sig system_signal(); + +Sig __sigtable[_NSIG-1]; + +/* + * Signal handler. + * + */ + +/* + * KERNEL INTERFACE: + * It is assumed the kernel will never give us a signal we haven't + * _explicitly_ asked for! + * + * The Kernel need only save space for _one_ function pointer + * (to system_signal) and must deal with SIG_DFL and SIG_IGN + * in kernel space. + * + * When a signal is required the kernel must set all the registers as if + * returning from a interrupt normally then push the number of the signal + * to be generated, push the current pc value, then set the pc to the + * address of the 'system_signal' function. + */ + +Sig +signal(number, pointer) +int number; +Sig pointer; +{ + Sig old_sig; + int rv; + if( number < 1 || number >= _NSIG ) { errno=EINVAL; return SIG_ERR; } + + if( pointer == SIG_DFL || pointer == SIG_IGN ) + rv = __signal(number, pointer); + else + rv = __signal(number, (__sighandler_t) system_signal); + + if( rv < 0 ) return SIG_ERR; + + old_sig = __sigtable[number-1]; + __sigtable[number-1] = pointer; + + return old_sig; +} + +#asm + .text +_system_signal: ! When this is called by the kernel the stack contains + pushf ! in order: + push ax ! + push bx ! The signal number, (NOS) + push cx ! The program counter, (TOS) + push dx ! + push si ! It does NOT contain the CS register or the flags. + push di ! This means it cannot be unraveled by an iret. + push bp + push es ! Note also only ES segment register is saved. + mov bx,sp ! Unlike minix the rv from a system call is in AX. + mov bx,[bx+20] +#if __FIRST_ARG_IN_AX__ + mov ax,bx +#else + push bx ! NB this is _unchecked_, do we want to ? +#endif + add bx,bx + mov bx,[bx+___sigtable-2] ! Offset by 2 cause no entry for signal 0 + call bx ! Do we want to check BX for 0 or 1 ? + inc sp + inc sp + pop es + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + ret #2 ! Get rid of the signum too. +#endasm + +#endif /* __AS386_16__ */ +#endif /* __MSDOS__ */ diff --git a/libc-0.0.4/syscall/syscall.dat b/libc-0.0.4/syscall/syscall.dat new file mode 100644 index 0000000..397616f --- /dev/null +++ b/libc-0.0.4/syscall/syscall.dat @@ -0,0 +1,148 @@ +# +# 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 a ptr to long not a long. +FSTAT 28 2 +IOCTL 54 3 . Make this and fcntl the same ? +FCNTL 55 3 +FCHMOD 94 X +FCHOWN 95 X +FSYNC 118 1 +FCHDIR 133 X +LLSEEK 140 X +READV 145 X +WRITEV 146 X +FLOCK 143 X - 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 1 +PROF 44 X +BRK 45 X +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 +PHYS 52 X +LOCK 53 X +MPX 56 X +SETPGID 57 X +ULIMIT 58 X +UMASK 60 1 +CHROOT 61 1 +USTAT 62 X +GETPGRP 65 X +SETSID 66 X +SIGACTION 67 X +SGETMASK 68 X +SSETMASK 69 X +SETREUID 70 X +SETREGID 71 X +SIGSUSPEND 72 X +SIGPENDING 73 X +SETHOSTNAME 74 X +SETRLIMIT 75 X +GETRLIMIT 76 X +REBOOT 76 3 . The magic number is 0xfee1,0xdead,... +GETRUSAGE 77 X +GETGROUPS 80 2 +SETGROUPS 81 2 +SYMLINK 83 2 +LSTAT 84 2 +READLINK 85 3 +SWAPON 87 X +REBOOT 88 X +MUNMAP 91 X +TRUNCATE 92 X +FTRUNCATE 93 X +GETPRIORITY 96 X +SETPRIORITY 97 X +PROFIL 98 X +STATFS 99 X +FSTATFS 100 X +SOCKETCALL 102 X +SYSLOG 103 X +SETITIMER 104 X +GETITIMER 105 X +UNAME 109 X +VHANGUP 111 X +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 X +SYSFS 135 X +PERSONALITY 136 X +SETFSUID 138 X +SETFSGID 139 X +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-0.0.4/syscall/syslibc.c b/libc-0.0.4/syscall/syslibc.c new file mode 100644 index 0000000..1e604e8 --- /dev/null +++ b/libc-0.0.4/syscall/syslibc.c @@ -0,0 +1,330 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <sys/types.h> +#include <time.h> + +/* MSDOS has it's own versions */ +#ifndef __MSDOS__ +#ifdef __AS386_16__ + +/********************** Function __cstartup *******************************/ + +#ifdef L___cstartup + +void (*__cleanup)() = 0; +char ** environ; + +#asm + loc 2 +call_main: + .word _main ! Segment 2 is the trailing pointers, main and the + .word call_exit ! routine to call exit. +#if __FIRST_ARG_IN_AX__ + .data +saved_arg1: + .word 0 +#endif +#if __CALLER_SAVES__ + .data +loopy_safe: + .word 0 +#endif + .text + +export ___cstartup +___cstartup: ! Crt0 startup + pop cx ! Argc + mov bx,sp ! Calculate ptrs to argv and envp + mov ax,cx + inc ax + shl ax,#1 + add ax,bx + push ax ! Push Envp + mov [_environ],ax ! And save + push bx ! Push argv +#if __FIRST_ARG_IN_AX__ + mov [saved_arg1],cx +#else + push cx ! Push argc +#endif + + mov si,#auto_start ! Pointer to first autostart function +auto_run: +#if __FIRST_ARG_IN_AX__ + mov ax,[saved_arg1] +#endif +#if __CALLER_SAVES__ + mov [loopy_safe],si +#endif + call [si] ! Call the function +#if __CALLER_SAVES__ + mov si,[loopy_safe] +#endif + inc si ! SI at next + inc si + jmp auto_run ! And round for the next. + +call_exit: ! Last item called by above. + pop bx ! Be tidy. +#if !__FIRST_ARG_IN_AX__ + push ax ! At the end the last called was main() push it`s +#endif + call _exit ! return val and call exit(); +bad_exit: + jmp bad_exit ! Exit returned !! + +export _exit +export __exit +_exit: ! exit(rv) function +#if __FIRST_ARG_IN_AX__ + mov [saved_arg1],ax +#else + mov bx,sp + push [bx+2] ! Copy the `rv` for the exit fuctions. +#endif + mov bx,[___cleanup] ! Call exit, normally this is `__do_exit` + test bx,bx + je no_clean ! But it`s default is null + call bx +no_clean: +#if __FIRST_ARG_IN_AX__ + mov ax,[saved_arg1] +#else + inc sp + inc sp +#endif +__exit: ! _exit(rv) + br ___exit ! This is just an alias for __exit(); + +#endasm + +#endif + +/********************** Function time ************************************/ + +#ifdef L_time +time_t time(where) +time_t *where; +{ + struct timeval rv; + if( gettimeofday(&rv, (void*)0) < 0 ) return -1; + if(where) *where = rv.tv_sec; + return rv.tv_sec; +} +#endif + +/********************** Function lseek ************************************/ + +#ifdef L_lseek +off_t lseek(fd, posn, where) +int fd; +off_t posn; +int where; +{ + off_t __lseek(); + if( __lseek(fd, &posn, where) < 0 ) return -1; + else return posn; +} +#endif + +/********************** Function getpid ************************************/ + +#ifdef L_getpid +int getpid() +{ + int ppid; + return __getpid(&ppid); +} +#endif + +/********************** Function getppid ************************************/ + +#ifdef L_getppid +int getppid() +{ + int ppid; + __getpid(&ppid); + return ppid; +} +#endif + +/********************** Function getuid ************************************/ + +#ifdef L_getuid +int getuid() +{ + int euid; + return __getuid(&euid); +} +#endif + +/********************** Function geteuid ************************************/ + +#ifdef L_geteuid +int geteuid() +{ + int euid; + __getuid(&euid); + return euid; +} +#endif + +/********************** Function getgid ************************************/ + +#ifdef L_getgid +int getgid() +{ + int egid; + return __getgid(&egid); +} +#endif + +/********************** Function getegid ************************************/ + +#ifdef L_getegid +int getegid() +{ + int egid; + __getgid(&egid); + return egid; +} +#endif + +/********************** Function dup2 ************************************/ + +#ifdef L_dup2 + +#include <fcntl.h> + +int dup2(ifd, ofd) +int ifd; +{ + return fcntl(ifd, F_DUPFD, ofd); +} +#endif + +/********************** Function dup ************************************/ + +#ifdef L_dup +#include <sys/param.h> +#include <fcntl.h> +#include <errno.h> + +/* This is horribly complicated, there _must_ be a better way! */ + +int +dup(fd) +int fd; +{ + int nfd; + extern int errno; + int oerr = errno; + + errno = 0; + for(nfd=0; nfd<NR_OPEN; nfd++) + { + if( fcntl(nfd, F_GETFD) < 0 ) + break; + } + if( nfd == NR_OPEN ) { errno = EMFILE ; return -1; } + errno = oerr; + if( fcntl(fd, F_DUPFD, nfd) < 0 ) + { + if( errno == EINVAL ) errno = EMFILE; + return -1; + } + return nfd; +} +#endif + +/********************** Function abort ************************************/ + +#ifdef L_abort +#include <signal.h> + +int abort() +{ + signal(SIGABRT, SIG_DFL); + kill(SIGABRT, getpid()); /* Correct one */ + pause(); /* System may just schedule */ + signal(SIGKILL, SIG_DFL); + kill(SIGKILL, getpid()); /* Can't trap this! */ + __exit(255); /* WHAT!! */ +} +#endif + +/********************** Function wait ************************************/ + +#ifdef L_wait +int +wait(status) +int * status; +{ + return wait4(-1, status, 0, (void*)0); +} +#endif + +/********************** Function waitpid ************************************/ + +#ifdef L_waitpid +int +waitpid(pid, status, opts) +int pid; +int * status; +int opts; +{ + return wait4(pid, status, opts, (void*)0); +} +#endif + +/********************** Function sleep ************************************/ + +#ifdef L_sleep +#include <signal.h> + +/* This uses SIGALRM, it does keep the previous alarm call but will lose + * any alarms that go off during the sleep + */ + +static void alrm() { } + +unsigned int sleep(seconds) +unsigned int seconds; +{ + void (*last_alarm)(); + unsigned int prev_sec; + + prev_sec = alarm(0); + if( prev_sec <= seconds ) prev_sec = 1; else prev_sec -= seconds; + + last_alarm = signal(SIGALRM, alrm); + alarm(seconds); + pause(); + seconds = alarm(prev_sec); + signal(SIGALRM, last_alarm); + return seconds; +} +#if 0 + /* Is this a better way ? If we have select of course :-) */ +#include <sys/time.h> +unsigned int +sleep(seconds) +unsigned int seconds; +{ + struct timeval timeout; + time_t start = time((void*)0); + timeout.tv_sec = seconds; + timeout.tv_usec = 0; + select(1, NULL, NULL, NULL, &timeout); + return seconds - (time((void*)0) - start); +} +#endif +#endif + +/********************** THE END ********************************************/ + +#endif /* __AS386_16__ */ +#endif /* __MSDOS__ */ diff --git a/libc-0.0.4/termios/Config b/libc-0.0.4/termios/Config new file mode 100644 index 0000000..f0c9bde --- /dev/null +++ b/libc-0.0.4/termios/Config @@ -0,0 +1 @@ +termios: Termios functions diff --git a/libc-0.0.4/termios/Makefile b/libc-0.0.4/termios/Makefile new file mode 100644 index 0000000..6925bb3 --- /dev/null +++ b/libc-0.0.4/termios/Makefile @@ -0,0 +1,27 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs + +TSRC=termios.c +TOBJ=tcsetattr.o tcgetattr.o tcdrain.o tcflow.o tcflush.o tcsendbreak.o \ + tcsetpgrp.o tcgetpgrp.o isatty.o + +OBJ=$(TOBJ) + +all: $(OBJ) + +libdos.a: + +libc.a: $(OBJ) + ar r ../libc.a $(OBJ) + @touch libc.a + +clean: + rm -f $(OBJ) libc.a + +$(TOBJ): $(TSRC) + $(CC) $(CFLAGS) -c -DL_$* -o $@ $(TSRC) + diff --git a/libc-0.0.4/termios/README b/libc-0.0.4/termios/README new file mode 100644 index 0000000..c83448d --- /dev/null +++ b/libc-0.0.4/termios/README @@ -0,0 +1,7 @@ +Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +There's currently nothing special about termios. + +-Robert diff --git a/libc-0.0.4/termios/termios.c b/libc-0.0.4/termios/termios.c new file mode 100644 index 0000000..1c7da7f --- /dev/null +++ b/libc-0.0.4/termios/termios.c @@ -0,0 +1,142 @@ +/* Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> This + * file is part of the Linux-8086 C library and is distributed under the + * GNU Library General Public License. + */ + +/* Note: This is based loosely on the Glib termios routines. */ + +#ifndef __MSDOS__ + +#include <errno.h> +#include <stddef.h> +#include <sys/ioctl.h> +#include <termios.h> + +#ifdef L_isatty +isatty(fd) +int fd; +{ + struct termios term; + int rv, err = errno; + rv= (ioctl(fd, TCGETS, &term)==0); + if( rv==0 && errno == ENOSYS ) + rv = (fd<3); + errno = err; + return rv; +} +#endif + +#ifdef L_tcgetattr +int +tcgetattr(fd, term) +int fd; +struct termios *term; +{ + return ioctl(fd, TCGETS, term); +} +#endif + +#ifdef L_tcsetattr +int +tcsetattr(fildes, optional_actions, termios_p) +int fildes; +int optional_actions; +struct termios *termios_p; +{ + switch (optional_actions) + { + case TCSANOW: + return ioctl(fildes, TCSETS, termios_p); + case TCSADRAIN: + return ioctl(fildes, TCSETSW, termios_p); + case TCSAFLUSH: + return ioctl(fildes, TCSETSF, termios_p); + default: + errno = EINVAL; + return -1; + } +} +#endif + +#ifdef L_tcdrain +/* Wait for pending output to be written on FD. */ +int +tcdrain(fd) +int fd; +{ + /* With an argument of 1, TCSBRK just waits for output to drain. */ + return ioctl(fd, TCSBRK, 1); +} +#endif + +#ifdef L_tcflow +int +tcflow(fd, action) +int fd; +int action; +{ + return ioctl(fd, TCXONC, action); +} +#endif + +#ifdef L_tcflush +/* Flush pending data on FD. */ +int +tcflush(fd, queue_selector) +int fd; +int queue_selector; +{ + return ioctl(fd, TCFLSH, queue_selector); +} +#endif + +#ifdef L_tcsendbreak +/* Send zero bits on FD. */ +int +tcsendbreak(fd, duration) +int fd; +int duration; +{ + /* + * The break lasts 0.25 to 0.5 seconds if DURATION is zero, and an + * implementation-defined period if DURATION is nonzero. We define a + * positive DURATION to be number of milliseconds to break. + */ + if (duration <= 0) + return ioctl(fd, TCSBRK, 0); + + /* + * ioctl can't send a break of any other duration for us. This could be + * changed to use trickery (e.g. lower speed and send a '\0') to send + * the break, but for now just return an error. + */ + errno = EINVAL; + return -1; +} +#endif + +#ifdef L_tcsetpgrp +/* Set the foreground process group ID of FD set PGRP_ID. */ +int +tcsetpgrp(fd, pgrp_id) +int fd; +pid_t pgrp_id; +{ + return ioctl(fd, TIOCSPGRP, &pgrp_id); +} +#endif + +#ifdef L_tcgetpgrp +/* Return the foreground process group ID of FD. */ +pid_t +tcgetpgrp(fd) +int fd; +{ + int pgrp; + if (ioctl(fd, TIOCGPGRP, &pgrp) < 0) + return (pid_t) - 1; + return (pid_t) pgrp; +} +#endif + +#endif diff --git a/libc-0.0.4/tests/Config b/libc-0.0.4/tests/Config new file mode 100644 index 0000000..4bdf884 --- /dev/null +++ b/libc-0.0.4/tests/Config @@ -0,0 +1,2 @@ + +tools: These are tools to test libc - make directly diff --git a/libc-0.0.4/tests/README b/libc-0.0.4/tests/README new file mode 100644 index 0000000..642e636 --- /dev/null +++ b/libc-0.0.4/tests/README @@ -0,0 +1,19 @@ +Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +These are user level tools, they're being used to test libc routines. + +env.c Prints the environment and arguments (Plus some junk) +compr.c Mini compression program (rather slow at times) +ucomp.c Mini uncompression program (Very fast) +ft.c Multiple simple file tools. +hd.c Hex dump. +line2.c Print lines from /etc/passwd (stdio) +lines.c Print lines from /etc/passwd +ouch.c Signal test +size.c Size of executables and object files. +sync.c :-) +wc.c Word count. + +-Robert diff --git a/libc-0.0.4/tests/Real_make b/libc-0.0.4/tests/Real_make new file mode 100644 index 0000000..38c4232 --- /dev/null +++ b/libc-0.0.4/tests/Real_make @@ -0,0 +1,19 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +SRC=env.c ft.c hd.c size.c sync.c compr.c ucomp.c ouch.c lines.c \ + wc.c line2.c rand.c grab.c +OBJ= +EXE=env ft hd size sync compr ucomp ouch lines wc line2 rand grab + +LINK_FILES=cat chgrp chmod chown cp install ln mkdir mkfifo mknod mv rm + +all: $(EXE) + +links: + for i in $(LINK_FILES) ; do ln -s ft $$i ; done + +no_links: + rm -f $(LINK_FILES) + diff --git a/libc-0.0.4/tests/compr.c b/libc-0.0.4/tests/compr.c new file mode 100644 index 0000000..8e53443 --- /dev/null +++ b/libc-0.0.4/tests/compr.c @@ -0,0 +1,383 @@ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <malloc.h> + +#define MAXNO 32767 +#define MAXLEN 127 +#define XXQSCAN /* Speed up scanning at the cost of not being optimal */ + +unsigned char *fptr; +unsigned short *vptr; +FILE * fd; + +#define ITBSIZE 4096 +#define itbfunc() (ptr[mainscan]^(ptr[mainscan+1]<<4)^(ptr[mainscan+2]<<2)) +/* +#define ITBSIZE 4001 +#define itbfunc() ((ptr[mainscan]+ptr[mainscan+1]*79+ptr[mainscan+2]*307)%4001) +*/ +int * itb; + +int size; +int maxno= 8000; +long cnt=0; + +long icount = 0; +long ocount = 0; + +unsigned char key; + +int fl; + +main(argc, argv) +int argc; +char ** argv; +{ + if( argc < 2 ) { fprintf(stderr, "Usage; ... \n"); exit(1); } + + if( argc == 3 ) + { + maxno = atoi(argv[2]); + if( maxno < 256 ) maxno = 256; + if( maxno > MAXNO) maxno = MAXNO; + } + + if( strcmp(argv[1], "-") == 0 ) + fd = stdin; + else + fd = fopen(argv[1], "r" ); + if( fd == 0 ) { perror("Open failed\n"); exit(1); } + + fptr = (unsigned char * ) malloc((unsigned)maxno*2); + itb = (int * ) malloc(ITBSIZE*sizeof(int)); + if( itb ) + vptr = (unsigned short * ) malloc((unsigned)maxno * sizeof(short)*2 ); + else + vptr = 0; + + if( fptr == 0 ) + { + perror("Cannot allocate RAM"); + exit(1); + } + if( vptr == 0 && itb ) free(itb); + + fl = 0; + { + if( (size = fread(fptr, 1, (int)maxno, fd )) < 0 ) { fprintf(stderr, "\nRead failed\n"); exit(1); } + + if( size ) + { + icount += size; + if( fl == 0 ) + { + key = scan_min(); + putchar(key); ocount++; + fl = 1; + } + else + fprintf(stderr, "\rBlock %d \r", fl++ ); + if( vptr) compress(); + else slo_compress(); + } + } + + fprintf(stderr, "\n"); + exit(0); +} + +scan_min() +{ + long count[256]; + long i; + int j, n; + + for( j=0; j<256; j++ ) count[j] = 0; + + for( i=0; i<size; i++) count[ fptr[i] & 0xFF ]++; + + for( i= (((unsigned long) -1) >> 1), j=0; j<256; j++ ) + if( count[j] < i ) + { + i = count[j] ; + n = j; + } + + fprintf(stderr, "Most unused in 0x%lx to 0x%lx is 0x%02x at %ld\n", cnt, cnt+size, n, i ); + cnt+= size; + + return n; +} + +compress() +{ + register long mainscan; + register long secondscan; + register unsigned char * ptr = (unsigned char * ) fptr; + register int len; + register int matchlen; + long notepos; + long emark; +#ifdef QSCAN + int count; +#endif + + for( mainscan=0; mainscan <ITBSIZE; itb[mainscan++] = -1 ); + + mainscan=0; + emark = size - 130 ; +loopback: + + for( ; mainscan < emark; ) + { + matchlen = 3; + notepos = -1; +#ifdef QSCAN + count = 0; +#endif + for( secondscan=itb[itbfunc()]; + secondscan >= 0 && mainscan - secondscan < maxno; + secondscan -= vptr[secondscan] ) + { +#ifdef DEBUG +if( vptr[secondscan] == 0 ) +{ + fprintf(stderr, "\nOh !!!!! mainsc %ld, sec-scan %ld\n", mainscan, secondscan); + vptr[secondscan] = secondscan+1; +} +#endif + + for( len = 0; len < MAXLEN ; len++ ) + if( mainscan+len >= size || ptr[mainscan+len] != ptr[secondscan+len] ) break; + if( len > matchlen && (len != 4 || mainscan - secondscan < 256 ) ) + { + notepos = secondscan; + matchlen = len; + if( len == MAXLEN ) break; + } +#ifdef QSCAN + if( matchlen > 20 && len > 3 && ++count > 5 ) + break; +#endif + } + + if( notepos == -1 ) + { + if( ptr[mainscan] == key ) + { + ocount+=2; + putchar(key); + putchar(0); + } + else + { + ocount++; + putchar(ptr[mainscan]); + } + matchlen = 1; + } + else + { + long x = mainscan - notepos; + ocount+=3; + putchar(key); + if( x > 255 ) putchar(matchlen | 0x80); + else putchar(matchlen); + putchar((int)x); + if( x > 255 ) { putchar((int)x>>8); ocount++; } + } + + while( matchlen-- ) + { + len = itbfunc(); + vptr[mainscan] = mainscan - itb[len]; +#if 1 + if( vptr[mainscan] == 0 ) + { + fprintf(stderr, "\nHumm.. ms=%ld, hash=%d, itb[hash]=%ld\n", mainscan, len, itb[len]); + vptr[mainscan] = mainscan+1; + } +#endif + itb[len] = mainscan; + mainscan++; + } + } + + fprintf(stderr, "\rBlock %d ..In:%ld Out:%ld \r", fl-1, icount, ocount ); + + if( emark < size-4 ) + { + int cnt; + long l ; + if(mainscan > maxno ) + { + for(cnt=0; cnt<ITBSIZE; cnt++) + { + if( itb[cnt] < maxno) itb[cnt] = -1; + else itb[cnt] -= maxno; + } + for(l=0; l<maxno; l++) + { + ptr[l] = ptr[l+maxno]; + vptr[l] = vptr[l+maxno]; + } + mainscan -= maxno; + size -= maxno; + } + if( size <= maxno ) + { + if(( cnt = fread(ptr+size, 1, (int)maxno, fd)) < 0 ) + { fprintf(stderr, "\nRead failed\n"); exit(1); } + size += cnt; + icount += cnt; + fprintf(stderr, "\rBlock %d \r", fl++ ); + } + emark = size - 130; + if( mainscan >= emark ) + emark = size -4; + + goto loopback; + } + + for( ; mainscan < size; ) + { + if( ptr[mainscan] == key ) + { + ocount+=2; + putchar(key); + putchar(0); + } + else + { + ocount++; + putchar(fptr[mainscan]); + } + mainscan++; + } + fprintf(stderr, "\rBlock %d ..In:%ld Out:%ld \r", fl-1, icount, ocount ); + /* end */ +} + +slo_compress() +{ + register long mainscan; + register long secondscan; + register unsigned char * ptr = (unsigned char * ) fptr; + register int len; + register int matchlen; + long notepos; + long emark; +#ifdef QSCAN + int count; +#endif + + mainscan=0; + emark = size - 130 ; +loopback: + + for( ; mainscan < emark; ) + { + matchlen = 3; + notepos = -1; +#ifdef QSCAN + count = 0; +#endif + for( secondscan=mainscan-1; + secondscan >= 0 && mainscan - secondscan < maxno; + secondscan-- ) + { + for( len = 0; len < MAXLEN ; len++ ) + if( mainscan+len >= size || ptr[mainscan+len] != ptr[secondscan+len] ) break; + if( len > matchlen && (len != 4 || mainscan - secondscan < 256 ) ) + { + notepos = secondscan; + matchlen = len; + if( len == MAXLEN ) break; + } +#ifdef QSCAN + if( matchlen > 20 && len > 3 && ++count > 5 ) + break; +#endif + } + + if( notepos == -1 ) + { + if( ptr[mainscan] == key ) + { + ocount+=2; + putchar(key); + putchar(0); + } + else + { + ocount++; + putchar(ptr[mainscan]); + } + matchlen = 1; + } + else + { + long x = mainscan - notepos; + ocount+=3; + putchar(key); + if( x > 255 ) putchar(matchlen | 0x80); + else putchar(matchlen); + putchar((int)x); + if( x > 255 ) { putchar((int)x>>8); ocount++; } + } + + mainscan += matchlen; + } + + fprintf(stderr, "\rBlock %d ..In:%ld Out:%ld \r", fl-1, icount, ocount ); + + if( emark < size-4 ) + { + int cnt; + long l ; + if(mainscan > maxno ) + { + for(l=0; l<maxno; l++) + { + ptr[l] = ptr[l+maxno]; + } + mainscan -= maxno; + size -= maxno; + } + if( size <= maxno ) + { + if(( cnt = fread(ptr+size, 1, (int)maxno, fd)) < 0 ) + { fprintf(stderr, "\nRead failed\n"); exit(1); } + size += cnt; + icount += cnt; + fprintf(stderr, "\rBlock %d \r", fl++ ); + } + emark = size - 130; + if( mainscan >= emark ) + emark = size -4; + + goto loopback; + } + + for( ; mainscan < size; ) + { + if( ptr[mainscan] == key ) + { + ocount+=2; + putchar(key); + putchar(0); + } + else + { + ocount++; + putchar(fptr[mainscan]); + } + mainscan++; + } + fprintf(stderr, "\rBlock %d ..In:%ld Out:%ld \r", fl-1, icount, ocount ); + /* end */ +} + diff --git a/libc-0.0.4/tests/env.c b/libc-0.0.4/tests/env.c new file mode 100644 index 0000000..baeb8e9 --- /dev/null +++ b/libc-0.0.4/tests/env.c @@ -0,0 +1,82 @@ + +char hex[] = "0123456789ABCDEF"; + +char buf[20]; +main(argc, argv, envp) +int argc; +char ** argv; +char ** envp; +{ + int i,j; char *p; char * str; + int * arg = &argc; + + for(j=0; j<8; j++) + { + phex(arg); + putstr(":"); + for(i=0; i<8; i++) + { + putstr(" "); + phex(*arg++); + } + putstr("\n"); + } + +#if 0 + str = alloca(sizeof(hex)+2); + putstr("Alloca = "); + phex(&str); + putstr(","); + phex(str); + putstr("\n"); +#endif + + p = (char*) &argc; + + putstr("ARGC="); phex(argc); putstr("\n"); + for(i=0; i<argc; i++) + { + phex(argv[i]); + putstr(":"); + putstr(argv[i]); + putstr("\n"); + } + putstr("ENV=>\n"); + for(; *envp; envp++) + { + phex(envp); + putstr(":"); + phex(*envp); + putstr(":"); + putstr(*envp); + putstr("\n"); + } +} + +phex(val) +{ + int i; + printf("%04x", val); +} + +putstr(str) +{ + printf("%s", str); +} + +#if 0 +int global_var_that_needs_init = 0x201; + +#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 + .word no_op ! Space filler cause segs are padded to 4 bytes. + .text ! So the function after is also in the correct seg. +#endasm + +static void init_vars() +{ + global_var_that_needs_init = getuid(); +} +#endif diff --git a/libc-0.0.4/tests/ft.c b/libc-0.0.4/tests/ft.c new file mode 100644 index 0000000..6456d0b --- /dev/null +++ b/libc-0.0.4/tests/ft.c @@ -0,0 +1,1217 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This program is distributed under the GNU General Public License. + */ + +/* + * File Tool, This program is a collection of basic file tools + * it includes cat, cp, ln, mkdir, mknod, chmod, chown, mv, rm + * + * Links may be used to call it under any of these names. + */ +#include <stdio.h> +#ifdef __STDC__ +#include <unistd.h> +#include <stdlib.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <dirent.h> +#include <sys/param.h> +#include <utime.h> +#include <pwd.h> +#include <grp.h> + +#ifdef __BCC__X +#undef S_IFLNK +#undef S_IFSOCK +#endif + +#ifdef S_IFSOCK +#include <sys/socket.h> +#endif +#ifndef S_IFLNK +#define lstat stat +#endif + +/* Ansi prototypes */ +#ifdef __STDC__ +#define PR(x) x +#else +#define PR(x) () +#endif + +void main PR((int argc, char ** argv)); +int select_command PR((char * argv)); +void do_prep PR((void)); +void do_post PR((void)); +void execute PR((char * dname, char * fname)); +int exec_for_subdir PR((char * dname)); +void exec_for_item PR((int when, char * fname)); +void parse_perms PR((char * prefix, char * ustring)); +int edit_mode PR((int mode, char * mode_str)); +int cmd_ft PR((char * fname)); +int cmd_mkfifo PR((char * fname)); +int cmd_mksock PR((char * fname)); +int cmd_rm PR((char * fname)); +void build_dest PR((char * dest, char * name, char * newpath)); +int strisdigit PR((char * str)); +int cmd_mv PR((char * fname)); +int cmd_ln PR((char * fname)); +int cmd_cp PR((char * fname)); +int copy_modes PR((char * file)); +int copy_file PR((char * source, char * dest)); +void Usage PR((void)); +int cmd_mkdir PR((char * dirname)); +int cmd_mknod PR((void)); +int warn_func PR((int enumber, char * estr, char * eobj)); +int error_func PR((int enumber, char * estr, char * eobj)); + +#define warning(x,y,z) ( Line_no = __LINE__, warn_func(x,y,z)) +#define error(x,y,z) ( Line_no = __LINE__, error_func(x,y,z)) +int Line_no = -1; + +#define DO_BDIR 0x0010 /* Do Dir before contents */ +#define DO_ADIR 0x0020 /* Do Dir after contents */ +#define DO_MCOPY 0x0040 /* Preserve modes flag forced */ +#define OK_DIR 0x0080 /* Directorys OK even if no flg_recurse */ +#define IGN_LNK 0x0100 /* Not interested in symlinks */ +#define NO_SOURCE 0x0200 /* Named files created */ +#define OK_NO_SOURCE 0x0400 /* Don't need the source */ + +#define CMD_FT (0+OK_DIR+DO_BDIR) +#define CMD_CAT (1+IGN_LNK) +#define CMD_CHGRP (2+OK_DIR+IGN_LNK+DO_ADIR) +#define CMD_CHMOD (3+OK_DIR+IGN_LNK+DO_ADIR) +#define CMD_CHOWN (4+OK_DIR+IGN_LNK+DO_ADIR) +#define CMD_CP (5+IGN_LNK) +#define CMD_EXTAR (6+DO_MCOPY+DO_BDIR) +#define CMD_INSTALL (7+DO_MCOPY) +#define CMD_LN (8+IGN_LNK+DO_BDIR) +#define CMD_MKDIR (9+NO_SOURCE) +#define CMD_MKFIFO (10+NO_SOURCE) +#define CMD_MKSOCK (11+NO_SOURCE) +#define CMD_MKNOD (12+NO_SOURCE) +#define CMD_MV (13+DO_MCOPY+OK_DIR+DO_BDIR) +#define CMD_RM (14+DO_ADIR) + +struct { + char * name; + int cmd; + int argpat; + char * opts; +} command_list[] = +{ + { "ft", CMD_FT, 0, "-Rv" }, + { "cat", CMD_CAT, 0, "uR" }, + { "chgrp", CMD_CHGRP, 1, "vfR" }, + { "chmod", CMD_CHMOD, 1, "vfR" }, + { "chown", CMD_CHOWN, 1, "vfR" }, + { "cp", CMD_CP, -1, "vifRrpsd" }, + { "extar", CMD_EXTAR, 1, "" }, + { "install", CMD_INSTALL, -1, "cdso:g:m:" }, + { "ln", CMD_LN, -1, "vifs" }, + { "mkdir", CMD_MKDIR, 0, "m:" }, + { "mkfifo", CMD_MKFIFO, 0, "m:" }, +#ifdef S_IFSOCK + { "mksock", CMD_MKSOCK, 0, "m:" }, +#endif + { "mknod", CMD_MKNOD, 4, "m:" }, + { "mv", CMD_MV, -1, "vif" }, + { "rm", CMD_RM, 0, "vifr" }, + { 0 } +}; + +int cmd_arg = 0; +int cmd_tok = CMD_FT; +char * cmd_opt = "-"; +char * cmd_string = 0; /* the first (or last) arg where special */ +char * prog_name = ""; + +char ** flist = 0; +int fcount = 0; +int add_base=0; +char * or_name = 0; +int or_offset = 0; + +int flg_recurse = 0; +int flg_verbose = 1; +int flg_preserve= 0; +int flg_mkpdir = 0; +int flg_noderef = 0; +int flg_symlink = 0; +int flg_exestrip= 0; + +int flg_r, flg_force; +char *str_o, *str_g, *str_m; + +/* Things to set on the new file */ +int set_user = -1; +int set_group = -1; +int set_mode = -1; +time_t set_time = -1; +char mode_str[32] = ""; +int u_mask = 0; /* 07777 altered by umask() */ + +struct stat cur_file_stat; +struct stat dest_item; +struct stat access_stat; + +int done_something = 0; + +void +main(argc, argv) +int argc; char ** argv; +{ + int ar; + (void) select_command(argv[0]); + + for(ar=1; + argv[ar] && argv[ar][0] == '-' && argv[ar][1]; + ar++) + { + char * p = argv[ar]+1; + /* For symbolic changes of the form -rwx */ + if( cmd_tok == CMD_CHMOD && strchr("rwx", *p) != 0 ) break; + while(*p) + { + char * ap=0, *av=0; + char ch; + /* Is it a valid opt for this cmd */ + if(*p == ':' || (ap=strchr(cmd_opt, *p)) == 0) Usage(); + + /* Got an argument ? */ + if(ap[1] == ':') + { + if(!argv[ar+1]) Usage(); + av = argv[++ar]; + } + + if( (ch = *p) == '-' ) + { + if( (ch=select_command(p)) < 0 ) Usage(); + } + switch(ch) + { + case '\0': break; + case 'r': + case 'R': flg_recurse++; break; + case 'v': flg_verbose++; break; + case 'p': if(cmd_tok == CMD_MKDIR) flg_mkpdir++; + else flg_preserve++; + break; + case 'd': if(cmd_tok == CMD_INSTALL) + { flg_mkpdir++; cmd_arg=0; } /* Special mkdir */ + else flg_noderef++; /* cmd_copy */ + break; + + case 'f': flg_force++; flg_verbose=0; break; + case 'o': str_o = av; break; + case 'g': str_g = av; break; + case 'm': str_m = av; break; + + case 's': flg_symlink++; + if( cmd_tok == CMD_LN) cmd_tok |= OK_DIR+OK_NO_SOURCE; + break; + } + if(*p == '-') break; + p++; + } + } + + switch(cmd_arg) + { + case 1: + if( ar >= argc ) Usage(); + cmd_string = argv[ar++]; + fcount = argc-ar; + flist = argv+ar; + break; + case 0: + fcount = argc-ar; + flist = argv+ar; + break; + case -1: + if( ar >= argc ) Usage(); + cmd_string = argv[argc-1]; + fcount = argc-ar-1; + flist = argv+ar; + break; + default: + if( ar != argc-cmd_arg ) Usage(); + fcount = argc-ar; + flist = argv+ar; + break; + } + + do_prep(); + + for(ar=0; ar<fcount; ar++) + { + done_something=1; + or_name = flist[ar]; or_offset = strlen(or_name)+1; + execute(flist[ar], (char*)0); + } + + do_post(); + + if( !done_something ) + { + if( cmd_tok == CMD_CAT ) + execute("-", (char*)0); + else + Usage(); + } + exit(0); +} + +int select_command(argv) +char * argv; +{ + int ar; + char *p, *s; + prog_name = argv; + for(ar=0; command_list[ar].name; ar++) + { + p = strrchr(argv, '-'); if(p) p++; else p=argv; + s = strrchr(p, '/'); if(s) s++; else s=p; + if( strcmp(s, command_list[ar].name) == 0 ) + { + cmd_arg = command_list[ar].argpat; + cmd_tok = command_list[ar].cmd; + cmd_opt = command_list[ar].opts; + return 0; + } + } + return -1; +} + +void do_prep() +{ + char * prefix = "::"; + + u_mask = umask(077); + umask(u_mask); + u_mask = (07777&(~u_mask)); + + if(cmd_tok&DO_MCOPY) flg_preserve++; + if(str_m) parse_perms(prefix, str_m); + + switch(cmd_tok) + { + /* mknod is very different */ + case CMD_MKNOD: cmd_mknod(); exit(0); break; + + case CMD_CP: + if(strcmp(cmd_string, "-") == 0) + { + cmd_tok = CMD_CAT; + cmd_arg = 0; + break; + } + if(flg_symlink) + { + cmd_tok = CMD_LN+OK_DIR+OK_NO_SOURCE; + flg_preserve = 0; + } + break; + + case CMD_CHOWN: prefix++; + case CMD_CHGRP: prefix++; + case CMD_CHMOD: + parse_perms(prefix, cmd_string); + set_time = 0; + break; + case CMD_INSTALL: + flg_exestrip = flg_symlink; + flg_symlink = 0; + if(str_o) parse_perms(prefix+2, str_o); + if(str_g) parse_perms(prefix+1, str_g); + if(flg_mkpdir) cmd_tok = CMD_MKDIR; + else + { + cmd_tok = CMD_CP; + flg_preserve = 1; + } + break; + } + +#ifndef S_IFLNK + if(flg_symlink) + { + error(0, "No support for symlinks available:", cmd_string); + exit(1); + } +#endif + + /* Are we transfering many to one ? Then it must be a directory */ + if(cmd_arg == -1) + { + if( stat(cmd_string, &dest_item) == -1) + { + if( fcount > 1 ) + { + if( cmd_mkdir(cmd_string) < 0 ) + exit(1); + stat(cmd_string, &dest_item); + add_base = 1; + } + } + else + { + if( !S_ISDIR(dest_item.st_mode) ) + { + if( fcount > 1 ) + { + error(0, "Destination must be a directory:", cmd_string); + exit(1); + } + } + else add_base = 1; + } + } +} + +void do_post() +{ + /* Oh! It seems there's nothing to do, ah well. */ +} + +void execute(dname, fname) +char * dname; char * fname; +{ + char * buf; + if( strcmp(dname, "-") == 0 ) + { + exec_for_item(0, dname); + return; + } + if( fname ) + { + buf = alloca(strlen(dname) + strlen(fname) + 4); + if( buf == 0 ) + { + error(errno, "Can't allocate memory for path beyond", dname); + return ; + } + strcpy(buf, dname); + if(strcmp(dname, "/")) strcat(buf, "/"); + strcat(buf, fname); + } + else buf = dname; + + if( lstat(buf, &cur_file_stat) == -1 ) + { + if( cmd_tok&(NO_SOURCE|OK_NO_SOURCE) ) + exec_for_item(0, buf); + else + warning(errno, "", buf); + return; + } + if( !flg_force && ( cmd_tok&NO_SOURCE )) + { + error(EEXIST, "", buf); + return; + } + + if( S_ISDIR(cur_file_stat.st_mode)) + { + if( (cmd_tok&OK_DIR) || flg_recurse ) + (void) exec_for_subdir(buf); + else + error(EISDIR, "", buf); + return; + } + +#ifdef S_IFLNK + if( S_ISLNK(cur_file_stat.st_mode)) + { + /* Links are special */ + if( cmd_tok&IGN_LNK ) + { + if( stat(buf, &cur_file_stat) == -1 ) + { + warning(errno, "", buf); + return; + } + } + } +#endif + exec_for_item(0, buf); +} + +int exec_for_subdir(dname) +char * dname; +{ + DIR * dfd; + struct dirent * ent; + int old_mode = -1; + + if( cmd_tok&DO_BDIR ) exec_for_item(-1, dname); + + if( flg_recurse ) + { + dfd = opendir(dname); + + if( dfd == 0 && errno == EACCES && flg_force ) + { + old_mode = (cur_file_stat.st_mode & 07777); + if( chmod(dname, (0700|old_mode)) ) + return error(errno, "Can't unlock", dname); + + dfd = opendir(dname); + } + if( dfd == 0 ) return error(errno, "Can't open", dname); + + while((ent=readdir(dfd))) + { + if( strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0 ) + continue; + + alloca(0); /* Free up if using fake version */ + execute(dname, ent->d_name); + } + closedir(dfd); + if( old_mode != -1 ) + chmod(dname, old_mode); + } + + if( cmd_tok&DO_ADIR ) + { + lstat(dname, &cur_file_stat); + exec_for_item(1, dname); + } + return 0; +} + +void exec_for_item(when, fname) +int when; char * fname; +{ + int rv = -1; + switch(cmd_tok) + { + case CMD_FT: rv = cmd_ft(fname); break; + + case CMD_CAT: rv = copy_file(fname, "-"); break; + + case CMD_CHGRP: /* And fall */ + case CMD_CHMOD: /* And fall */ + case CMD_CHOWN: rv = copy_modes(fname); break; + + case CMD_CP: rv = cmd_cp(fname); break; + case CMD_MV: rv = cmd_mv(fname); break; + case CMD_RM: rv = cmd_rm(fname); break; + + case CMD_EXTAR: error(ENOSYS, "", ""); exit(1); + + case CMD_LN+OK_DIR+OK_NO_SOURCE: + case CMD_LN: rv = cmd_ln(fname); break; + + case CMD_INSTALL: error(EINVAL, "", "Bad program"); exit(1); + + case CMD_MKDIR: rv = cmd_mkdir(fname); break; + case CMD_MKFIFO: rv = cmd_mkfifo(fname); break; +#ifdef S_IFSOCK + case CMD_MKSOCK: rv = cmd_mksock(fname); break; +#endif + case CMD_MKNOD: break; + } +} + +void parse_perms(prefix, ustring) +char * prefix; char * ustring; +{ + char * userstr; + char * groupstr; + char * modestr; + char * cp; + struct passwd * pwd = 0; + struct group * grp; + + userstr = alloca(strlen(prefix) + strlen(ustring) + 2); + strcpy(userstr, prefix); + strcat(userstr, ustring); + + /* Select User */ + cp = strchr(userstr, ':'); + if(!cp) cp = strchr(userstr, '.'); + if(cp) *cp = '\0'; + + /* If there's a user */ + if( *userstr != 0 ) + { + pwd = getpwnam(userstr); + if(pwd == NULL) + { + if(!strisdigit(userstr) ) + { + error(EINVAL, "Unknown user", userstr); + exit(1); + } + set_user = atoi(userstr); + } + else set_user = pwd->pw_uid; + endpwent(); + } + if(cp) + { + groupstr = cp+1; + cp = strchr(groupstr, ':'); + if(!cp) cp = strchr(groupstr, '.'); + if(cp) *cp = '\0'; + if( *groupstr != '\0' ) + { + grp = getgrnam(groupstr); + if(grp == NULL) + { + if(!strisdigit(groupstr) ) + { + error(EINVAL, "Unknown group", groupstr); + exit(1); + } + set_group = atoi(groupstr); + } + else set_group = grp->gr_gid; + endgrent(); + } + else if( pwd ) + set_group = pwd->pw_gid; + } + if(cp) + { + modestr = cp+1; + if(strisdigit(modestr)) + set_mode = strtol(modestr, NULL, 8); + else + { + strncpy(mode_str, modestr, sizeof(mode_str)-1); + /* This is the time that the mode change will fail on syn error */ + (void) edit_mode(u_mask, mode_str); + } + } + + if( set_user < 0 && set_group < 0 && set_mode < 0 && *mode_str == 0) + { + error(EINVAL, "", "Permission string has no changes"); + exit(1); + } +} + +int edit_mode(mode, mode_str) +int mode; char * mode_str; +{ + char * str=mode_str; +static mtab[] = {0, 0111, 0222, 0333, 0444, 0555, 0666, 0777 }; + + int done_change = 0; + int isdir = S_ISDIR(mode); + int change_op = 0; + int change_mask = u_mask; + int v=0, s=0, nm=0; + + for(; *mode_str; mode_str++) + { + switch(*mode_str) + { + case ',': change_op = 0; + change_mask=u_mask; continue; + case '=': change_op = 1; if(0) { + case '+': change_op = 2; } if(0) { + case '-': change_op = 3; } + v=0; nm=0; + if(strchr(",=+-", mode_str[1]) == 0 ) continue; + break; + case 'a': if(change_op) goto ch_error; + nm |= 07777; if(0) { + case 'u': nm |= 04700; s= 6; } if(0) { + case 'g': nm |= 02070; s= 3; } if(0) { + case 'o': nm |= 01007; s= 0; } + if(change_op==0) { change_mask=nm; continue; } + v |= mtab[(mode>>s)&7]; + break; + case 'r': v |= 0444; break; + case 'w': v |= 0222; break; + case 'x': v |= 0111; break; + case 's': v |=06000; break; + case 't': v |=01000; break; + case 'X': v |= mtab[isdir]; break; + default: goto ch_error; + } + switch(change_op) + { + case 0: goto ch_error; + case 1: mode= ((mode&(~change_mask)) | (v&change_mask)); + break; + case 2: mode= ( mode | (v&change_mask)); + break; + case 3: mode= ( mode & ~(v&change_mask)); + break; + } + done_change=1; + } + if(!done_change) + { +ch_error: + error(EINVAL, "Invalid mode string", str); + exit(1); + } + return mode; +} + +int +cmd_ft(fname) +char * fname; +{ +static char oldpath[2048] = "~"; +static int last_uid=-1, last_gid=-1, last_mode=-1; + struct passwd * pptr; + struct group * gptr; + + if( flg_verbose>1 ) + { + char *p = 0; + if( fname[1] ) p = strrchr(fname, '/'); + if( p ) + { + *p = '\0'; + if( strcmp(fname, oldpath) != 0 ) + { + strcpy(oldpath, fname); + printf("%s/\n", oldpath); + } + *p = '/'; + } + else if( *oldpath ) + *oldpath = '\0'; + if(p) printf("%s", p+1); + else printf("%s", fname); + +#ifdef S_IFLNK + if( S_ISLNK(cur_file_stat.st_mode)) + { + char linkbuf[1024]; + int v; + *linkbuf='\0'; + v = readlink(fname, linkbuf, sizeof(linkbuf)); + if(v>0) linkbuf[v] = '\0'; + printf("\t+%s", linkbuf); + } + else +#endif + if( cur_file_stat.st_mode != last_mode + || cur_file_stat.st_uid != last_uid + || cur_file_stat.st_gid != last_gid) + { + printf("\t"); + if( cur_file_stat.st_uid != last_uid ) + { + pptr = getpwuid(cur_file_stat.st_uid); + if( pptr ) + printf("%s", pptr->pw_name); + else + printf("%d", cur_file_stat.st_uid); + } + printf(":"); + if( cur_file_stat.st_gid != last_gid ) + { + gptr = getgrgid(cur_file_stat.st_gid); + if( gptr ) + printf("%s", gptr->gr_name); + else + printf("%d", cur_file_stat.st_gid); + } + if( (cur_file_stat.st_mode&07777) != (last_mode&07777) ) + printf(":%03o", cur_file_stat.st_mode & 07777); + + switch(cur_file_stat.st_mode & S_IFMT) + { + case S_IFDIR: printf("\td"); break; + case S_IFIFO: printf("\tp"); break; +#ifdef S_IFSOCK + case S_IFSOCK: printf("\ts"); break; +#endif + case S_IFBLK: printf("\tb,%d,%d", cur_file_stat.st_rdev>>8, + cur_file_stat.st_rdev&0xFF); + break; + case S_IFCHR: printf("\tc,%d,%d", cur_file_stat.st_rdev>>8, + cur_file_stat.st_rdev&0xFF); + break; + } + last_mode = ((cur_file_stat.st_mode&07777)|S_IFREG); + if( (cur_file_stat.st_mode&07000) ) last_mode = -1; + last_uid = cur_file_stat.st_uid; + last_gid = cur_file_stat.st_gid; + } + printf("\n"); + } + else printf("%s\n", fname); + + return 0; +} + +int +cmd_mkfifo(fname) +char * fname; +{ + int rv; + int mode=0666; + if( set_mode >= 0 ) mode=set_mode; + rv = mknod(fname, S_IFIFO|mode, 0); + if(rv<0) + warning(errno, "Cannot create fifo", fname); + return rv; +} + +#ifdef S_IFSOCK +int +cmd_mksock(fname) +char * fname; +{ + int rv, fd, len; + struct sockaddr *adr; + + len = strlen(fname)+1 + sizeof(*adr) - sizeof(adr->sa_data); + if( len < sizeof(*adr) ) len = sizeof(*adr); + + adr = alloca(len+2); + adr->sa_family = AF_UNIX; + strcpy(adr->sa_data, fname); + + rv = fd = socket(AF_UNIX, SOCK_STREAM, 0); + if( fd>=0 ) rv = bind(fd, adr, len); + if( fd>=0 ) close(fd); + if(set_mode >= 0 && chmod(fname, set_mode&07777) < 0 ) + warning(errno, "Chmod", fname); + + if(rv<0) + warning(errno, "Cannot create socket", fname); + return rv; +} +#endif + +int +cmd_rm(fname) +char * fname; +{ + struct stat dirstat; + int rv; + char * buf, * p; + + if( S_ISDIR(cur_file_stat.st_mode) ) + if( !flg_recurse ) return error(EISDIR, "", fname); + + if( S_ISDIR(cur_file_stat.st_mode) ) + { + if( rmdir(fname) >= 0 ) return 0; + } + else + { + if( unlink(fname) >= 0 ) return 0; + } + + if( !flg_force ) + return error(errno, "", fname); + + /* Try VERY hard */ + buf = alloca(strlen(fname)+4); + strcpy(buf, fname); + p = strrchr(buf, '/'); + if( p ) strcpy(p+1, "."); else strcpy(buf, "."); + + if( stat(buf, &dirstat) < 0 ) return -1; + if( chmod(buf, dirstat.st_mode|0700) < 0 ) return -1; + + if( S_ISDIR(cur_file_stat.st_mode) ) + rv = rmdir(fname); + else + rv = unlink(fname); + + chmod(buf, dirstat.st_mode); + + return rv; +} + +void +build_dest(dest, name, newpath) +char * dest; char * name; char * newpath; +{ + char * p; + strcpy(dest, newpath); + if( add_base ) + { + strcat(dest, "/"); + p = strrchr(or_name, '/'); + if(p==0) strcat(dest, or_name); + else strcat(dest, p+1); + } + if(strlen(name) <= or_offset) return; + strcat(dest, name+or_offset); +} + +int +strisdigit(str) +char * str; +{ + if( str==0 || *str == 0 ) return 0; + + for(;*str; str++) + if(*str>'9'|| *str<'0') return 0; + return 1; +} + +int +cmd_mv(fname) +char * fname; +{ + char * destfile; + destfile = alloca(strlen(fname)+strlen(cmd_string)+4); + + build_dest(destfile, fname, cmd_string); + + if( !flg_force && lstat(destfile, &access_stat) == 0 ) + return error(EEXIST, "", destfile); + + if( rename(fname, destfile) == 0 ) return 0; + + if( errno != EXDEV ) + return error(errno, "", fname); + + if( S_ISDIR(cur_file_stat.st_mode) ) + return error(EISDIR, "Can't rename across devices", fname); + + if( copy_file(fname, destfile) != 0 ) return -1; + copy_modes(destfile); + return unlink(fname); +} + +int +cmd_ln(fname) +char * fname; +{ + char * destfile; + destfile = alloca(strlen(fname)+strlen(cmd_string)+4); + + build_dest(destfile, fname, cmd_string); + + if( lstat(destfile, &access_stat) != -1 ) + { + if( !flg_force ) return error(EEXIST, "", destfile); + cmd_rm(destfile); + } + +#ifdef S_IFLNK + if( flg_symlink ) + { + if( symlink(fname, destfile) == 0 ) return 0; + } + else + { +#endif + if( link(fname, destfile) == 0 ) return 0; +#ifdef S_IFLNK + } +#endif + + return error(errno, "", destfile); +} + +int +cmd_cp(fname) +char * fname; +{ + struct stat dest_stat; + char * destfile; + int no_dest = 0; + + destfile = alloca(strlen(fname)+strlen(cmd_string)+4); + + build_dest(destfile, fname, cmd_string); + + if( stat(destfile, &dest_stat) >= 0 ) + { + if( dest_stat.st_ino == cur_file_stat.st_ino + && dest_stat.st_dev == cur_file_stat.st_dev ) + { + warning(EPERM, "Can't copy file to itself", fname); + return -1; + } + } + else no_dest = 1; + + if( S_ISDIR(cur_file_stat.st_mode) ) + { + if( !no_dest ) + { + if( S_ISDIR(dest_stat.st_mode) ) return 0; + if( unlink(destfile) < 0 ) + return error(errno, "Can't delete", destfile); + } + return cmd_mkdir(destfile); + } + else if( S_ISDIR(dest_stat.st_mode) ) + return error(EPERM, "Can't copy non-directory to directory", destfile); + else if( S_ISREG(cur_file_stat.st_mode) ) + { + /* Copy_ok - do we want to force a real file */; + if( flg_force && !no_dest && !S_ISREG(dest_stat.st_mode) ) + cmd_rm(destfile); + } + else if( flg_recurse ) /* Don't copy other things while recursing */ + { + return error(EPERM, "Can't copy", fname); + } + + if( copy_file(fname, destfile) != 0 ) return -1; + if( flg_preserve ) copy_modes(destfile); + return 0; +} + +int +copy_modes(file) +char * file; +{ + int user, group, mode; + /* chown turns off set[ug]id bits for non-root, + so do the chmod last. */ + + /* Try to copy the old file's modtime and access time. */ + if(set_time) + { + struct utimbuf tv; + + tv.actime = cur_file_stat.st_atime; + tv.modtime = cur_file_stat.st_mtime; + if( set_time != -1 ) + tv.modtime = set_time; + if (utime (file, &tv) && !flg_force) + return error (errno, "", file); + } + + /* Try to preserve ownership. For non-root it might fail, but that's ok. + But root probably wants to know, e.g. if NFS disallows it. */ + user = cur_file_stat.st_uid; if(set_user>=0) user = set_user; + group = cur_file_stat.st_gid; if(set_group>=0) group = set_group; + + if (chown (file, user, group) + && (errno != EPERM || geteuid() == 0 || (flg_preserve==0 && flg_force==0))) + error (errno, "Can't change perms for", file); + + mode = cur_file_stat.st_mode; + if(set_mode>=0) mode=set_mode; + else if(*mode_str) + mode = edit_mode(mode, mode_str); + + if (chmod (file, mode & 07777)) + return error (errno, "", file); + + return 0; +} + +/* This copies from something to a file or stdout */ +/* If the source has zero blocks (possibly holes) the destination + * is built with holes (assuming it's a normal file) */ + +int +copy_file(source, dest) +char * source; char * dest; +{ + char * buf; + int sfd, dfd; + struct stat st; + int blksz = BUFSIZ; + int cc; + char * ptr; + int hole_flag = 0; + int retv = 0; + int no_seek; + int mmode = 0666; + + if(flg_verbose>1) printf("%s -> %s\n", source, dest); + if( strcmp(source, "-") == 0 ) + sfd = 0; + else + { + sfd = open(source, O_RDONLY); + if(sfd<0) return error(errno, "", source); + mmode = (cur_file_stat.st_mode&0777); + } + + if( strcmp(dest, "-") == 0 ) + dfd = 1; + else + { + dfd = open(dest, O_WRONLY|O_TRUNC|O_CREAT, mmode); + if(dfd<0) + { + close(sfd); + return error(errno, "Cannot create", source); + } + } + + if( fstat(dfd, &st) ) + { + retv = error(errno, "", dest); + no_seek = 1; + } + else + { +#ifndef __BCC__ + blksz = st.st_blksize; +#endif + no_seek = !S_ISREG(st.st_mode); + } + buf = alloca(blksz + sizeof(int)); + if( buf == 0 ) return error(0, "Out of memory", ""); + + for(;;) + { + cc = read(sfd, buf, blksz); + if(cc<0) + { + retv = error(errno, "", source); + goto exit_now; + } + if(cc==0) break; + buf[cc] = 1; + for(ptr=buf; *ptr==0 ; ptr++) ; + if((hole_flag = (ptr == buf+cc))) + { /* Make a hole */ + if( lseek(dfd, (off_t) cc, SEEK_CUR) < 0 ) + { + retv = error(errno, "", dest); + goto exit_now; + } + } + else + { + if( cc != write(dfd, buf, cc)) + { + retv = error(errno, "", dest); + goto exit_now; + } + } + } + if( hole_flag ) + { + if( lseek(dfd, (off_t) -1, SEEK_CUR) < 0 + || write(dfd, "", 1) != 1 ) + { + retv = error(errno, "", dest); + goto exit_now; + } + } + +exit_now: + if(sfd>2) close(sfd); + if(dfd>2) close(dfd); + return retv; +} + +void +Usage() +{ + int i; + + printf("FileTool Usage: %s%s", prog_name[0]=='-'?"ft -":"", prog_name); + if( cmd_tok == CMD_FT ) + { + printf(" --[com_name] [-options] [files]\n"); + printf("\nAvailable commands are:\n"); + } + + for(i=1; command_list[i].name; i++) + { + if( cmd_tok == CMD_FT ) + printf(" %s --%s", prog_name, command_list[i].name); + else if( cmd_tok != command_list[i].cmd ) + continue; + + if( *command_list[i].opts ) + printf(" [-%s]", command_list[i].opts); + switch(command_list[i].argpat) + { + case 1: printf(" <info> [files]"); break; + case -1: printf(" [files] [dest]"); break; + case 0: printf(" [files]"); break; + default: printf(" path [bcu] major minor"); break; + } + printf("\n"); + } + + exit(99); +} + +int +cmd_mkdir(dirname) +char * dirname; +{ + int retv; + int mode = 0777; + if( set_mode >= 0 ) mode = set_mode; + + retv = mkdir(dirname, mode); + if(retv<0) + { + if(flg_mkpdir && errno == ENOENT) + { + /* Create parents */ + } + } + if( retv>=0 && cmd_tok == CMD_MKDIR ) + { + if( set_user > 0 || set_group > 0 ) + { + if( chown(dirname, set_user, set_group) < 0) + warning(errno, "Cannot change directory owner", dirname); + else if( chmod (dirname, mode & 07777) ) + warning(errno, "", dirname); + } + } + + if(retv<0) error(errno, "Cannot create directory", dirname); + return retv; +} + +int +cmd_mknod() +{ + int device; + int rv = -1; + int mode=0666; + if( set_mode >= 0 ) mode=set_mode; + + device = (atoi(flist[2])<<8) + atoi(flist[3]); + + if(flist[1][0] == 'b') + rv = mknod(flist[0], S_IFBLK|mode, device); + else if(flist[1][0] == 'c' || flist[1][0] == 'u') + rv = mknod(flist[0], S_IFCHR|mode, device); + else Usage(); + + if(rv<0) + { + error(errno, "", flist[0]); + exit(1); + } + return rv; +} + +int +warn_func(enumber, estr, eobj) +int enumber; char * estr; char * eobj; +{ + if(flg_verbose) + return error_func(enumber, estr, eobj); + return 0; +} + +int +error_func(enumber, estr, eobj) +int enumber; char * estr; char * eobj; +{ + fprintf(stderr, "%s%s(%d): ", prog_name[0]=='-'?"ft":"", prog_name, Line_no); + fprintf(stderr, "%s%s%s: %s\n", estr, (*estr?" ":""), eobj, strerror(enumber)); + return -1; +} diff --git a/libc-0.0.4/tests/grab.c b/libc-0.0.4/tests/grab.c new file mode 100755 index 0000000..bd62a0f --- /dev/null +++ b/libc-0.0.4/tests/grab.c @@ -0,0 +1,80 @@ + +#include <stdio.h> +#include <malloc.h> + +struct s +{ + struct s * n; + char v[1]; +}; + +#define M ((unsigned)-1>>1) +#define V (M^(M>>1)) + +main (argc,argv) +int argc; +char ** argv; +{ + struct s * ptr1 = 0; + struct s * ptr2; + struct s * ptr3; + int i,sz; + long total = 0; + + for(i=0, sz=256 ; i<32; i++, sz = ((sz << 1) | (sz & V)) & M) + { + ptr2 = (struct s *) malloc(sz-sizeof(int)); + printf("%2d(%8u)..%08lx..%ld\n",i,sz,(long)ptr2,(long)ptr2); + if(ptr2==0) break; + total+=sz; + if(ptr1==0) + { + ptr1 = ptr3 = ptr2; + ptr3->n = 0; + } + else + { + ptr3->n = ptr2; + ptr3 = ptr2; + ptr3->n = 0; + } + } + for(sz>>=1; sz>255; ) + { + ptr2 = (struct s *) malloc(sz-sizeof(int)); + if(ptr2==0) { sz >>=1; continue; } + printf("%2d(%8u)..%08lx..%ld\n",i++,sz,(long)ptr2,(long)ptr2); + total+=sz; + if(ptr1==0) + { + ptr1 = ptr3 = ptr2; + ptr3->n = 0; + } + else + { + ptr3->n = ptr2; + ptr3 = ptr2; + ptr3->n = 0; + } + } + printf("Free all - total was %ldK bytes\n", total/1024); + while( ptr1 ) + { + ptr3 = ptr1->n; + free(ptr1); + ptr1 = ptr3; + } + ptr2 = (struct s *) malloc(200); + printf("%2d(%8u)..%08lx..%ld\n",i++,200,(long)ptr2,(long)ptr2); + ptr2 = (struct s *) malloc(30000); + printf("%2d(%8u)..%08lx..%ld\n",i++,30000,(long)ptr2,(long)ptr2); + ptr2 = (struct s *) malloc(20000); + printf("%2d(%8u)..%08lx..%ld\n",i++,20000,(long)ptr2,(long)ptr2); + sz = (256<<sizeof(int)); + do + { + ptr2 = (struct s *) malloc(sz-sizeof(int)); + printf("%2d(%8u)..%08lx..%ld\n",i++,sz,(long)ptr2,(long)ptr2); + } + while(ptr2 && i < 100); +} diff --git a/libc-0.0.4/tests/hd.c b/libc-0.0.4/tests/hd.c new file mode 100644 index 0000000..f6af1f9 --- /dev/null +++ b/libc-0.0.4/tests/hd.c @@ -0,0 +1,90 @@ +#include <stdio.h> +#include <ctype.h> + +int lastnum[16] = { -1 }; +long lastaddr = -1; + +main(argc, argv) +int argc; +char ** argv; +{ + FILE * fd; + int j, ch; + char buf[20]; + int num[16]; + long offset = 0; + +#ifndef MSDOS + if( argc == 1 ) + { + fd = stdin; + } + else +#endif + { + if( argc == 3 ) offset = strtol(argv[2], (char*)0, 16); + else if( argc != 2 ) + { + fprintf(stderr, "Usage: hd file [hexoffset]\n"); + exit(1); + } + fd = fopen(argv[1], "rb"); + if( fd == 0 ) + { + fprintf(stderr, "Cannot open file '%s'\n", argv[1]); + exit(1); + } + } + + /* if( offset ) fseek(fd, offset, 0); */ + + for(ch=0; ch!=EOF; offset+=16) + { + memset(buf, '\0', 16); + for(j=0; j<16; j++) num[j] = -1; + for(j=0; j<16; j++) + { + ch = fgetc(fd); + if( ch == EOF ) break; + + num[j] = ch; + if( isascii(ch) && isprint(ch) ) buf[j] = ch; + else buf[j] = '.'; + } + printline(offset, num, buf, ch==EOF); + } + fclose(fd); +} + +printline(address, num, chr, eofflag) +long address; +int * num; +char * chr; +int eofflag; +{ + int j; + + if( lastaddr >= 0 ) + { + for(j=0; j<16; j++) + if( num[j] != lastnum[j] ) + break; + if( j == 16 && !eofflag ) return; + if( lastaddr+16 != address ) + printf("*\n"); + } + + lastaddr = address; + printf("%06lx:", address); + for(j=0; j<16; j++) + { + if( num[j] >= 0 ) + printf(" %02x", num[j]); + else + printf(" "); + lastnum[j] = num[j]; + num[j] = -1; + } + + printf(" %.16s\n", chr); +} diff --git a/libc-0.0.4/tests/line2.c b/libc-0.0.4/tests/line2.c new file mode 100644 index 0000000..6cc11ff --- /dev/null +++ b/libc-0.0.4/tests/line2.c @@ -0,0 +1,15 @@ + +#include <stdio.h> + +char buf[256]; + +main() +{ + FILE * fd; + fd = fopen("/etc/passwd", "r"); + + while(fgets(buf, sizeof(buf), fd) != NULL) + { + printf(">>%s", buf); + } +} diff --git a/libc-0.0.4/tests/lines.c b/libc-0.0.4/tests/lines.c new file mode 100644 index 0000000..6f3afb0 --- /dev/null +++ b/libc-0.0.4/tests/lines.c @@ -0,0 +1,36 @@ + +#include <string.h> +#include <fcntl.h> + +char * +readline(fd) +{ +static char linebuf[256]; + int cc; + char * p; + + cc = read(fd, linebuf, sizeof(linebuf)-1); + if( cc <= 0 ) return 0; + p = strchr(linebuf, '\n'); + if( p == 0 ) p = linebuf+sizeof(linebuf)-1; + else + { + p++; lseek(fd, (long)(p-linebuf)-cc, 1); + } + *p = 0; + return linebuf; +} + +main() +{ + int fd = open("/etc/passwd", O_RDONLY); + char * p; + + if(fd<0) exit(1); + + while( p=readline(fd) ) + { + write(1, ">>", 2); + write(1, p, strlen(p)); + } +} diff --git a/libc-0.0.4/tests/ls.c b/libc-0.0.4/tests/ls.c new file mode 100755 index 0000000..8cae4d0 --- /dev/null +++ b/libc-0.0.4/tests/ls.c @@ -0,0 +1,1049 @@ +/* ls 3.2 - List files. Author: Kees J. Bot + * + * About the amount of bytes for heap + stack under Minix: + * Ls needs a average amount of 42 bytes per unserviced directory entry, so + * scanning 10 directory levels deep in an ls -R with 100 entries per directory + * takes 42000 bytes of heap. So giving ls 10000 bytes is tight, 20000 is + * usually enough, 40000 is pessimistic. + */ + +/* Compile with the proper -D flag for your system: + * + * _MINIX Minix (1.5 or later) + * BSD BSD derived (has st_blocks) + * AMOEBA Amoeba's emulation of UNIX + */ + +/* The array _ifmt[] is used in an 'ls -l' to map the type of a file to a + * letter. This is done so that ls can list any future file or device type + * other than symlinks, without recompilation. (Yes it's dirty.) + */ +char _ifmt[] = "0pcCd?bB-?l?s???"; + +#define ifmt(mode) _ifmt[((mode) >> 12) & 0xF] + +#define nil 0 +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#ifdef AMOEBA +#undef S_IFLNK /* Liars */ +#endif +#include <dirent.h> +#include <time.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> +#include <fcntl.h> +#if BSD || __minix_vmd +#include <termios.h> +#endif +#if __minix_vmd +#include <sys/ioctl.h> +#endif + +#ifndef major +#define major(dev) ((int) (((dev) >> 8) & 0xFF)) +#define minor(dev) ((int) (((dev) >> 0) & 0xFF)) +#endif + +#if !_MINIX +#define SUPER_ID uid /* Let -A flag be default for SUPER_ID == 0. */ +#else +#define SUPER_ID gid +#endif + +#ifdef S_IFLNK +int (*status)(const char *file, struct stat *stp); +#else +#define status stat +#endif + +/* Basic disk block size is 512 except for one niche O.S. */ +#if _MINIX +#define BLOCK 1024 +#else +#define BLOCK 512 +#endif + +/* Some terminals ignore more than 80 characters on a line. Dumb ones wrap + * when the cursor hits the side. Nice terminals don't wrap until they have + * to print the 81st character. Wether we like it or not, no column 80. + */ +#ifdef TIOCGWINSZ +int ncols= 79; +#else +#define ncols 79 +#endif + +#define NSEP 2 /* # spaces between columns. */ + +#ifdef TIOCGWINSZ +#define MAXCOLS 150 +#else +#define MAXCOLS (1 + (ncols / (1+NSEP))) /* Max # of files per line. */ +#endif + +char *arg0; /* Last component of argv[0]. */ +int uid, gid; /* callers id. */ +int ex= 0; /* Exit status to be. */ +int istty; /* Output is on a terminal. */ + +/* Safer versions of malloc and realloc: */ + +void heaperr(void) +{ + fprintf(stderr, "%s: Out of memory\n", arg0); + exit(-1); +} + +void *allocate(size_t n) +/* Deliver or die. */ +{ + void *a; + + if ((a= malloc(n)) == nil) heaperr(); + return a; +} + +#define reallocate rllct /* Same as realloc under some compilers. */ + +void *reallocate(void *a, size_t n) +{ + if ((a= realloc(a, n)) == nil) heaperr(); + return a; +} + +char allowed[] = "acdfgilnqrstu1ACFLMRTX"; +char flags[sizeof(allowed)]; + +char arg0flag[] = "cfmrtx"; /* These in argv[0] go to upper case. */ + +void setflags(char *flgs) +{ + int c; + + while ((c= *flgs++) != 0) { + if (strchr(allowed, c) == nil) { + fprintf(stderr, "Usage: %s -[%s] [file ...]\n", + arg0, allowed); + exit(1); + } else + if (strchr(flags, c) == nil) + flags[strlen(flags)] = c; + } +} + +int present(int f) +{ + return f == 0 || strchr(flags, f) != nil; +} + +void report(char *f) +/* Like perror(3), but in the style: "ls: junk: No such file or directory. */ +{ + fprintf(stderr, "%s: %s: %s\n", arg0, f, strerror(errno)); + ex= 1; +} + +/* Two functions, uidname and gidname, translate id's to readable names. + * All names are remembered to avoid searching the password file. + */ +#define NNAMES (1 << (sizeof(int) + sizeof(char *))) +enum whatmap { PASSWD, GROUP }; + +struct idname { /* Hash list of names. */ + struct idname *next; + char *name; + uid_t id; +} *uids[NNAMES], *gids[NNAMES]; + +char *idname(unsigned id, enum whatmap map) +/* Return name for a given user/group id. */ +{ + struct idname *i; + struct idname **ids= &(map == PASSWD ? uids : gids)[id % NNAMES]; + + while ((i= *ids) != nil && id < i->id) ids= &i->next; + + if (i == nil || id != i->id) { + /* Not found, go look in the password or group map. */ + char *name= nil; + char noname[3 * sizeof(uid_t)]; + + if (!present('n')) { + if (map == PASSWD) { + struct passwd *pw= getpwuid(id); + + if (pw != nil) name= pw->pw_name; + } else { + struct group *gr= getgrgid(id); + + if (gr != nil) name= gr->gr_name; + } + } + if (name == nil) { + /* Can't find it, weird. Use numerical "name." */ + sprintf(noname, "%u", id); + name= noname; + } + + /* Add a new id-to-name cell. */ + i= allocate(sizeof(*i)); + i->id= id; + i->name= allocate(strlen(name) + 1); + strcpy(i->name, name); + i->next= *ids; + *ids= i; + } + return i->name; +} + +#define uidname(uid) idname((uid), PASSWD) +#define gidname(gid) idname((gid), GROUP) + +/* Path name construction, addpath adds a component, delpath removes it. + * The string path is used throughout the program as the file under examination. + */ + +char *path; /* Path name constructed in path[]. */ +int plen= 0, pidx= 0; /* Lenght/index for path[]. */ + +void addpath(int *didx, char *name) +/* Add a component to path. (name may also be a full path at the first call) + * The index where the current path ends is stored in *pdi. + */ +{ + if (plen == 0) path= (char *) allocate((plen= 32) * sizeof(path[0])); + + if (pidx == 1 && path[0] == '.') pidx= 0; /* Remove "." */ + + *didx= pidx; /* Record point to go back to for delpath. */ + + if (pidx > 0 && path[pidx-1] != '/') path[pidx++]= '/'; + + do { + if (*name != '/' || pidx == 0 || path[pidx-1] != '/') { + if (pidx == plen) + path= (char *) reallocate((void *) path, + (plen*= 2) * sizeof(path[0])); + path[pidx++]= *name; + } + } while (*name++ != 0); + + --pidx; /* Put pidx back at the null. The path[pidx++]= '/' + * statement will overwrite it at the next call. + */ +} + +#define delpath(didx) (path[pidx= didx]= 0) /* Remove component. */ + +int field = 0; /* (used to be) Fields that must be printed. */ + /* (now) Effects triggered by certain flags. */ + +#define F_INODE 0x001 /* -i */ +#define F_BLOCKS 0x002 /* -s */ +#define F_EXTRA 0x004 /* -X */ +#define F_MODE 0x008 /* -lMX */ +#define F_LONG 0x010 /* -l */ +#define F_GROUP 0x020 /* -g */ +#define F_BYTIME 0x040 /* -tuc */ +#define F_ATIME 0x080 /* -u */ +#define F_CTIME 0x100 /* -c */ +#define F_MARK 0x200 /* -F */ +#define F_TYPE 0x400 /* -T */ +#define F_DIR 0x800 /* -d */ + +struct file { /* A file plus stat(2) information. */ + struct file *next; /* Lists are made of them. */ + char *name; /* Null terminated name. */ + ino_t ino; + mode_t mode; + uid_t uid; + gid_t gid; + nlink_t nlink; + dev_t rdev; + off_t size; + time_t mtime; + time_t atime; + time_t ctime; +#if BSD + long blocks; +#endif +}; + +void setstat(struct file *f, struct stat *stp) +{ + f->ino= stp->st_ino; + f->mode= stp->st_mode; + f->nlink= stp->st_nlink; + f->uid= stp->st_uid; + f->gid= stp->st_gid; + f->rdev= stp->st_rdev; + f->size= stp->st_size; + f->mtime= stp->st_mtime; + f->atime= stp->st_atime; + f->ctime= stp->st_ctime; +#if BSD + f->blocks= stp->st_blocks; +#endif +} + +#define PAST (26*7*24*3600L) /* Half a year ago. */ +/* Between PAST and FUTURE from now a time is printed, otherwise a year. */ +#define FUTURE (15*60L) /* Fifteen minutes. */ + +static char *timestamp(struct file *f) +/* Transform the right time field into something readable. */ +{ + struct tm *tm; + time_t t; + static time_t now; + static int drift= 0; + static char date[] = "Jan 19 2038"; + static char month[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + + t= f->mtime; + if (field & F_ATIME) t= f->atime; + if (field & F_CTIME) t= f->ctime; + + tm= localtime(&t); + if (--drift < 0) { time(&now); drift= 50; } /* limit time() calls */ + + if (t < now - PAST || t > now + FUTURE) { + sprintf(date, "%.3s %2d %4d", + month + 3*tm->tm_mon, + tm->tm_mday, + 1900 + tm->tm_year); + } else { + sprintf(date, "%.3s %2d %02d:%02d", + month + 3*tm->tm_mon, + tm->tm_mday, + tm->tm_hour, tm->tm_min); + } + return date; +} + +char *permissions(struct file *f) +/* Compute long or short rwx bits. */ +{ + static char rwx[] = "drwxr-x--x"; + + rwx[0] = ifmt(f->mode); + /* Note that rwx[0] is a guess for the more alien file types. It is + * correct for BSD4.3 and derived systems. I just don't know how + * "standardized" these numbers are. + */ + + if (field & F_EXTRA) { /* Short style */ + int mode = f->mode, ucase= 0; + + if (uid == f->uid) /* What group of bits to use. */ + /* mode<<= 0, */ + ucase= (mode<<3) | (mode<<6); + /* Remember if group or others have permissions. */ + else + if (gid == f->gid) + mode<<= 3; + else + mode<<= 6; + + rwx[1]= mode&S_IRUSR ? (ucase&S_IRUSR ? 'R' : 'r') : '-'; + rwx[2]= mode&S_IWUSR ? (ucase&S_IWUSR ? 'W' : 'w') : '-'; + + if (mode&S_IXUSR) { + static char sbit[]= { 'x', 'g', 'u', 's' }; + + rwx[3]= sbit[(f->mode&(S_ISUID|S_ISGID))>>10]; + if (ucase&S_IXUSR) rwx[3] += 'A'-'a'; + } else + rwx[3]= f->mode&(S_ISUID|S_ISGID) ? '=' : '-'; + rwx[4]= 0; + } else { /* Long form. */ + char *p= rwx+1; + int mode= f->mode; + + do { + p[0] = (mode & S_IRUSR) ? 'r' : '-'; + p[1] = (mode & S_IWUSR) ? 'w' : '-'; + p[2] = (mode & S_IXUSR) ? 'x' : '-'; + mode<<= 3; + } while ((p+=3) <= rwx+7); + + if (f->mode&S_ISUID) rwx[3]= f->mode&(S_IXUSR>>0) ? 's' : '='; + if (f->mode&S_ISGID) rwx[6]= f->mode&(S_IXUSR>>3) ? 's' : '='; + if (f->mode&S_ISVTX) rwx[9]= f->mode&(S_IXUSR>>6) ? 't' : '='; + } + return rwx; +} + +void numeral(int i, char **pp) +{ + char itoa[3*sizeof(int)], *a=itoa; + + do *a++ = i%10 + '0'; while ((i/=10) > 0); + + do *(*pp)++ = *--a; while (a>itoa); +} + +#define K 1024L /* A kilobyte counts in multiples of K */ +#define T 1000L /* A megabyte in T*K, a gigabyte in T*T*K */ + +char *cxsize(struct file *f) +/* Try and fail to turn a 32 bit size into 4 readable characters. */ +{ + static char siz[] = "1.2m"; + char *p= siz; + off_t z; + + siz[1]= siz[2]= siz[3]= 0; + + if (f->size <= 5*K) { /* <= 5K prints as is. */ + numeral((int) f->size, &p); + return siz; + } + z= (f->size + K-1) / K; + + if (z <= 999) { /* Print as 123k. */ + numeral((int) z, &p); + *p = 'k'; /* Can't use 'K', looks bad */ + } else + if (z*10 <= 99*T) { /* 1.2m (Try ls -X /dev/at0) */ + z= (z*10 + T-1) / T; /* Force roundup */ + numeral((int) z / 10, &p); + *p++ = '.'; + numeral((int) z % 10, &p); + *p = 'm'; + } else + if (z <= 999*T) { /* 123m */ + numeral((int) ((z + T-1) / T), &p); + *p = 'm'; + } else { /* 1.2g */ + z= (z*10 + T*T-1) / (T*T); + numeral((int) z / 10, &p); + *p++ = '.'; + numeral((int) z % 10, &p); + *p = 'g'; + } + return siz; +} + +/* Transform size of file to number of blocks. This was once a function that + * guessed the number of indirect blocks, but that nonsense has been removed. + */ +#if BSD +#define nblocks(f) ((f)->blocks) +#else +#define nblocks(f) (((f)->size + BLOCK-1) / BLOCK) +#endif + +/* From number of blocks to kilobytes. */ +#if BLOCK < 1024 +#define nblk2k(nb) (((nb) + (1024 / BLOCK - 1)) / (1024 / BLOCK)) +#else +#define nblk2k(nb) ((nb) * (BLOCK / 1024)) +#endif + +static int (*CMP)(struct file *f1, struct file *f2); +static int (*rCMP)(struct file *f1, struct file *f2); + +static void mergesort(struct file **al) +/* This is either a stable mergesort, or thermal noise, I'm no longer sure. + * It must be called like this: if (L != nil && L->next != nil) mergesort(&L); + */ +{ + /* static */ struct file *l1, **mid; /* Need not be local */ + struct file *l2; + + l1= *(mid= &(*al)->next); + do { + if ((l1= l1->next) == nil) break; + mid= &(*mid)->next; + } while ((l1= l1->next) != nil); + + l2= *mid; + *mid= nil; + + if ((*al)->next != nil) mergesort(al); + if (l2->next != nil) mergesort(&l2); + + l1= *al; + for (;;) { + if ((*CMP)(l1, l2) <= 0) { + if ((l1= *(al= &l1->next)) == nil) { + *al= l2; + break; + } + } else { + *al= l2; + l2= *(al= &l2->next); + *al= l1; + if (l2 == nil) break; + } + } +} + +int namecmp(struct file *f1, struct file *f2) +{ + return strcmp(f1->name, f2->name); +} + +int mtimecmp(struct file *f1, struct file *f2) +{ + return f1->mtime == f2->mtime ? 0 : f1->mtime > f2->mtime ? -1 : 1; +} + +int atimecmp(struct file *f1, struct file *f2) +{ + return f1->atime == f2->atime ? 0 : f1->atime > f2->atime ? -1 : 1; +} + +int ctimecmp(struct file *f1, struct file *f2) +{ + return f1->ctime == f2->ctime ? 0 : f1->ctime > f2->ctime ? -1 : 1; +} + +int typecmp(struct file *f1, struct file *f2) +{ + return ifmt(f1->mode) - ifmt(f2->mode); +} + +int revcmp(struct file *f1, struct file *f2) { return (*rCMP)(f2, f1); } + +static void sort(struct file **al) +/* Sort the files according to the flags. */ +{ + if (!present('f') && *al != nil && (*al)->next != nil) { + CMP= namecmp; + + if (!(field & F_BYTIME)) { + /* Sort on name */ + + if (present('r')) { rCMP= CMP; CMP= revcmp; } + mergesort(al); + } else { + /* Sort on name first, then sort on time. */ + + mergesort(al); + if (field & F_CTIME) + CMP= ctimecmp; + else + if (field & F_ATIME) + CMP= atimecmp; + else + CMP= mtimecmp; + + if (present('r')) { rCMP= CMP; CMP= revcmp; } + mergesort(al); + } + /* Separate by file type if so desired. */ + + if (field & F_TYPE) { + CMP= typecmp; + mergesort(al); + } + } +} + +struct file *newfile(char *name) +/* Create file structure for given name. */ +{ + struct file *new; + + new= (struct file *) allocate(sizeof(*new)); + new->name= strcpy((char *) allocate(strlen(name)+1), name); + return new; +} + +void pushfile(struct file **flist, struct file *new) +/* Add file to the head of a list. */ +{ + new->next= *flist; + *flist= new; +} + +void delfile(struct file *old) +/* Release old file structure. */ +{ + free((void *) old->name); + free((void *) old); +} + +struct file *popfile(struct file **flist) +/* Pop file off top of file list. */ +{ + struct file *f; + + f= *flist; + *flist= f->next; + return f; +} + +int dotflag(char *name) +/* Return flag that would make ls list this name: -a or -A. */ +{ + if (*name++ != '.') return 0; + + switch (*name++) { + case 0: return 'a'; /* "." */ + case '.': if (*name == 0) return 'a'; /* ".." */ + default: return 'A'; /* ".*" */ + } +} + +int adddir(struct file **aflist, char *name) +/* Add directory entries of directory name to a file list. */ +{ + DIR *d; + struct dirent *e; + + if (access(name, 0) < 0) { + report(name); + return 0; + } + + if ((d= opendir(name)) == nil) { + report(name); + return 0; + } + while ((e= readdir(d)) != nil) { + if (e->d_ino != 0 && present(dotflag(e->d_name))) { + pushfile(aflist, newfile(e->d_name)); + aflist= &(*aflist)->next; + } + } + closedir(d); + return 1; +} + +off_t countblocks(struct file *flist) +/* Compute total block count for a list of files. */ +{ + off_t cb = 0; + + while (flist != nil) { + switch (flist->mode & S_IFMT) { + case S_IFDIR: + case S_IFREG: +#ifdef S_IFLNK + case S_IFLNK: +#endif + cb += nblocks(flist); + } + flist= flist->next; + } + return cb; +} + +void printname(char *name) +/* Print a name with control characters as '?' (unless -q). The terminal is + * assumed to be eight bit clean. + */ +{ + int c, q= present('q'); + + while ((c= *name++) != 0) { + if (q && (c <= ' ' || c == 0177)) c= '?'; + putchar(c); + } +} + +int mark(struct file *f, int doit) +{ + int c; + + if (!(field & F_MARK)) return 0; + + switch (f->mode & S_IFMT) { + case S_IFDIR: c= '/'; break; +#ifdef S_IFIFO + case S_IFIFO: c= '|'; break; +#endif +#ifdef S_IFLNK + case S_IFLNK: c= '@'; break; +#endif +#ifdef S_IFSOCK + case S_IFSOCK: c= '='; break; +#endif + case S_IFREG: + if (f->mode & (S_IXUSR | S_IXGRP | S_IXOTH)) { + c= '*'; + break; + } + default: + c= 0; + } + if (doit && c != 0) putchar(c); + return c; +} + +int colwidth[MAXCOLS]; /* Need colwidth[i] spaces to print column i. */ +int sizwidth[MAXCOLS]; /* Spaces for the size field in a -X print. */ +int namwidth[MAXCOLS]; /* Name field. */ + +int maxise(int *aw, int w) +/* Set *aw to the larger of it and w. Then return it. */ +{ + if (w > *aw) *aw= w; + return *aw; +} + +static int nsp= 0; /* This many spaces have not been printed yet. */ +#define spaces(n) (nsp= (n)) +#define terpri() (nsp= 0, putchar('\n')) /* No trailing spaces */ + +void print1(struct file *f, int col, int doit) +/* Either compute the number of spaces needed to print file f (doit == 0) or + * really print it (doit == 1). + */ +{ + int width= 0, n; + char *p; + + while (nsp>0) { putchar(' '); nsp--; }/* Fill gap between two columns */ + + if (field & F_INODE) { + if (doit) printf("%5d ", f->ino); else width+= 6; + } + if (field & F_BLOCKS) { + if (doit) printf("%4ld ", nblk2k(nblocks(f))); else width+= 5; + } + if (field & F_MODE) { + if (doit) + printf("%s ", permissions(f)); + else + width+= (field & F_EXTRA) ? 5 : 11; + } + if (field & F_EXTRA) { + p= cxsize(f); + n= strlen(p)+1; + + if (doit) { + n= sizwidth[col] - n; + while (n > 0) { putchar(' '); --n; } + printf("%s ", p); + } else + width+= maxise(&sizwidth[col], n); + } + if (field & F_LONG) { + if (doit) { + printf("%2d %-8s ", f->nlink, uidname(f->uid)); + if (field & F_GROUP) printf("%-8s ", gidname(f->gid)); + + switch (f->mode & S_IFMT) { + case S_IFBLK: + case S_IFCHR: +#ifdef S_IFMPB + case S_IFMPB: +#endif +#ifdef S_IFMPC + case S_IFMPC: +#endif + printf("%3d, %3d ", + major(f->rdev), minor(f->rdev)); + break; + default: + printf("%8ld ", (long) f->size); + } + printf("%s ", timestamp(f)); + } else + width += (field & F_GROUP) ? 43 : 34; + } + n= strlen(f->name); + if (doit) { + printname(f->name); + if (mark(f, 1) != 0) n++; +#ifdef S_IFLNK + if ((field & F_LONG) && (f->mode & S_IFMT) == S_IFLNK) { + char *buf; + int r, didx; + + buf= (char *) allocate(((size_t) f->size + 1) + * sizeof(buf[0])); + addpath(&didx, f->name); + r= readlink(path, buf, (int) f->size); + delpath(didx); + if (r > 0) buf[r] = 0; else r=1, strcpy(buf, "?"); + printf(" -> "); + printname(buf); + free((void *) buf); + n+= 4 + r; + } +#endif + spaces(namwidth[col] - n); + } else { + if (mark(f, 0) != 0) n++; +#ifdef S_IFLNK + if ((field & F_LONG) && (f->mode & S_IFMT) == S_IFLNK) { + n+= 4 + (int) f->size; + } +#endif + width+= maxise(&namwidth[col], n + NSEP); + maxise(&colwidth[col], width); + } +} + +int countfiles(struct file *flist) +/* Return number of files in the list. */ +{ + int n= 0; + + while (flist != nil) { n++; flist= flist->next; } + + return n; +} + +struct file *filecol[MAXCOLS]; /* filecol[i] is list of files for column i. */ +int nfiles, nlines; /* # files to print, # of lines needed. */ + +int columnise(struct file *flist, int nplin) +/* Chop list of files up in columns. Note that 3 columns are used for 5 files + * even though nplin may be 4, filecol[3] will simply be nil. + */ +{ + int i, j; + + nlines= (nfiles + nplin - 1) / nplin; /* nlines needed for nfiles */ + + filecol[0]= flist; + + for (i=1; i<nplin; i++) { /* Give nlines files to each column. */ + for (j=0; j<nlines && flist != nil; j++) flist= flist->next; + + filecol[i]= flist; + } +} + +int print(struct file *flist, int nplin, int doit) +/* Try (doit == 0), or really print the list of files over nplin columns. + * Return true if it can be done in nplin columns or if nplin == 1. + */ +{ + register struct file *f; + register int i, totlen; + + columnise(flist, nplin); + + if (!doit) { + if (nplin==1 && !(field & F_EXTRA)) + return 1; /* No need to try 1 column. */ + + for (i=0; i<nplin; i++) + colwidth[i]= sizwidth[i]= namwidth[i]= 0; + } + while (--nlines >= 0) { + totlen=0; + + for (i=0; i<nplin; i++) { + if ((f= filecol[i]) != nil) { + filecol[i]= f->next; + print1(f, i, doit); + } + if (!doit && nplin>1) { + /* See if this line is not too long. */ + totlen+= colwidth[i]; + if (totlen > ncols+NSEP) return 0; + } + } + if (doit) terpri(); + } + return 1; +} + +enum depth { SURFACE, SURFACE1, SUBMERGED }; +enum state { BOTTOM, SINKING, FLOATING }; + +void listfiles(struct file *flist, enum depth depth, enum state state) +/* Main workhorse of ls, it sorts and prints the list of files. Flags: + * depth: working with the command line / just one file / listing dir. + * state: How "recursive" do we have to be. + */ +{ + struct file *dlist= nil, **afl= &flist, **adl= &dlist; + int nplin; + static int white = 1; /* Nothing printed yet. */ + + /* Flush everything previously printed, so new error output will + * not intermix with files listed earlier. + */ + fflush(stdout); + + if (field != 0 || state != BOTTOM) { /* Need stat(2) info. */ + while (*afl != nil) { + static struct stat st; + int r, didx; + + addpath(&didx, (*afl)->name); + + if ((r= status(path, &st)) < 0 +#ifdef S_IFLNK + && (status == lstat || lstat(path, &st) < 0) +#endif + ) { + if (depth != SUBMERGED || errno != ENOENT) + report((*afl)->name); + delfile(popfile(afl)); + } else { + setstat(*afl, &st); + afl= &(*afl)->next; + } + delpath(didx); + } + } + sort(&flist); + + if (depth == SUBMERGED && (field & (F_BLOCKS | F_LONG))) + printf("total %ld\n", nblk2k(countblocks(flist))); + + if (state == SINKING || depth == SURFACE1) { + /* Don't list directories themselves, list their contents later. */ + afl= &flist; + while (*afl != nil) { + if (((*afl)->mode & S_IFMT) == S_IFDIR) { + pushfile(adl, popfile(afl)); + adl= &(*adl)->next; + } else + afl= &(*afl)->next; + } + } + + if ((nfiles= countfiles(flist)) > 0) { + /* Print files in how many columns? */ + nplin= !present('C') ? 1 : nfiles < MAXCOLS ? nfiles : MAXCOLS; + + while (!print(flist, nplin, 0)) nplin--; /* Try first */ + + print(flist, nplin, 1); /* Then do it! */ + white = 0; + } + + while (flist != nil) { /* Destroy file list */ + if (state == FLOATING && (flist->mode & S_IFMT) == S_IFDIR) { + /* But keep these directories for ls -R. */ + pushfile(adl, popfile(&flist)); + adl= &(*adl)->next; + } else + delfile(popfile(&flist)); + } + + while (dlist != nil) { /* List directories */ + if (dotflag(dlist->name) != 'a' || depth != SUBMERGED) { + int didx; + + addpath(&didx, dlist->name); + + flist= nil; + if (adddir(&flist, path)) { + if (depth != SURFACE1) { + if (!white) putchar('\n'); + printf("%s:\n", path); + white = 0; + } + listfiles(flist, SUBMERGED, + state == FLOATING ? FLOATING : BOTTOM); + } + delpath(didx); + } + delfile(popfile(&dlist)); + } +} + +int main(int argc, char **argv) +{ + struct file *flist= nil, **aflist= &flist; + enum depth depth; + char *lsflags; +#ifdef TIOCGWINSZ + struct winsize ws; +#endif + + uid= geteuid(); + gid= getegid(); + + if ((arg0= strrchr(argv[0], '/')) == nil) arg0= argv[0]; else arg0++; + argv++; + + if (strcmp(arg0, "ls") != 0) { + char *p= arg0+1; + + while (*p != 0) { + if (strchr(arg0flag, *p) != nil) *p += 'A' - 'a'; + p++; + } + setflags(arg0+1); + } + while (*argv != nil && (*argv)[0] == '-') { + if ((*argv)[1] == '-' && (*argv)[2] == 0) { + argv++; + break; + } + setflags(*argv++ + 1); + } + + istty= isatty(1); + + if (istty && (lsflags= getenv("LSOPTS")) != nil) { + if (*lsflags == '-') lsflags++; + setflags(lsflags); + } + + if (!present('1') && !present('C') && !present('l') + && (istty || present('M') || present('X') || present('F')) + ) setflags("C"); + + if (istty) setflags("q"); + + if (SUPER_ID == 0 || present('a')) setflags("A"); + + if (present('i')) field|= F_INODE; + if (present('s')) field|= F_BLOCKS; + if (present('M')) field|= F_MODE; + if (present('X')) field|= F_EXTRA|F_MODE; + if (present('t')) field|= F_BYTIME; + if (present('u')) field|= F_ATIME; + if (present('c')) field|= F_CTIME; + if (present('l')) { + field= (field | F_MODE | F_LONG) & ~F_EXTRA; + if (present('g')) field|= F_GROUP; + } + if (present('F')) field|= F_MARK; + if (present('T')) field|= F_TYPE; + if (present('d')) field|= F_DIR; + +#ifdef S_IFLNK + status= present('L') ? stat : lstat; +#endif + +#ifdef TIOCGWINSZ + if (present('C')) { + int t= istty ? 1 : open("/dev/tty", O_WRONLY); + + if (t >= 0 && ioctl(t, TIOCGWINSZ, &ws) == 0 && ws.ws_col > 0) + ncols= ws.ws_col - 1; + + if (t != 1) close(t); + } +#endif + + depth= SURFACE; + + if (*argv == nil) { + if (!(field & F_DIR)) depth= SURFACE1; + pushfile(aflist, newfile(".")); + } else { + if (argv[1] == nil && !(field & F_DIR)) depth= SURFACE1; + + do { + pushfile(aflist, newfile(*argv++)); + aflist= &(*aflist)->next; + } while (*argv!=nil); + } + listfiles(flist, depth, + (field & F_DIR) ? BOTTOM : present('R') ? FLOATING : SINKING); + exit(ex); +} +/* Kees J. Bot 25-4-89. */ diff --git a/libc-0.0.4/tests/makefile b/libc-0.0.4/tests/makefile new file mode 100644 index 0000000..150bf45 --- /dev/null +++ b/libc-0.0.4/tests/makefile @@ -0,0 +1,17 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +TOP=.. +include $(TOP)/Make.defs +CFLAGS=$(CCFLAGS) -ansi + +default: all + +include Real_make + +fetch_them: + cp -p $(SRC) Real_make $(TOPDIR)/tests/. + +clean: + rm -f $(OBJ) $(EXE) $(LINK_FILES) diff --git a/libc-0.0.4/tests/ouch.c b/libc-0.0.4/tests/ouch.c new file mode 100644 index 0000000..c2925c6 --- /dev/null +++ b/libc-0.0.4/tests/ouch.c @@ -0,0 +1,27 @@ + +#include <signal.h> +#include <stdio.h> +#include <errno.h> + +void trap() +{ + write(1, "Ouch!!\n", 7); +} + +main() +{ + char buf[2]; + int cc; + + signal(SIGINT, trap); + while( (cc=read(0, buf, 1)) > 0 || (cc == -1 && errno == EINTR) ) + { + if( cc < 0 ) + fprintf(stderr, "INTR\n"); + else + fprintf(stderr, "%x\n", buf[0]); + } + + + write(1, "\nExit!\n", 7); +} diff --git a/libc-0.0.4/tests/rand.c b/libc-0.0.4/tests/rand.c new file mode 100644 index 0000000..c4fc6d2 --- /dev/null +++ b/libc-0.0.4/tests/rand.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +FILE * popen(); + +main() +{ + FILE * fd = popen("./hd", "w"); + int ch; + + srand(time((void*)0)); + + for(ch=0; ch<256; ch++) + putc(rand(), fd); + + pclose(fd); +} diff --git a/libc-0.0.4/tests/size.c b/libc-0.0.4/tests/size.c new file mode 100644 index 0000000..2d6676b --- /dev/null +++ b/libc-0.0.4/tests/size.c @@ -0,0 +1,51 @@ +#include <fcntl.h> +#include <a.out.h> + +void size(filename) + char *filename; +{ + int f; + struct exec ex; + long total; + int cc; + + if ((f = open(filename, O_RDONLY)) < 0 ) + { + perror(filename); + return; + } + cc = read(f, &ex, sizeof(ex)); + + if (cc == sizeof(ex) && !BADMAG(ex)) + { + total = ex.a_text + ex.a_data + ex.a_bss; + printf("%-ld\t%-ld\t%-ld\t%-ld\t%-lx\t%s\n", + ex.a_text, ex.a_data, ex.a_bss, total, total, + filename); + } + else if( cc > 16 && memcmp(&ex, "\243\206\001\000*", 5) == 0 ) + { /* *.o file */ + total = ((unsigned char*)&ex)[9] + + ((unsigned char*)&ex)[10] * 256; + printf("\t\t\t%-ld\t%-lx\t%s\n", + total, total, filename); + } + else + printf("%s: Not an a.out file\n", filename); + close(f); +} + +int main(argc, argv) + int argc; + char **argv; +{ + if (argc < 2) + { + printf("Usage: %s file\n", argv[0]); + exit(1); + } + printf("text\tdata\tbss\tdec\thex\tfilename\n"); + for (--argc, ++argv; argc > 0; --argc, ++argv) + size(*argv); + exit(0); +} diff --git a/libc-0.0.4/tests/sync.c b/libc-0.0.4/tests/sync.c new file mode 100644 index 0000000..03ca096 --- /dev/null +++ b/libc-0.0.4/tests/sync.c @@ -0,0 +1 @@ +int main() { return sync(); } diff --git a/libc-0.0.4/tests/ucomp.c b/libc-0.0.4/tests/ucomp.c new file mode 100644 index 0000000..cc3eef8 --- /dev/null +++ b/libc-0.0.4/tests/ucomp.c @@ -0,0 +1,108 @@ + +/* + * Uncompress program this is very very fast + * + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <malloc.h> + +#define MAXLEN 255 + +#define maxno 61000U +#define USE_BSS + +#ifdef USE_BSS +unsigned char fptr[maxno]; +#else +unsigned char *fptr; +#endif +FILE * fd; +int key; + +main(argc, argv) +int argc; +char ** argv; +{ +#ifndef USE_BSS + fptr = (unsigned char * ) malloc(maxno); + + if( fptr == 0 ) + { + perror("Cannot allocate memory"); + exit(1); + } +#endif + + if( argc < 2 ) + { + fd = stdin; + key = getc(fd); + uncompress(); + } + else + { + fd = fopen(argv[1], "r" ); + if( fd == 0 ) { perror("Open failed"); exit(1); } + + key = getc(fd); + uncompress(); + } +} + +/* + + Uncompression routine -- v.v.fast +*/ + +uncompress() +{ + register unsigned char * mainscan; + register unsigned char * secondscan; + register unsigned char * ptr = (unsigned char * ) fptr; + register unsigned char * eptr = ptr+maxno; + register unsigned int len; + register int ch; + + mainscan = ptr; + + for(;;) + { + ch = getc(fd); + if(ch == EOF) break; + ch &= 0xFF; + if(ch == key) + { + ch = getc(fd); + if( ch == 0 ) + *mainscan++ = key; + else + { + len = (unsigned char) getc(fd); + if( ch & 0x80 ) + len += ((unsigned char) getc(fd)) << 8; + secondscan = mainscan - len; + if(len > mainscan - ptr) secondscan += maxno; + len = (unsigned char) ch & 0x7F; + for( ; len>0; len-- ) + { + *mainscan++ = *secondscan++; + if( secondscan == eptr ) secondscan = ptr; + if( mainscan == eptr ) + { write(1, ptr, (int)(mainscan-ptr)); mainscan = ptr; } + } + } + } + else + *mainscan++ = ch; + + if( mainscan == eptr ) + { write(1, ptr, (int)(mainscan-ptr)); mainscan = ptr; } + } + if( mainscan != ptr ) + { write(1, ptr, (int)(mainscan-ptr)); mainscan = ptr; } +} + diff --git a/libc-0.0.4/tests/wc.c b/libc-0.0.4/tests/wc.c new file mode 100644 index 0000000..08b93ca --- /dev/null +++ b/libc-0.0.4/tests/wc.c @@ -0,0 +1,133 @@ + +#include <stdio.h> +#include <ctype.h> + +int lflag; /* Want count lines */ +int wflag; /* Want count words */ +int cflag; /* Want count characters */ + +long lcount; /* File count of lines */ +long wcount; /* File count of words */ +long ccount; /* File count of characters */ + +long ltotal; /* Total count of lines */ +long wtotal; /* Total count of words */ +long ctotal; /* Total count of characters */ + +int +main(argc, argv) +int argc; +char **argv; +{ + char *p; + int ar; + + if (argc > 1 && argv[1][0] == '-') + { + for (p = argv[1] + 1; *p; p++) + { + switch (*p) + { + case 'l': + lflag++; + break; + case 'w': + wflag++; + break; + case 'c': + cflag++; + break; + default: + Usage(); + } + } + argc--; + argv++; + } + + /* If no flags are set, treat as wc -lwc. */ + if (!lflag && !wflag && !cflag) + lflag = wflag = cflag = 1; + + /* No filename, use stdin */ + if (argc == 1) + { + count(stdin, ""); + exit(0); + } + + /* There is an explicit list of files. Loop on files. */ + for (ar = 1; ar < argc; ar++) + { + FILE *f; + + if ((f = fopen(argv[ar], "r")) == NULL) + fprintf(stderr, "wc: cannot open %s\n", argv[ar]); + else + { + count(f, argv[ar]); + fclose(f); + } + } + + if (argc > 2) + { + if (lflag) + printf("%7ld ", ltotal); + if (wflag) + printf("%7ld ", wtotal); + if (cflag) + printf("%7ld ", ctotal); + printf("total\n"); + } + exit(0); +} + +count(f, fname) +FILE *f; +char *fname; +{ + register int c; + register int inword = 0; + + lcount = 0; + wcount = 0; + ccount = 0; + + while ((c = getc(f)) != EOF) + { + ccount++; + + if (isspace(c)) + { + if (inword) + wcount++; + inword = 0; + } + else + inword = 1; + + if (c == '\n' || c == '\f') + lcount++; + } + + ltotal += lcount; + wtotal += wcount; + ctotal += ccount; + + if (lflag) + printf("%7ld ", lcount); + if (wflag) + printf("%7ld ", wcount); + if (cflag) + printf("%7ld ", ccount); + if (fname && *fname) + printf("%s", fname); + printf("\n"); +} + +Usage() +{ + fprintf(stderr, "Usage: wc [-lwc] [name ...]\n"); + exit(1); +} diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..52eb94a --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,23 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +CC=bcc +CFLAGS=-O -ansi +LDFLAGS= + +ifeq (Real_make,$(wildcard Real_make)) +include Real_make +endif + +ifneq ($(TOPDIR),) +starter: + make -C ../libc/tests fetch_them + make all +endif + +not_from_here: + @echo Do make tests from the top directory + +clean: + rm -f Real_make $(SRC) $(OBJ) $(EXE) $(LINK_FILES) diff --git a/unproto/Makefile b/unproto/Makefile new file mode 100644 index 0000000..638be25 --- /dev/null +++ b/unproto/Makefile @@ -0,0 +1,97 @@ +# @(#) Makefile 1.3 91/12/01 12:37:57 + +## BEGIN CONFIGURATION STUFF + +# For maximal flexibility, the "/lib/cpp | unproto" pipeline can be +# packaged as an executable shell script (see the provided "cpp.sh" script) +# that should be installed as "/whatever/cpp". This script should then be +# specified to the C compiler as a non-default preprocessor. +# +PROG = unproto +PIPE = + +# For maximal performance, the overhead of shell script inpretation can +# be eliminated by having the unprototyper program itself open the pipe +# to the preprocessor. In that case, define the PIPE_THROUGH_CPP macro +# as the path name of the default C preprocessor (usually "/lib/cpp"), +# install the unprototyper as "/whatever/cpp" and specify that to the C +# compiler as a non-default preprocessor. +# +# PROG = cpp +# PIPE = -DPIPE_THROUGH_CPP=\"/lib/cpp\" + +# Some compilers complain about some #directives. The following is only a +# partial solution, because the directives are still seen by /lib/cpp. +# Be careful with filtering out #pragma, because some non-ANSI compilers +# (SunOS) rely on its use. +# +# SKIP = -DIGNORE_DIRECTIVES=\"pragma\",\"foo\",\"bar\" +# +SKIP = + +# If you need support for functions that implement ANSI-style variable +# length argument lists, edit the stdarg.h file provided with this +# package so that it contains the proper definitions for your machine. + +## END CONFIGURATION STUFF + +SHELL = /bin/sh + +CFILES = tok_io.c tok_class.c tok_pool.c unproto.c vstring.c symbol.c error.c +HFILES = error.h token.h vstring.h symbol.h +SCRIPTS = cpp.sh +SAMPLES = stdarg.h varargs.c example.c example.out +SOURCES = README Makefile $(CFILES) $(HFILES) $(SCRIPTS) $(SAMPLES) +FILES = $(SOURCES) unproto.1 +OBJECTS = tok_io.o tok_class.o tok_pool.o unproto.o vstring.o symbol.o error.o + +ifneq ($(TOPDIR),) +include $(TOPDIR)/Make.defs +CFLAGS=$(CCFLAGS) $(PIPE) $(SKIP) +else +CC=bcc +CFLAGS=-O $(PIPE) $(SKIP) +LDFLAGS=-s +endif + +#CFLAGS = -O -pg -Dstatic= $(PIPE) $(SKIP) +#CFLAGS = -g $(PIPE) $(SKIP) -DDEBUG + +$(PROG): $(OBJECTS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(MALLOC) + +install: $(PROG) + install -d $(LIBDIR) + install -m 755 $(PROG) $(LIBDIR)/unproto + +# For linting, enable all bells and whistles. + +lint: + lint -DPIPE_THROUGH_CPP=\"foo\" -DIGNORE_DIRECTIVES=\"foo\",\"bar\" \ + $(CFILES) + +# Testing requires that the program is compiled with -DDEBUG + +test: $(PROG) example.c example.out + ./cpp example.c >example.tmp + @echo the following diff command should produce no output + diff -b example.out example.tmp + rm -f example.tmp + +shar: $(FILES) + @shar $(FILES) + +archive: + $(ARCHIVE) $(SOURCES) + +clean: + rm -f *.o core cpp unproto mon.out varargs.o varargs example.tmp + +error.o : error.c token.h error.h Makefile +symbol.o : symbol.c token.h symbol.h Makefile +tok_class.o : tok_class.c error.h vstring.h token.h symbol.h Makefile +tok_io.o : tok_io.c token.h vstring.h error.h Makefile +tok_pool.o : tok_pool.c token.h vstring.h Makefile +unproto.o : unproto.c vstring.h stdarg.h token.h error.h symbol.h Makefile +varargs.o : varargs.c stdarg.h Makefile +vstring.o : vstring.c vstring.h Makefile diff --git a/unproto/README b/unproto/README new file mode 100644 index 0000000..6856d3a --- /dev/null +++ b/unproto/README @@ -0,0 +1,130 @@ +@(#) README 1.3 91/12/01 12:37:55 + +unproto - ANSI C to old C converter + +Purpose: + +This is a filter that sits in between the C preprocessor and the next C +compiler stage, and that on the fly rewrites ANSI C to old C. Its +primary application is to compile ANSI C software in UNIX environments +that do not (yet) have an ANSI C compiler and that cannot run GCC +because of technical or political problems. + +The filter leaves old-style C alone, and de-ANSI-fies function +headings, function pointer type declarations (and casts), function type +declarations, and combinations thereof. Many freely-distributable +unprotoizers have problems with the latter because they are based on a +non-recursive algorithm or even make assumptions about code layout. + +The unprototyper has support for systems that require special tricks +for variadic functions (fortunately, many don't). A sample `stdarg.h' +file is provided with support for sparc, mc68k, 80x86, vax and others. + +The program has been tested on a Sun SLC running SunOS 4.1.1 and on a +80286 PC clone running Microport's version of System V Release 2. It +runs at about the same speed as /lib/cpp, so it should have negigible +impact on compilation times. + +Problems solved with this release: + +Minor: the program was originally intended for the compilation of +already tested ANSI C source, so that diagnostics from the native C +compiler would be sufficient. The present release produces better +diagnostics, so that it can also be used for program development. + +Major: the template Makefile suggested that all #pragma directives be +filtered out. This turns out to be a bad idea because some non-ANSI +compilers (SunOS) rely on #pragmas to correctly handle the unusual flow +control caused by vfork(2), setjmp(3) etcetera. A warning to this +effect has been added to the Makefile. + +No changes were made to the actual filter logic; output should be +identical to that of the previous release. + +Restrictions: + +Other ANSI-isms are just passed on without modification, such as +trigraphs, token pasting (##), #pragmas, stringizing (#text) and +string concatenation ("string1" "string2"). + +The unprototyper does not understand declarations of (object). The +result (the object disappears) will be a syntax error so this should +not go by unnoticed. + +Some C programmers rely on ANSI-style prototypes for the automatic type +conversion of function arguments. The unprototyper, however, does not +generate casts. The lack of automatic conversion between integral +and/or pointer argument types should not be a problem in environments +where sizeof(int) == sizeof(long) == sizeof(pointer). A more serious +problem is the lack of automatic type conversions beteen integral and +floating-point function argument types. Let lint(1) be your friend. + +Operation: + +This package implements an non-default C preprocessor (the output from +the default C preprocessor being piped through the unprototyper). How +one tells the C compiler to use an non-default preprocessor program is +somewhat compiler-dependent: + + SunOS 4.x: cc -Qpath directory_with_non-default_cpp ... + + SysV Rel2: cc -Bdirectory_with_non-default_cpp/ -tp ... + +Your C compiler manual should provide the necessary information. + +On some systems the lint(1) command is just a shell script, and writing +a version that uses the unprototyper should not be too hard. With SunOS +4.x, /usr/bin/lint is not a shell script, but it does accept the same +syntax as the cc(1) command for the specification of a non-default +compiler pass. + +You may have to do some research on the lint command provided with your +own machine. + +Configuration: + +Check the contents of the `stdarg.h' file provided with this package. +This file serves a dual purpose. It should be included by C source file +that implements ANSI-style variadic functions. It is also used to +configure the `unproto' program so that it emits the proper magic for +the `...' construct. + +The `stdarg.h' file contains definitions for the sparc architecture and +for architectures that pass arguments via the stack (usually OK for +80*86, mc68k and vax C compilers). Risc processors often need special +tricks. These are usually found in the file `/usr/include/varargs.h'. + +The file `varargs.c' provided with this package can be used to verify +that the `stdarg.h' file has been set up correctly. + +For maximal flexibility, you can use the `cpp' shell script provided +with this package to set up the pipe between the default C preprocessor +and the unprototyper command. The script assumes that the unprototyper +binary is called `unproto'. See the cpp.sh script and the Makefile for +details. + +The overhead of shell-script interpretation can be avoided by having +the unprototyper itself open the pipe to the C preprocessor. In this +case, the `unproto.c' source file should be compiled with the +`PIPE_THROUGH_CPP' macro defined as the pathname of the C preprocessor +(usually `/lib/cpp'), and the unprototyper binary should be called +`cpp'. See the Makefile for details. + +Installation: + +Install the `stdarg.h' include file and the `unproto.1' manual page in +suitable places. + +If you use the `cpp' shell script to pipe the preprocessor output +through the unprototyper program, install the `unproto' binary in a +place where the `cpp' shell script can find it, and install the `cpp' +shell script in a suitable place. + +If the unprototyper itself opens the pipe to the C preprocessor (i.e. +the unprototyper was built with the `PIPE_THROUGH_CPP' macro defined), +install the `cpp' unprototyper binary in a suitable place. + + Wietse Venema + wietse@wzv.win.tue.nl + Eindhoven University of Technology + The Netherlands diff --git a/unproto/Shar.Headers b/unproto/Shar.Headers new file mode 100644 index 0000000..d707a4f --- /dev/null +++ b/unproto/Shar.Headers @@ -0,0 +1,50 @@ +Newsgroups: comp.sources.misc +From: wietse@wzv.win.tue.nl (Wietse Venema) +Subject: v26i094: unproto - compile ANSI C with old C compiler, Part01/02 +Message-ID: <csm-v26i094=unproto.083344@sparky.IMD.Sterling.COM> +X-Md4-Signature: 69685c0673793ce6c539657a3d1de2ab +Date: Sun, 1 Dec 1991 14:35:08 GMT +Approved: kent@sparky.imd.sterling.com + +Submitted-by: wietse@wzv.win.tue.nl (Wietse Venema) +Posting-number: Volume 26, Issue 94 +Archive-name: unproto/part01 +Environment: SYSV2, SunOS +Supersedes: unproto: Volume 23, Issue 12-13 + +This is a filter that sits in between the C preprocessor and the next C +compiler stage, and that on the fly rewrites ANSI C to old C. Its +primary application is to compile ANSI C software in UNIX environments +that do not (yet) have an ANSI C compiler and that cannot run GCC +because of technical or political problems. + +Problems solved with this release: + +Minor: the program was originally intended for the compilation of +already tested ANSI C source, so that diagnostics from the native C +compiler would be sufficient. The present release produces better +diagnostics, so that it can also be used for program development. + +Major: the template Makefile suggested that all #pragma directives be +filtered out. This turns out to be a bad idea because some non-ANSI +compilers (SunOS) rely on #pragmas to correctly handle the unusual flow +control caused by vfork(2), setjmp(3) etcetera. A warning to this +effect has been added to the Makefile. + +No changes were made to the actual filter logic; output should be +identical to that of the previous release. + +Newsgroups: comp.sources.misc +From: wietse@wzv.win.tue.nl (Wietse Venema) +Subject: v26i095: unproto - compile ANSI C with old C compiler, Part02/02 +Message-ID: <1991Dec1.143532.21763@sparky.imd.sterling.com> +X-Md4-Signature: e41270a11de3ed19fd262a273924fc94 +Date: Sun, 1 Dec 1991 14:35:32 GMT +Approved: kent@sparky.imd.sterling.com + +Submitted-by: wietse@wzv.win.tue.nl (Wietse Venema) +Posting-number: Volume 26, Issue 95 +Archive-name: unproto/part02 +Environment: SYSV2, SunOS +Supersedes: unproto: Volume 23, Issue 12-13 + diff --git a/unproto/cpp.sh b/unproto/cpp.sh new file mode 100644 index 0000000..8122b68 --- /dev/null +++ b/unproto/cpp.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# @(#) cpp.sh 1.2 91/09/22 21:21:43 + +# Unprototypeing preprocessor for non-ANSI C compilers. Define __STDC__ +# if you have enough courage. You will have to modify this script if +# your cc(1) command specifies output file names to the preprocessor. + +exec /lib/cpp "$@" -Dconst= -Dvolatile= | unproto diff --git a/unproto/error.c b/unproto/error.c new file mode 100644 index 0000000..bc9702b --- /dev/null +++ b/unproto/error.c @@ -0,0 +1,78 @@ +/*++ +/* NAME +/* error 3 +/* SUMMARY +/* diagnostics +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "error.h" +/* +/* void error(quit, text) +/* int quit; +/* char *text; +/* +/* void error_where(quit, path, line, text) +/* int quit; +/* char *path; +/* int line; +/* char *text; +/* DESCRIPTION +/* The routines in this file print a diagnostic (text) and optionally +/* terminate the program (quit != 0) with exit status "quit". +/* +/* error() provides a default context, i.e. the source-file +/* coordinate of the last read token. +/* +/* error_where() allows the caller to explicitly specify context: path +/* is a source-file name, and line is a line number. +/* +/* context is ignored if the line number is zero or if the path +/* is an empty string. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/11/30 21:10:35 +/* VERSION/RELEASE +/* 1.1 +/*--*/ + +static char error_sccsid[] = "@(#) error.c 1.1 91/11/30 21:10:35"; + +/* C library */ + +#include <stdio.h> + +void exit(); + +/* Application-specific stuff */ + +#include "token.h" +#include "error.h" + +/* error - report problem (implicit context) and optionally quit */ + +void error(quit, text) +int quit; +char *text; +{ + error_where(quit, curr_path, curr_line, text); +} + +/* error_where - report problem (explicit context) and optionally quit */ + +void error_where(quit, path, line, text) +int quit; +char *path; +int line; +char *text; +{ + if (line && path[0]) + fprintf(stderr, "%s, line %d: ", path, line); + fprintf(stderr, "%s\n", text); + if (quit) + exit(quit); +} diff --git a/unproto/error.h b/unproto/error.h new file mode 100644 index 0000000..579906d --- /dev/null +++ b/unproto/error.h @@ -0,0 +1,4 @@ +/* @(#) error.h 1.1 91/11/30 21:10:36 */ + +extern void error(); /* default context */ +extern void error_where(); /* user-specified context */ diff --git a/unproto/example.c b/unproto/example.c new file mode 100644 index 0000000..003df4a --- /dev/null +++ b/unproto/example.c @@ -0,0 +1,140 @@ + /* + * @(#) example.c 1.2 91/09/22 21:21:45 + * + * Examples of things that can be done with the unproto package + */ + + /* + * New-style argument list with structured argument, one field being pointer + * to function returning pointer to function with function-pointer argument + */ + +x(struct { + struct { + int (*(*foo) (int (*arg1) (double))) (float arg2); + } foo; +} baz) { + return (0); +} + + /* + * Old-style argument list with new-style argument type, declaration + * embedded within block. Plus a couple assignments with function calls that + * look like casts. + */ + +foo(bar) +int (*(*bar) (float)) (int); +{ + int (*baz) (int) = (int (*) (int)) 0, + y = (y * (*baz) (y)), + *(*z) (int) = (int *(*) (int)) 0; + + struct { int (*foo)(int); } *(*s)(int) = + (struct { int (*foo)(int); } *(*)(int)) 0; + + { + y = (y * (*baz) (y)); + } + { + z = (int *(*) (int)) 0; + } + { + s = (struct { int (*foo)(int); } *(*)(int)) 0; + } + + return (0); +} + +/* Multiple declarations in one statement */ + +test1() +{ + int foo2,*(*(*bar)(int))(float),*baz(double); +} + +/* Discriminate declarations from executable statements */ + +test2(char *y) +{ + int foo = 5,atoi(char *); + + foo = 5,atoi(y); +} + +/* Declarations without explicit type */ + +test3,test4(int); + +test5(int y) +{ + { + test3; + } + { + test4(y); + } +} + +test6[1],test7(int); + +test7(int x) +{ + { + test6[1]; + } + { + test7(x); + } +} + +/* Checking a complicated cast */ + +struct { + struct { + int (*f)(int), o; + } bar; +} (*baz2)(int) = (struct { struct { int (*f)(int), o; } bar; } (*)(int)) 0; + +/* Distinguish things with the same shape but with different meaning */ + +test8(x) +{ + { + struct { + int foo; + } bar(int); + } + { + do { + int foo; + } while (x); + } +} + +/* Do not think foo(*bar) is a function pointer declaration */ + +test9(char *bar) +{ + foo(*bar); +} + +/* another couple of special-cased words. */ + +test10(int x) +{ + { + int test10(int); + do test10(x); + while (x); + } + { + return test10(x); + } +} + +test11(int *x) +{ + while (*x) + (putchar(*x++)); +} diff --git a/unproto/example.out b/unproto/example.out new file mode 100644 index 0000000..6dc75f3 --- /dev/null +++ b/unproto/example.out @@ -0,0 +1,173 @@ +# 1 "example.c" + + + + + + + + + + + +x + + + +(baz) +# 16 "example.c" +struct { struct { int (*(*foo)())(); } foo;} baz; +# 16 "example.c" +{/*1*/ + /* end dcls */return (0); +}/*1*/ + + + + + + + +foo +(bar)int (*(*bar)())(); +{/*1*/ + int (*baz)() = (int (*)()) 0, + y = (y * (*baz)(y)), + *(*z)() = (int *(*)()) 0; + + struct {/*2*/ int (*foo)(); }/*2*/ *(*s)() = + (struct { int (*foo)(); } *(*)()) 0; + + /* end dcls */{/*2*/ + y /* end dcls */= (y * (*baz)(y)); + }/*2*/ + {/*2*/ + z /* end dcls */= (int *(*)()) 0; + }/*2*/ + {/*2*/ + s /* end dcls */= (struct { int (*foo)(); } *(*)()) 0; + }/*2*/ + + return (0); +}/*1*/ + + + +test1 +() +# 52 "example.c" +{/*1*/ + int foo2,*(*(*bar)())(),*baz(); +}/*1*/ + + + +test2 +(y) +# 59 "example.c" +char *y; +# 59 "example.c" +{/*1*/ + int foo = 5,atoi(); + + foo /* end dcls */= 5,atoi(y); +}/*1*/ + + + +test3,test4(); + +test5 +(y) +# 70 "example.c" +int y; +# 70 "example.c" +{/*1*/ + /* end dcls */{/*2*/ + test3/* end dcls */; + }/*2*/ + {/*2*/ + test4/* end dcls */(y); + }/*2*/ +}/*1*/ + +test6[1],test7(); + +test7 +(x) +# 82 "example.c" +int x; +# 82 "example.c" +{/*1*/ + /* end dcls */{/*2*/ + test6/* end dcls */[1]; + }/*2*/ + {/*2*/ + test7/* end dcls */(x); + }/*2*/ +}/*1*/ + + + +struct {/*1*/ + struct {/*2*/ + int (*f)(), o; + }/*2*/ bar; +}/*1*/ (*baz2)() = (struct { struct { int (*f)(), o; } bar; } (*)()) 0; + + + +test8 +(x) +# 102 "example.c" +{/*1*/ + /* end dcls */{/*2*/ + struct {/*3*/ + int foo; + }/*3*/ bar(); + }/*2*/ + {/*2*/ + /* end dcls */do {/*3*/ + int foo; + }/*3*/ while (x); + }/*2*/ +}/*1*/ + + + +test9 +(bar) +# 118 "example.c" +char *bar; +# 118 "example.c" +{/*1*/ + foo/* end dcls */(*bar); +}/*1*/ + + + +test10 +(x) +# 125 "example.c" +int x; +# 125 "example.c" +{/*1*/ + /* end dcls */{/*2*/ + int test10(); + /* end dcls */do test10(x); + while (x); + }/*2*/ + {/*2*/ + /* end dcls */return test10(x); + }/*2*/ +}/*1*/ + +test11 +(x) +# 137 "example.c" +int *x; +# 137 "example.c" +{/*1*/ + /* end dcls */while (*x) + (putchar(*x++)); +}/*1*/ diff --git a/unproto/stdarg.h b/unproto/stdarg.h new file mode 100644 index 0000000..978529b --- /dev/null +++ b/unproto/stdarg.h @@ -0,0 +1,38 @@ + /* + * @(#) stdarg.h 1.2 91/11/30 21:10:39 + * + * Sample stdarg.h file for use with the unproto filter. + * + * This file serves two purposes. + * + * 1 - As an include file for use with ANSI-style C source that implements + * variadic functions. + * + * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is + * defined, its value will appear in the place of the "..." in argument + * lists of variadic function *definitions* (not declarations). + * + * Compilers that pass arguments via the stack can use the default code at the + * end of this file (this usually applies for the VAX, MC68k and 80*86 + * architectures). + * + * RISC-based systems often need special tricks. An example of the latter is + * given for the SPARC architecture. Read your /usr/include/varargs.h for + * more information. + * + * You can use the varargs.c program provided with the unproto package to + * verify that the stdarg.h file has been set up correctly. + */ + +#ifdef sparc +# define _VA_ALIST_ "__builtin_va_alist" + typedef char *va_list; +# define va_start(ap, p) (ap = (char *) &__builtin_va_alist) +# define va_arg(ap, type) ((type *) __builtin_va_arg_incr((type *) ap))[0] +# define va_end(ap) +#else /* vax, mc68k, 80*86 */ + typedef char *va_list; +# define va_start(ap, p) (ap = (char *) (&(p)+1)) +# define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1] +# define va_end(ap) +#endif diff --git a/unproto/symbol.c b/unproto/symbol.c new file mode 100644 index 0000000..0871f63 --- /dev/null +++ b/unproto/symbol.c @@ -0,0 +1,161 @@ +/*++ +/* NAME +/* symbol 3 +/* SUMMARY +/* rudimentary symbol table package +/* SYNOPSIS +/* #include "symbol.h" +/* +/* void sym_init() +/* +/* void sym_enter(name, type) +/* char *name; +/* int type; +/* +/* struct symbol *sym_find(name) +/* char *name; +/* DESCRIPTION +/* This is a rudimentary symbol-table package, just enough to +/* keep track of a couple of C keywords. +/* +/* sym_init() primes the table with C keywords. At present, most of +/* the keywords that have to do with types are left out. +/* We need a different strategy to detect type definitions because +/* we do not keep track of typedef names. +/* +/* sym_enter() adds an entry to the symbol table. +/* +/* sym_find() locates a symbol table entry (it returns 0 if +/* it is not found). +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/11/30 21:10:33 +/* VERSION/RELEASE +/* 1.2 +/*--*/ + +static char symbol_sccsid[] = "@(#) symbol.c 1.2 91/11/30 21:10:33"; + +/* C library */ + +extern char *strcpy(); +extern char *malloc(); + +/* Application-specific stuff */ + +#include "error.h" +#include "token.h" +#include "symbol.h" + +#define SYM_TABSIZE 20 + +static struct symbol *sym_tab[SYM_TABSIZE] = {0,}; + +/* More string stuff. Maybe it should go to an #include file. */ + +#define STREQ(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0) + +/* hash - hash a string; original author: P. J. Weinberger at Bell Labs. */ + +static unsigned hash(s, size) +register char *s; +unsigned size; +{ + register unsigned long h = 0; + register unsigned long g; + + /* + * For a performance comparison with the hash function presented in K&R, + * first edition, see the "Dragon" book by Aho, Sethi and Ullman. + */ + + while (*s) { + h = (h << 4) + *s++; + if (g = (h & 0xf0000000)) { + h ^= (g >> 24); + h ^= g; + } + } + return (h % size); +} + +/* sym_enter - enter symbol into table */ + +void sym_enter(name, type) +char *name; +int type; +{ + struct symbol *s; + int where; + + if ((s = (struct symbol *) malloc(sizeof(*s))) == 0 + || (s->name = malloc(strlen(name) + 1)) == 0) + error(1, "out of memory"); + (void) strcpy(s->name, name); + s->type = type; + + where = hash(name, SYM_TABSIZE); + s->next = sym_tab[where]; + sym_tab[where] = s; +} + +/* sym_find - locate symbol definition */ + +struct symbol *sym_find(name) +register char *name; +{ + register struct symbol *s; + + /* + * This function is called for almost every "word" token, so it better be + * fast. + */ + + for (s = sym_tab[hash(name, SYM_TABSIZE)]; s; s = s->next) + if (STREQ(name, s->name)) + return (s); + return (0); +} + + /* + * Initialization data for symbol table. We do not enter keywords for types. + * We use a different strategy to detect type declarations because we do not + * keep track of typedef names. + */ + +struct sym { + char *name; + int tokno; +}; + +static struct sym syms[] = { + "if", TOK_CONTROL, + "else", TOK_CONTROL, + "while", TOK_CONTROL, + "do", TOK_CONTROL, + "switch", TOK_CONTROL, + "case", TOK_CONTROL, + "default", TOK_CONTROL, + "return", TOK_CONTROL, + "continue", TOK_CONTROL, + "break", TOK_CONTROL, + "goto", TOK_CONTROL, + "struct", TOK_COMPOSITE, + "union", TOK_COMPOSITE, + 0, +}; + +/* sym_init - enter known keywords into symbol table */ + +void sym_init() +{ + register struct sym *p; + + for (p = syms; p->name; p++) + sym_enter(p->name, p->tokno); +} + diff --git a/unproto/symbol.h b/unproto/symbol.h new file mode 100644 index 0000000..0711c1f --- /dev/null +++ b/unproto/symbol.h @@ -0,0 +1,11 @@ +/* @(#) symbol.h 1.1 91/09/22 21:21:42 */ + +struct symbol { + char *name; /* symbol name */ + int type; /* symbol type */ + struct symbol *next; +}; + +extern void sym_enter(); /* add symbol to table */ +extern struct symbol *sym_find(); /* locate symbol */ +extern void sym_init(); /* prime the table */ diff --git a/unproto/tok_class.c b/unproto/tok_class.c new file mode 100644 index 0000000..e25b695 --- /dev/null +++ b/unproto/tok_class.c @@ -0,0 +1,180 @@ +/*++ +/* NAME +/* tok_class 3 +/* SUMMARY +/* token classification +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "token.h" +/* +/* struct token *tok_class(skip) +/* int skip; +/* DESCRIPTION +/* tok_class() collects a single and composite tokens, and +/* recognizes keywords. +/* At present, the only composite tokens are ()-delimited, +/* comma-separated lists. +/* +/* The skip argument has the same meaning as with the tok_get() +/* function. +/* DIAGNOSTICS +/* The code complains if input terminates in the middle of a list. +/* BUGS +/* Does not preserve white space at the beginning of a list element +/* or after the end of a list. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/11/30 21:10:28 +/* VERSION/RELEASE +/* 1.3 +/*--*/ + +static char class_sccsid[] = "@(#) tok_class.c 1.3 91/11/30 21:10:28"; + +/* C library */ + +#include <stdio.h> + +extern char *strcpy(); + +/* Application-specific stuff */ + +#include "error.h" +#include "vstring.h" +#include "token.h" +#include "symbol.h" + +static struct token *tok_list(); +static void tok_list_struct(); +static void tok_list_append(); + +/* tok_space_append - append trailing space except after list */ + +#define tok_space_append(list,t) { \ + if (list == 0 /* leading space*/ \ + || list->tokno == TOK_LIST) \ + tok_free(t); \ + else \ + tok_list_append(list, t); \ + } + +/* tok_class - discriminate single tokens, keywords, and composite tokens */ + +struct token *tok_class(skip) +int skip; +{ + register struct token *t; + register struct symbol *s; + + if (t = tok_get(skip)) { + switch (t->tokno) { + case '(': /* beginning of list */ + t = tok_list(t); + break; + case TOK_WORD: /* look up keyword */ + if (s = sym_find(t->vstr->str)) + t->tokno = s->type; + break; + } + } + return (t); +} + +/* tok_list - collect ()-delimited, comma-separated list of tokens */ + +static struct token *tok_list(t) +struct token *t; +{ + register struct token *list = tok_alloc(); + char filename[BUFSIZ]; + int lineno; + + /* Save context of '(' for diagnostics. */ + + strcpy(filename, curr_path); + lineno = curr_line; + + list->tokno = TOK_LIST; + list->head = list->tail = t; +#ifdef DEBUG + strcpy(list->vstr->str, "LIST"); +#endif + + for (;;) { + if ((t = tok_get(DO_WSPACE)) == 0) { /* skip blanks */ + error_where(0, filename, lineno, "unmatched '('"); + return (list); /* do not waste any data */ + } + switch (t->tokno) { + case ')': /* end of list */ + tok_free(t); + return (list); + case '{': /* struct/union type */ + tok_list_struct(list->tail, t); + break; + case TOK_WSPACE: /* preserve trailing blanks */ + tok_space_append(list->tail->tail, t); /* except after list */ + break; + case '\n': /* preserve line count */ + tok_flush(t); + break; + case ',': /* list separator */ + tok_list_append(list, t); + break; + case '(': /* beginning of list */ + tok_list_append(list->tail, tok_list(t)); + break; + default: /* ordinary token */ + tok_list_append(list->tail, t); + break; + } + } +} + +/* tok_list_struct - collect structured type info within list */ + +static void tok_list_struct(list, t) +register struct token *list; +register struct token *t; +{ + tok_list_append(list, t); + + while (t = tok_class(DO_WSPACE)) { + switch (t->tokno) { + case '\n': /* preserve line count */ + tok_flush(t); + break; + case TOK_WSPACE: /* preserve trailing blanks */ + tok_space_append(list->tail, t); /* except after list */ + break; + case '{': /* recurse */ + tok_list_struct(list, t); + break; + case '}': /* done */ + tok_list_append(list, t); + return; + default: /* other */ + tok_list_append(list, t); + break; + } + } +} + +/* tok_list_append - append data to list */ + +static void tok_list_append(h, t) +struct token *h; +struct token *t; +{ + if (h->head == 0) { + h->head = h->tail = t; + } else { + h->tail->next = t; + h->tail = t; + } +} diff --git a/unproto/tok_io.c b/unproto/tok_io.c new file mode 100644 index 0000000..ab1129b --- /dev/null +++ b/unproto/tok_io.c @@ -0,0 +1,464 @@ +/*++ +/* NAME +/* tok_io 3 +/* SUMMARY +/* token I/O +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "token.h" +/* +/* struct token *tok_get(skip_flag) +/* int skip_flag; +/* +/* void tok_unget(t) +/* struct token *t; +/* +/* void tok_flush(t) +/* struct token *t; +/* +/* void tok_show(t) +/* struct token *t; +/* +/* void put_str(s) +/* char *s; +/* +/* void put_ch(c) +/* int c; +/* +/* void show_line_control() +/* +/* char curr_path[]; +/* int curr_line; +/* DESCRIPTION +/* These functions read from stdin and write to stdout. The +/* output functions maintain some memory so that two successive +/* words will always be separated by white space. +/* +/* The input routines eliminate backslash-newline from the input. +/* +/* tok_get() reads the next token from standard input. It returns +/* a null pointer when the end of input is reached. If the skip_flag +/* argument is nonzero, white space (except newline) will be skipped. +/* +/* tok_unget() implements a limited amount of token push back. +/* +/* tok_show() displays the contents of a (possibly composite) token +/* on the standard output. +/* +/* tok_flush() displays the contents of a (possibly composite) token +/* on the standard output and makes it available for re-use. +/* +/* put_str() writes a null-terminated string to standard output. +/* +/* put_ch() writes one character to standard output. +/* +/* show_line_control() displays the line number of the next line +/* to be written to standard output, in a format suitable for the C +/* compiler parser phase. +/* +/* The curr_path[] and curr_line variables contain the input file name and +/* line number of the most recently read token. +/* BUGS +/* The tokenizer is just good enough for the unproto filter. +/* As a benefit, it is quite fast. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/11/30 21:10:26 +/* VERSION/RELEASE +/* 1.2 +/*--*/ + +static char io_sccsid[] = "@(#) tok_io.c 1.2 91/11/30 21:10:26"; + +/* C library */ + +#include <stdio.h> +#include <ctype.h> + +extern char *strchr(); +extern char *malloc(); +extern char *realloc(); +extern char *strcpy(); + +/* Application-specific stuff */ + +#include "token.h" +#include "vstring.h" +#include "error.h" + +/* Stuff to keep track of original source file name and position */ + +char curr_path[BUFSIZ]; /* current file name */ +int curr_line = 0; /* # of last read line */ + +/* Forward declarations */ + +static void read_quoted(); +static void read_comment(); + +/* Buffered i/o stuff */ + +static struct vstring *buf = 0; /* read-ahead buffer */ +static char *bp = ""; /* buffer position */ + +#ifdef DEBUG +#define INITBUF 1 /* small initial buffer size */ +#else +#define INITBUF BUFSIZ /* reasonable initial buffer size */ +#endif + +#define input() (*bp ? *bp++ : next_line()) +#define unput(c) (*--bp = (c)) + +#define TOK_BUFSIZE 5 /* token push-back buffer size */ + +static struct token *tok_buf[TOK_BUFSIZE]; +static int tok_bufpos = 0; + +/* Type of last token sent to output, for pretty printing */ + +static int last_tok = 0; + +/* Directives that should be ignored. */ + +#ifdef IGNORE_DIRECTIVES + +static char *ignore_directives[] = { + IGNORE_DIRECTIVES, + 0, +}; + +#endif + +/* Modified string and ctype stuff. */ + +#define STREQUAL(x,y) (*(x) == *(y) && strcmp((x),(y)) == 0) + +#define ISALNUM(c) (isalnum(c) || (c) == '_') +#define ISALPHA(c) (isalpha(c) || (c) == '_') +#define ISSPACE(c) (isspace(c) && c != '\n') +#define ISDOT(c) (c == '.') + +/* Collect all characters that satisfy one condition */ + +#define COLLECT(v,c,cond) { \ + register struct vstring *vs = v; \ + register char *cp = vs->str; \ + *cp++ = c; \ + for (;;) { \ + if ((c = input()) == 0) { \ + break; \ + } else if (cond) { \ + if (VS_ADDCH(vs, cp, c) == 0) \ + error(1, "out of memory"); \ + } else { \ + unput(c); \ + break; \ + } \ + } \ + *cp = 0; \ + } + +/* do_control - parse control line, uses tok_get() */ + +static int do_control() +{ + struct token *t1; + struct token *t2; + int pass_thru = 1; /* 0 = ignore, 1 = output */ + + (void) input(); /* skip the hash */ + + if (t1 = tok_get(NO_WSPACE)) { + switch (t1->tokno) { + + /* + * In case of line number control, the remainder of the line has + * the format: linenumber "pathname". + */ + case TOK_NUMBER: + if (t2 = tok_get(NO_WSPACE)) { + if (t2->tokno == '"') { + curr_line = atoi(t1->vstr->str) - 1; + strcpy(curr_path, t2->vstr->str); + } + tok_free(t2); + } + break; + +#ifdef IGNORE_DIRECTIVES + case TOK_WORD: + /* Optionally ignore other #directives, such as #pragma. */ + { + char **cpp; + char *cp = t1->vstr->str; + + for (cpp = ignore_directives; *cpp; cpp++) { + if (STREQUAL(cp, *cpp)) { + pass_thru = 0; + break; + } + } + } + break; +#endif + } + tok_free(t1); + } + return (pass_thru); +} + +/* next_line - read one logical line, handle #control */ + +static int next_line() +{ + register int c; + register char *cp; + + /* Allocate buffer upon first entry */ + + if (buf == 0) + buf = vs_alloc(INITBUF); + + for (;;) { + cp = buf->str; + + /* Account for EOF and line continuations */ + + while ((c = getchar()) != EOF) { + if (VS_ADDCH(buf, cp, c) == 0) /* store character */ + error(1, "out of memory"); + if (c == '\n') { /* real end of line */ + curr_line++; + break; + } else if (c == '\\') { + if ((c = getchar()) == EOF) { /* XXX strip backslash-EOF */ + break; + } else if (c == '\n') { /* strip backslash-newline */ + curr_line++; + put_ch('\n'); /* preserve line count */ + cp--; /* un-store backslash */ + } else { + ungetc(c, stdin); /* keep backslash-other */ + } + } + } + *cp = 0; + bp = buf->str; + + /* Account for EOF and #control */ + + switch (bp[0]) { + case 0: /* EOF */ + return (0); + case '#': /* control */ + if (do_control()) + fputs(buf->str, stdout); /* pass through */ + else + putchar('\n'); /* filter out */ + break; + default: /* non-control */ + return (input()); + } + } +} + +/* tok_unget - push back one token */ + +void tok_unget(t) +register struct token *t; +{ + if (tok_bufpos >= TOK_BUFSIZE) + error(1, "too much pushback"); + tok_buf[tok_bufpos++] = t; +} + +/* tok_get - get next token */ + +struct token *tok_get(skip_flag) +int skip_flag; +{ + register struct token *t; + register int c; + int d; + + /* Use push-back token, if any. */ + + if (tok_bufpos) { + t = tok_buf[--tok_bufpos]; + return (t); + } + + /* + * Get one from the pool and fill it in. The loop is here in case we + * should skip white-space tokens, which happens in a minority of all + * cases. + */ + + t = tok_alloc(); + + for (;;) { + if ((c = input()) == 0) { + tok_free(t); + return (0); + } else if (!isascii(c)) { + t->vstr->str[0] = c; + t->vstr->str[1] = 0; + t->tokno = TOK_OTHER; + return (t); + } else if (c == '"' || c == '\'') { + read_quoted(t, c); + t->tokno = c; + return (t); + } else if (ISALPHA(c)) { + COLLECT(t->vstr, c, ISALNUM(c)); + t->tokno = TOK_WORD; + return (t); + } else if (isdigit(c)) { + COLLECT(t->vstr, c, isdigit(c)); + t->tokno = TOK_NUMBER; + return (t); + } else if (ISSPACE(c)) { + COLLECT(t->vstr, c, ISSPACE(c)); + if (skip_flag) + continue; + t->tokno = TOK_WSPACE; + return (t); + } else if (ISDOT(c)) { + COLLECT(t->vstr, c, ISDOT(c)); + t->tokno = TOK_OTHER; + return (t); + } else { + t->vstr->str[0] = c; + if (c == '/') { + if ((d = input()) == '*') { + t->vstr->str[1] = d; /* comment */ + read_comment(t->vstr); + if (skip_flag) + continue; + t->tokno = TOK_WSPACE; + return (t); + } else { + unput(d); + } + } + t->vstr->str[1] = 0; + t->tokno = c; + return (t); + } + } +} + +/* read_qouted - read string or character literal */ + +static void read_quoted(t, ch) +register struct token *t; +int ch; +{ + register char *cp = t->vstr->str; + register int c; + + *cp++ = ch; + + while (c = input()) { + if (c == '\n') { /* newline in string */ + unput(c); + break; + } + if (VS_ADDCH(t->vstr, cp, c) == 0) /* store character */ + error(1, "out of memory"); + if (c == ch) /* end of string */ + break; + if (c == '\\') /* eat next character */ + if ((c = input()) != 0 && VS_ADDCH(t->vstr, cp, c) == 0) + error(1, "out of memory"); + } + *cp = 0; + return; +} + +/* read_comment - stuff a whole comment into one huge token */ + +static void read_comment(vs) +register struct vstring *vs; +{ + register char *cp = vs->str + 2; /* skip slash star */ + register int c; + register int d; + + while (c = input()) { + if (VS_ADDCH(vs, cp, c) == 0) + error(1, "out of memory"); + if (c == '*') { + if ((d = input()) == '/') { + if (VS_ADDCH(vs, cp, d) == 0) + error(1, "out of memory"); + break; + } else { + unput(d); + } + } + } + *cp = 0; +} + +/* put_str - output a string */ + +void put_str(s) +char *s; +{ + fputs(s, stdout); + last_tok = s[0]; /* XXX */ +#ifdef DEBUG + fflush(stdout); +#endif +} + +/* put_ch - put character */ + +void put_ch(c) +int c; +{ + last_tok = putchar(c); +#ifdef DEBUG + fflush(stdout); +#endif +} + +/* tok_show - output (possibly composite) token */ + +void tok_show(t) +struct token *t; +{ + register struct token *p; + register struct token *s; + + switch (t->tokno) { + case TOK_LIST: + for (s = t->head; s; s = s->next) { + put_ch(s->tokno); /* opening paren or ',' */ + for (p = s->head; p; p = p->next) + tok_show(p); + } + put_ch(')'); /* closing paren */ + break; + case TOK_WORD: + if (ISALPHA(last_tok)) + putchar(' '); + /* FALLTRHOUGH */ + default: + fputs(t->vstr->str, stdout); /* token contents */ + last_tok = t->vstr->str[0]; +#ifdef DEBUG + fflush(stdout); +#endif + if (t->head) /* trailing blanks */ + for (p = t->head; p; p = p->next) + tok_show(p); + } +} diff --git a/unproto/tok_pool.c b/unproto/tok_pool.c new file mode 100644 index 0000000..c2a9665 --- /dev/null +++ b/unproto/tok_pool.c @@ -0,0 +1,104 @@ +/*++ +/* NAME +/* tok_pool 3 +/* SUMMARY +/* maintain pool of unused token structures +/* PACKAGE +/* unproto +/* SYNOPSIS +/* #include "token.h" +/* +/* struct token *tok_alloc() +/* +/* void tok_free(t) +/* struct token *t; +/* DESCRIPTION +/* tok_alloc() and tok_free() maintain a pool of unused token +/* structures. +/* +/* tok_alloc() takes the first free token structure from the pool +/* or allocates a new one if the pool is empty. +/* +/* tok_free() adds a (possibly composite) token structure to the pool. +/* BUGS +/* The pool never shrinks. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/09/01 23:08:36 +/* VERSION/RELEASE +/* 1.1 +/*--*/ + +static char pool_sccsid[] = "@(#) tok_pool.c 1.1 91/09/01 23:08:36"; + +/* C library */ + +extern char *malloc(); + +/* Application-specific stuff */ + +#include "token.h" +#include "vstring.h" + +extern void error(); + +#define TOKLEN 5 /* initial string buffer length */ + +struct token *tok_pool = 0; /* free token pool */ + +/* tok_alloc - allocate token structure from pool or heap */ + +struct token *tok_alloc() +{ + register struct token *t; + + if (tok_pool) { /* re-use an old one */ + t = tok_pool; + tok_pool = t->next; + } else { /* create a new one */ + if ((t = (struct token *) malloc(sizeof(struct token))) == 0 + || (t->vstr = vs_alloc(TOKLEN)) == 0) + error(1, "out of memory"); + } + t->next = t->head = t->tail = 0; +#ifdef DEBUG + strcpy(t->vstr->str, "BUSY"); +#endif + return (t); +} + +/* tok_free - return (possibly composite) token to pool of free tokens */ + +void tok_free(t) +register struct token *t; +{ +#ifdef DEBUG + /* Check if we are freeing free token */ + + register struct token *p; + + for (p = tok_pool; p; p = p->next) + if (p == t) + error(1, "freeing free token"); +#endif + + /* Free neighbours and subordinates first */ + + if (t->next) + tok_free(t->next); + if (t->head) + tok_free(t->head); + + /* Free self */ + + t->next = tok_pool; + t->head = t->tail = 0; + tok_pool = t; +#ifdef DEBUG + strcpy(t->vstr->str, "FREE"); +#endif +} diff --git a/unproto/token.h b/unproto/token.h new file mode 100644 index 0000000..672039d --- /dev/null +++ b/unproto/token.h @@ -0,0 +1,47 @@ +/* @(#) token.h 1.3 91/11/30 21:10:37 */ + +struct token { + int tokno; /* token value, see below */ + int len; /* string or list length */ + struct vstring *vstr; /* token contents */ + struct token *next; + struct token *head; + struct token *tail; +}; + +/* Special token values */ + +#define TOK_LIST 256 /* () delimited list */ +#define TOK_WORD 257 /* keyword or identifier */ +#define TOK_NUMBER 258 /* number */ +#define TOK_WSPACE 259 /* white space except newline */ +#define TOK_OTHER 260 /* other multi-char token */ +#define TOK_CONTROL 261 /* flow control keyword */ +#define TOK_COMPOSITE 262 /* struct or union */ + +/* Input/output functions and macros */ + +extern struct token *tok_get(); /* read next single token */ +extern void tok_show(); /* display (composite) token */ +extern struct token *tok_class(); /* classify tokens */ +extern void put_ch(); /* write character */ +extern void put_str(); /* write string */ +extern void tok_unget(); /* stuff token back into input */ + +#define tok_flush(t) (tok_show(t), tok_free(t)) + +/* tok_get() and tok_class() options */ + +#define DO_WSPACE 0 /* retain space, tab */ +#define NO_WSPACE 1 /* skip space, tab */ + +/* Memory management */ + +struct token *tok_alloc(); /* allocate token storage */ +extern void tok_free(); /* re-cycle storage */ + +/* Context */ + +extern char curr_path[]; /* current path name */ +extern int curr_line; /* current line number */ +#define show_line_control() printf("# %d %s\n", curr_line, curr_path); diff --git a/unproto/unproto.1 b/unproto/unproto.1 new file mode 100644 index 0000000..671e917 --- /dev/null +++ b/unproto/unproto.1 @@ -0,0 +1,79 @@ +.TH UNPROTO 1 +.ad +.fi +.SH NAME +unproto +\- +ANSI C to old C converter +.SH PACKAGE +.na +.nf +unproto +.SH SYNOPSIS +.na +.nf +/lib/cpp ... | unproto + +/somewhere/cpp ... +.SH DESCRIPTION +.ad +.fi +This document describes a filter that sits between the +C preprocessor (usually \fI/lib/cpp\fP) and the next C compiler +pass. It rewrites ANSI-C style function headers, function type +declarations, function pointer types, and function pointer casts +to old style. Other ANSI-isms are passed on without modification +(token pasting, pragmas, etcetera). + +For maximal flexibility, the "cpp | unproto" pipeline can be +packaged as an executable shell script named "/somewhere/cpp". +This script should then be specified to the C compiler as a +non-default preprocessor. + +The overhead of shell script interpretation can be avoided by +having the unprototyper itself open the pipe to the preprocessor. +In that case, the source should be compiled with the PIPE_THROUGH_CPP +macro defined (usually as "/lib/cpp"), and the resulting binary +should be installed as "/somewhere/cpp". +.SH SEE ALSO +.na +.nf +.ad +.fi +cc(1), how to specify a non-default C preprocessor. + +Some versions of the lint command are implemented as a shell +script. It should require only minor modification for integration +with the unprotoizer. Other versions of the lint command accept the same +command syntax as the C compiler for the specification of a non-default +preprocessor. Some research may be needed. +.SH DIAGNOSTICS +.ad +.fi +The progam will complain if it unexpectedly +reaches the end of input. +.SH BUGS +.ad +.fi +Should be run on preprocessed source only, i.e. after macro expansion. + +Declarations of (whatever) are misunderstood and will result in +syntax errors. + +Does not generate explicit type casts for function argument +expressions. +.SH AUTHOR(S) +.na +.nf +Wietse Venema (wietse@wzv.win.tue.nl) +Eindhoven University of Technology +Department of Mathematics and Computer Science +Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +.SH LAST MODIFICATION +.na +.nf +91/09/22 21:21:35 +.SH VERSION/RELEASE +.na +.nf +1.2 diff --git a/unproto/unproto.c b/unproto/unproto.c new file mode 100644 index 0000000..9ca26ce --- /dev/null +++ b/unproto/unproto.c @@ -0,0 +1,749 @@ +/*++ +/* NAME +/* unproto 1 +/* SUMMARY +/* ANSI C to old C converter +/* PACKAGE +/* unproto +/* SYNOPSIS +/* /lib/cpp ... | unproto +/* +/* /somewhere/cpp ... +/* DESCRIPTION +/* This document describes a filter that sits between the +/* C preprocessor (usually \fI/lib/cpp\fP) and the next C compiler +/* pass. It rewrites ANSI-C style function headers, function type +/* declarations, function pointer types, and function pointer casts +/* to old style. Other ANSI-isms are passed on without modification +/* (token pasting, pragmas, etcetera). +/* +/* For maximal flexibility, the "cpp | unproto" pipeline can be +/* packaged as an executable shell script named "/somewhere/cpp". +/* This script should then be specified to the C compiler as a +/* non-default preprocessor. It will not work if your C compiler +/* specifies output file names to the preprocessor. +/* +/* The overhead of shell script interpretation can be avoided by +/* having the unprototyper itself open the pipe to the preprocessor. +/* In that case, the source should be compiled with the PIPE_THROUGH_CPP +/* macro defined (usually as "/lib/cpp"), and the resulting binary +/* should be installed as "/somewhere/cpp". +/* SEE ALSO +/* .ad +/* .fi +/* cc(1), how to specify a non-default C preprocessor. +/* +/* Some versions of the lint command are implemented as a shell +/* script. It should require only minor modification for integration +/* with the unprotoizer. Other versions of the lint command accept the same +/* command syntax as the C compiler for the specification of a non-default +/* preprocessor. Some research may be needed. +/* DIAGNOSTICS +/* The progam will complain if it unexpectedly +/* reaches the end of input. +/* BUGS +/* Should be run on preprocessed source only, i.e. after macro expansion. +/* +/* Declarations of (whatever) are misunderstood and will result in +/* syntax errors. +/* +/* Does not generate explicit type casts for function argument +/* expressions. +/* AUTHOR(S) +/* Wietse Venema (wietse@wzv.win.tue.nl) +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/09/22 21:21:35 +/* VERSION/RELEASE +/* 1.2 +/*--*/ + +static char unproto_sccsid[] = "@(#) unproto.c 1.3 91/11/30 21:10:30"; + +/* C library */ + +#include <stdio.h> +#include <errno.h> + +extern void exit(); +extern int optind; +extern char *optarg; +extern int getopt(); + +/* Application-specific stuff */ + +#include "vstring.h" +#include "stdarg.h" +#include "token.h" +#include "error.h" +#include "symbol.h" + +/* Forward declarations. */ + +static struct token *dcl_flush(); +static void block_flush(); +static void block_dcls(); +static struct token *show_func_ptr_type(); +static struct token *show_struct_type(); +static void show_arg_name(); +static void show_type(); +static void pair_flush(); +static void check_cast(); + +#define check_cast_flush(t) (check_cast(t), tok_free(t)) + +#ifdef PIPE_THROUGH_CPP +static int pipe_stdin_through_cpp(); +#endif + +/* Disable debugging printfs while preserving side effects. */ + +#ifdef DEBUG +#define DPRINTF printf +#else +#define DPRINTF (void) +#endif + +/* An attempt to make some complicated expressions a bit more readable. */ + +#define STREQ(x,y) (*(x) == *(y) && !strcmp((x),(y))) + +#define LAST_ARG_AND_EQUAL(s,c) ((s)->next == 0 && (s)->head \ + && ((s)->head == (s)->tail) \ + && (STREQ((s)->head->vstr->str, (c)))) + +#define LIST_BEGINS_WITH_STAR(s) (s->head->head && s->head->head->tokno == '*') + +#define IS_FUNC_PTR_TYPE(s) (s->tokno == TOK_LIST && s->next \ + && s->next->tokno == TOK_LIST \ + && LIST_BEGINS_WITH_STAR(s)) + +/* main - driver */ + +int main(argc, argv) +int argc; +char **argv; +{ + register struct token *t; +#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */ + int cpp_status; + int wait_pid; + int cpp_pid; + + cpp_pid = pipe_stdin_through_cpp(argv); +#else + if ( argc > 1 ) { + if( freopen(argv[1], "r", stdin) == 0 ) { + fprintf(stderr, "Cannot open '%s'\n", argv[1]); + exit(9); + } + } + if ( argc > 2 ) { + if( freopen(argv[2], "w", stdout) == 0 ) { + fprintf(stderr, "Cannot open '%s'\n", argv[2]); + exit(9); + } + } +#endif + + sym_init(); /* prime the symbol table */ + + while (t = tok_class(DO_WSPACE)) { + if (t = dcl_flush(t)) { /* try declaration */ + if (t->tokno == '{') { /* examine rejected token */ + block_flush(t); /* body */ + } else { + tok_flush(t); /* other, recover */ + } + } + } + +#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */ + while ((wait_pid = wait(&cpp_status)) != -1 && wait_pid != cpp_pid) + /* void */ ; + return (wait_pid != cpp_pid || cpp_status != 0); +#else + return (0); +#endif +} + +#ifdef PIPE_THROUGH_CPP /* pipe through /lib/cpp */ + +/* pipe_stdin_through_cpp - avoid shell script overhead */ + +static int pipe_stdin_through_cpp(argv) +char **argv; +{ + int pipefds[2]; + int pid; + char **cpptr = argv; + + /* + * With most UNIX implementations, the second non-option argument to + * /lib/cpp specifies the output file. If an output file other than + * stdout is specified, we must force /lib/cpp to write to stdout, and we + * must redirect our own standard output to the specified output file. + */ + +#define IS_OPTION(cp) ((cp)[0] == '-' && (cp)[1] != 0) + + /* Skip to first non-option argument, if any. */ + + while (*++cpptr && IS_OPTION(*cpptr)) + /* void */ ; + + /* + * Assume that the first non-option argument is the input file name. The + * next argument could be the output destination or an option (System V + * Release 2 /lib/cpp gets the options *after* the file arguments). + */ + + if (*cpptr && *++cpptr && **cpptr != '-') { + + /* + * The first non-option argument is followed by another argument that + * is not an option ("-stuff") or a hyphen ("-"). Redirect our own + * standard output before we clobber the file name. + */ + + if (freopen(*cpptr, "w", stdout) == 0) { + perror(*cpptr); + exit(1); + } + /* Clobber the file name argument so that /lib/cpp writes to stdout */ + + *cpptr = "-"; + } + /* Set up the pipe that connects /lib/cpp to our standard input. */ + + if (pipe(pipefds)) { + perror("pipe"); + exit(1); + } + switch (pid = fork()) { + case -1: /* error */ + perror("fork"); + exit(1); + case 0: /* child */ + close(pipefds[0]); /* close reading end */ + close(1); /* connect stdout to pipe */ + if (dup(pipefds[1]) != 1) + error(1, "dup() problem"); + close(pipefds[1]); /* close redundant fd */ + execv(PIPE_THROUGH_CPP, argv); + perror(PIPE_THROUGH_CPP); + exit(1); + default: /* parent */ + close(pipefds[1]); /* close writing end */ + close(0); /* connect stdin to pipe */ + if (dup(pipefds[0]) != 0) + error(1, "dup() problem"); + close(pipefds[0]); /* close redundant fd */ + return (pid); + } +} + +#endif + +/* header_flush - rewrite new-style function header to old style */ + +static void header_flush(t) +register struct token *t; +{ + register struct token *s; + + /* Do argument names, but suppress void and rewrite trailing ... */ + + if (LAST_ARG_AND_EQUAL(t->head, "void")) { + put_str("()\n"); /* no arguments */ + } else { + for (s = t->head; s; s = s->next) { /* foreach argument... */ + if (LAST_ARG_AND_EQUAL(s, "...")) { +#ifdef _VA_ALIST_ /* see ./stdarg.h */ + put_ch(s->tokno); /* ',' */ + put_str(_VA_ALIST_); /* varargs magic */ +#endif + } else { + put_ch(s->tokno); /* opening '(' or ',' */ + show_arg_name(s); /* extract argument name */ + } + } + put_str(")\n"); /* closing ')' */ + } + + /* Do argument types, but suppress void and trailing ... */ + + if (!LAST_ARG_AND_EQUAL(t->head, "void")) { + for (s = t->head; s; s = s->next) { /* foreach argument... */ + if (!LAST_ARG_AND_EQUAL(s, "...")) { + if (s->head != s->tail) { /* really new-style argument? */ + show_line_control(); /* fix line number */ + show_type(s); /* rewrite type info */ + put_str(";\n"); + } + } + } + } + tok_free(t); + show_line_control(); /* because '{' follows */ +} + +/* show_arg_name - extract argument name from argument type info */ + +static void show_arg_name(s) +register struct token *s; +{ + if (s->head) { + register struct token *p; + register struct token *t = 0; + + /* Find the last interesting item. */ + + for (p = s->head; p; p = p->next) { + if (p->tokno == TOK_WORD) { + t = p; /* remember last word */ + } else if (IS_FUNC_PTR_TYPE(p)) { + t = p; /* or function pointer */ + p = p->next; + } + } + + /* Extract argument name from last interesting item. */ + + if (t) { + if (t->tokno == TOK_LIST) + show_arg_name(t->head); /* function pointer, recurse */ + else + tok_show(t); /* print last word */ + } + } +} + +/* show_type - rewrite type to old-style syntax */ + +static void show_type(s) +register struct token *s; +{ + register struct token *p; + + for (p = s->head; p; p = p->next) { + if (IS_FUNC_PTR_TYPE(p)) { + p = show_func_ptr_type(p); /* function pointer type */ + } else { + tok_show(p); /* other */ + } + } +} + +/* show_func_ptr_type - display function_pointer type using old-style syntax */ + +static struct token *show_func_ptr_type(t) +struct token *t; +{ + register struct token *s; + + /* + * Rewrite (list1) (list2) to (list1) (). Only (list1) is given to us; + * the caller must have verified the presence of (list2). Account for the + * rare case that (list1) is a comma-separated list. That should be an + * error, but we do not want to waste any information. + */ + + for (s = t->head; s; s = s->next) { + put_ch(s->tokno); /* opening paren or ',' */ + show_type(s); /* recurse */ + } + put_str(")()"); /* closing paren */ + return (t->next); +} + +/* show_struct_type - display structured type, rewrite function-pointer types */ + +static struct token *show_struct_type(p) +register struct token *p; +{ + tok_show(p); /* opening brace */ + + while (p->next) { /* XXX cannot return 0 */ + p = p->next; + if (IS_FUNC_PTR_TYPE(p)) { + p = show_func_ptr_type(p); /* function-pointer member */ + } else if (p->tokno == '{') { + p = show_struct_type(p); /* recurse */ + } else { + tok_show(p); /* other */ + if (p->tokno == '}') { + return (p); /* done */ + } + } + } + DPRINTF("/* missing '}' */"); + return (p); +} + +/* is_func_ptr_cast - recognize function-pointer type cast */ + +static int is_func_ptr_cast(t) +register struct token *t; +{ + register struct token *p; + + /* + * Examine superficial structure. Require (list1) (list2). Require that + * list1 begins with a star. + */ + + if (!IS_FUNC_PTR_TYPE(t)) + return (0); + + /* + * Make sure that there is no name in (list1). Do not worry about + * unexpected tokens, because the compiler will complain anyway. + */ + + for (p = t->head->head; p; p = p->next) { + switch (p->tokno) { + case TOK_LIST: /* recurse */ + return (is_func_ptr_cast(p)); + case TOK_WORD: /* name in list */ + return (0); + } + } + return (1); /* no name found */ +} + +/* check_cast - display ()-delimited, comma-separated list */ + +static void check_cast(t) +struct token *t; +{ + register struct token *s; + register struct token *p; + + /* + * Rewrite function-pointer types and function-pointer casts. Do not + * blindly rewrite (*list1)(list2) to (*list1)(). Function argument lists + * are about the only thing we can discard without provoking diagnostics + * from the compiler. + */ + + for (s = t->head; s; s = s->next) { + put_ch(s->tokno); /* opening paren or ',' */ + for (p = s->head; p; p = p->next) { + switch (p->tokno) { + case TOK_LIST: + if (is_func_ptr_cast(p)) { /* not: IS_FUNC_PTR_TYPE(p) */ + p = show_func_ptr_type(p); /* or we might take away */ + } else { /* function-call arguments */ + check_cast(p); /* recurse */ + } + break; + case '{': + p = show_struct_type(p); /* rewrite func. ptr. types */ + break; + default: + tok_show(p); + break; + } + } + } + put_ch(')'); /* closing paren */ +} + +/* block_dcls - on the fly rewrite decls/initializers at start of block */ + +static void block_dcls() +{ + register struct token *t; + + /* + * Away from the top level, a declaration should be preceded by type or + * storage-class information. That is why inside blocks, structs and + * unions we insist on reading one word before passing the _next_ token + * to the dcl_flush() function. + * + * Struct and union declarations look the same everywhere: we make an + * exception for these more regular constructs and pass the "struct" and + * "union" tokens to the type_dcl() function. + */ + + while (t = tok_class(DO_WSPACE)) { + switch (t->tokno) { + case TOK_WSPACE: /* preserve white space */ + case '\n': /* preserve line count */ + tok_flush(t); + break; + case TOK_WORD: /* type declarations? */ + tok_flush(t); /* advance to next token */ + t = tok_class(DO_WSPACE); /* null return is ok */ + case TOK_COMPOSITE: /* struct or union */ + if ((t = dcl_flush(t)) == 0) + break; + /* FALLTRHOUGH */ + default: /* end of declarations */ + DPRINTF("/* end dcls */"); + /* FALLTRHOUGH */ + case '}': /* end of block */ + tok_unget(t); + return; + } + } +} + +/* block_flush - rewrite struct, union or statement block on the fly */ + +static void block_flush(t) +register struct token *t; +{ + static int count = 0; + + tok_flush(t); + DPRINTF("/*%d*/", ++count); + + /* + * Rewrite function pointer types in declarations and function pointer + * casts in initializers at start of block. + */ + + block_dcls(); + + /* Remainder of block: only rewrite function pointer casts. */ + + while (t = tok_class(DO_WSPACE)) { + if (t->tokno == TOK_LIST) { + check_cast_flush(t); + } else if (t->tokno == '{') { + block_flush(t); + } else { + tok_flush(t); + if (t->tokno == '}') { + DPRINTF("/*%d*/", count--); + return; + } + } + } + DPRINTF("/* missing '}' */"); +} + +/* pair_flush - on the fly rewrite casts in grouped stuff */ + +static void pair_flush(t, start, stop) +register struct token *t; +register int start; +register int stop; +{ + tok_flush(t); + + while (t = tok_class(DO_WSPACE)) { + if (t->tokno == start) { /* recurse */ + pair_flush(t, start, stop); + } else if (t->tokno == TOK_LIST) { /* expression or cast */ + check_cast_flush(t); + } else { /* other, copy */ + tok_flush(t); + if (t->tokno == stop) { /* done */ + return; + } + } + } + DPRINTF("/* missing '%c' */", stop); +} + +/* initializer - on the fly rewrite casts in initializer */ + +static void initializer() +{ + register struct token *t; + + while (t = tok_class(DO_WSPACE)) { + switch (t->tokno) { + case ',': /* list separator */ + case ';': /* list terminator */ + tok_unget(t); + return; + case TOK_LIST: /* expression or cast */ + check_cast_flush(t); + break; + case '[': /* array substript, may nest */ + pair_flush(t, '[', ']'); + break; + case '{': /* structured data, may nest */ + pair_flush(t, '{', '}'); + break; + default: /* other, just copy */ + tok_flush(t); + break; + } + } +} + +/* func_ptr_dcl_flush - rewrite function pointer declaration */ + +static struct token *func_ptr_dcl_flush(list) +register struct token *list; +{ + register struct token *t; + + /* + * Ignore blanks because they would be output earlier than the list that + * preceded them... Recover gracefully from syntax errors. + */ + + while (t = tok_class(NO_WSPACE)) { + switch (t->tokno) { + case '\n': /* preserve line count */ + tok_flush(t); + break; + case TOK_LIST: + /* Function pointer type: (list1) (list2) -> (list1) () */ + (void) show_func_ptr_type(list); /* may be recursive */ + tok_free(list); + tok_free(t); + return (0); + default: /* not a declaration */ + tok_unget(t); + return (list); + } + } + + /* Hit EOF; must be mistake, but do not waste any information. */ + + return (list); +} + +/* function_dcl_flush - rewrite function { heading, type declaration } */ + +static struct token *function_dcl_flush(list) +register struct token *list; +{ + register struct token *t; + + /* + * Ignore blanks because they would be output earlier than the list that + * preceded them... + */ + + while (t = tok_class(NO_WSPACE)) { + switch (t->tokno) { + case '\n': + /* Preserve line count */ + tok_flush(t); + break; + case '{': + /* Function heading: word (list) { -> old style heading */ + header_flush(list); + tok_unget(t); + return (0); + case TOK_WORD: + /* Old-style function heading: word (list) word...{ */ + tok_flush(list); + tok_unget(t); + return (0); + case TOK_LIST: + /* Function typedef? word (list1) (list) -> word (list1) () */ + tok_flush(list); + put_str("()"); + tok_free(t); + return (0); + case ',': + case ';': + /* Function type declaration: word (list) -> word () */ + tok_free(list); + put_str("()"); + tok_unget(t); + return (0); + default: + /* Something else, reject the list. */ + tok_unget(t); + return (list); + } + } + + /* Hit EOF; must be mistake, but do not waste any information. */ + + return (list); +} + +/* dcl_flush - parse declaration on the fly, return rejected token */ + +static struct token *dcl_flush(t) +register struct token *t; +{ + register int got_word; + + /* + * Away from the top level, type or storage-class information is required + * for an (extern or forward) function type declaration or a variable + * declaration. + * + * With our naive word-counting approach, this means that the caller should + * read one word before passing the next token to us. This is how we + * distinguish, for example, function declarations from function calls. + * + * An exception are structs and unions, because they look the same at any + * level. The caller should give is the "struct" or "union" token. + */ + + for (got_word = 0; t; t = tok_class(DO_WSPACE)) { + switch (t->tokno) { + case TOK_WSPACE: /* advance past blanks */ + case '\n': /* advance past newline */ + case '*': /* indirection: keep trying */ + tok_flush(t); + break; + case TOK_WORD: /* word: keep trying */ + case TOK_COMPOSITE: /* struct or union */ + got_word = 1; + tok_flush(t); + break; + default: + + /* + * Function pointer types can be preceded by zero or more words + * (at least one when not at the top level). Other stuff can be + * accepted only after we have seen at least one word (two words + * when not at the top level). See also the above comment on + * structs and unions. + */ + + if (t->tokno == TOK_LIST && LIST_BEGINS_WITH_STAR(t)) { + if (t = func_ptr_dcl_flush(t)) { + return (t); /* reject token */ + } else { + got_word = 1; /* for = and [ and , and ; */ + } + } else if (got_word == 0) { + return (t); /* reject token */ + } else { + switch (t->tokno) { + case TOK_LIST: /* function type */ + if (t = function_dcl_flush(t)) + return (t); /* reject token */ + break; + case '[': /* dimension, does not nest */ + pair_flush(t, '[', ']'); + break; + case '=': /* initializer follows */ + tok_flush(t); + initializer(); /* rewrite casts */ + break; + case '{': /* struct, union, may nest */ + block_flush(t); /* use code for stmt blocks */ + break; + case ',': /* separator: keep trying */ + got_word = 0; + tok_flush(t); + break; + case ';': /* terminator: succeed */ + tok_flush(t); + return (0); + default: /* reject token */ + return (t); + } + } + } + } + return (0); /* hit EOF */ +} diff --git a/unproto/varargs.c b/unproto/varargs.c new file mode 100644 index 0000000..4ca56d8 --- /dev/null +++ b/unproto/varargs.c @@ -0,0 +1,32 @@ + /* + * @(#) varargs.c 1.1 91/09/01 23:08:45 + * + * This program can be used to verify that the stdarg.h file is set up + * correctly for your system. If it works, it should print one line with the + * text "stdarg.h works". + */ + +#include <stdio.h> +#include "stdarg.h" + +main(int argc, char *argv[]) +{ + varargs_test("%s %s\n", "stdarg.h", "works"); +} + +varargs_test(char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + while (*fmt) { + if (strncmp("%s", fmt, 2) == 0) { + fputs(va_arg(ap, char *), stdout); + fmt += 2; + } else { + putchar(*fmt); + fmt++; + } + } + va_end(ap); +} diff --git a/unproto/vstring.c b/unproto/vstring.c new file mode 100644 index 0000000..fb8d053 --- /dev/null +++ b/unproto/vstring.c @@ -0,0 +1,91 @@ +/*++ +/* NAME +/* vs_alloc(), VS_ADDCH() +/* SUMMARY +/* auto-resizing string library +/* PACKAGE +/* vstring +/* SYNOPSIS +/* #include "vstring.h" +/* +/* struct vstring *vs_alloc(len) +/* int len; +/* +/* int VS_ADDCH(vs, wp, ch) +/* struct vstring *vs; +/* char *wp; +/* int ch; +/* DESCRIPTION +/* These functions and macros implement a small library for +/* arbitrary-length strings that grow automatically when +/* they fill up. The allocation strategy is such that there +/* will always be place for the terminating null character. +/* +/* vs_alloc() allocates storage for a variable-length string. +/* +/* VS_ADDCH() adds a character to a variable-length string +/* and automagically extends the string if fills up. +/* \fIvs\fP is a pointer to a vstring structure; \fIwp\fP +/* the current write position in the corresponding character +/* array; \fIch\fP the character value to be written. +/* Note that VS_ADDCH() is a macro that evaluates some +/* arguments more than once. +/* DIAGNOSTICS +/* VS_ADDCH() returns zero if it was unable to dynamically +/* resize a string. +/* +/* vs_alloc() returns a null pointer in case of problems. +/* BUGS +/* Auto-resizing may change the address of the string data in +/* a vstring structure. Beware of dangling pointers. +/* AUTHOR(S) +/* Wietse Venema +/* Eindhoven University of Technology +/* Department of Mathematics and Computer Science +/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands +/* LAST MODIFICATION +/* 91/09/22 21:21:38 +/* VERSION/RELEASE +/* 1.2 +/*--*/ + +static char vstring_sccsid[] = "@(#) vstring.c 1.2 91/09/22 21:21:38"; + +/* C library */ + +extern char *malloc(); +extern char *realloc(); + +/* Application-specific stuff */ + +#include "vstring.h" + +/* vs_alloc - initial string allocation */ + +struct vstring *vs_alloc(len) +int len; +{ + register struct vstring *vp; + + if (len < 1 + || (vp = (struct vstring *) malloc(sizeof(struct vstring))) == 0 + || (vp->str = malloc(len)) == 0) + return (0); + vp->last = vp->str + len - 1; + return (vp); +} + +/* vs_realloc - extend string, update write pointer */ + +char *vs_realloc(vp, cp) +register struct vstring *vp; +char *cp; +{ + int where = cp - vp->str; + int len = vp->last - vp->str + 1; + + if ((vp->str = realloc(vp->str, len *= 2)) == 0) + return (0); + vp->last = vp->str + len - 1; + return (vp->str + where); +} diff --git a/unproto/vstring.h b/unproto/vstring.h new file mode 100644 index 0000000..ec02a6e --- /dev/null +++ b/unproto/vstring.h @@ -0,0 +1,14 @@ +/* @(#) vstring.h 1.1 91/09/01 23:08:42 */ + +struct vstring { + char *str; /* string value */ + char *last; /* last position */ +}; + +extern struct vstring *vs_alloc(); /* initial allocation */ +extern char *vs_realloc(); /* string extension */ + +/* macro to add one character to auto-resized string */ + +#define VS_ADDCH(vs,wp,c) \ + ((wp < (vs)->last || (wp = vs_realloc(vs,wp))) ? (*wp++ = c) : 0) |