summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2002-07-24 21:00:16 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:47 +0200
commit2060b4f4cc1c13975e495d088344825f7700181b (patch)
tree5efd3dbb269b09d4b3351fdb6b50d6dca0291d47
parent673f690a37f6673a3262e933709c79de8a66f48c (diff)
downloaddev86-2060b4f4cc1c13975e495d088344825f7700181b.tar.gz
Import Dev86src-0.16.5.tar.gzv0.16.5
-rw-r--r--Makefile5
-rw-r--r--README16
-rw-r--r--bcc/bcc.c58
-rw-r--r--bcc/codefrag.c1
-rw-r--r--bcc/declare.c4
-rw-r--r--bcc/exptree.c5
-rw-r--r--bcc/input.c1
-rw-r--r--bcc/preproc.c66
-rw-r--r--bcc/proto.h1
-rw-r--r--bcc/scan.h1
-rw-r--r--bcc/state.c3
-rw-r--r--bcc/table.c4
-rw-r--r--ld/globvar.h1
-rw-r--r--ld/ld.c6
-rw-r--r--ld/writex86.c32
-rw-r--r--ld/x86_cpm86.h44
16 files changed, 232 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index b0e5113..d1ada45 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
# This file is part of the Linux-8086 Development environment and is
# distributed under the GNU General Public License.
-VERSION=0.16.4
+VERSION=0.16.5
TARGETS= \
clean bcc unproto copt as86 ld86 elksemu \
@@ -58,7 +58,8 @@ ifdef.o: ifdef.c
Uninstall:
@# CHECK FROM HERE
@make -n Uninstall
- @echo 'Are you really sure... have you checked this... ^C to interrupt'
+ @echo 'Are you really sure... have you checked this...'
+ @echo "I haven't used this in _years_ ... ^C to interrupt"
@read line
rm -rf /usr/bcc
rm -f $(BINDIR)/bcc $(BINDIR)/as86_encap $(BINDIR)/dis86
diff --git a/README b/README
index 32b382c..78643c3 100644
--- a/README
+++ b/README
@@ -1,11 +1,11 @@
This is a development environment for ELKS-86 and standalone 8086 code.
-All you need to do is 'make' from the top directory and the main
-parts of the package will be made. These can be tested by use the 'ncc'
-program from the newly created bin subdirectory.
+All you need to do is 'make' from the top directory and the main parts
+of the package will be made. These can be tested by using the 'ncc'
+program from the newly created bin subdirectory. (ncc is a varient of
+the bcc driver program that doesn't need to be installed to be used).
Use 'make install' to install them.
-Use 'make Uninstall' to remove everything (Beware with this though!)
Some other bits can be built by 'make other' and installed with
'make install-other'.
@@ -29,6 +29,11 @@ In the unlikely event you're makeing a non-cross development environment
you can, on the initial make, do "make LIBPRE=/usr' to have the libraries
and include files directly under /usr rather than /usr/bcc.
+Note: These prefix options only effect the 'bcc.c' driver program and
+ the install scripts, all the others get their paths from bcc.c.
+ The ELKSSRC location can, however, greatly effect how the ELKS
+ libraries are built.
+
All the versions of the library are built by make; 'normal', 'fast',
'MSDOS', 'standalone' and Linux-i386.
@@ -49,7 +54,8 @@ the BSS and Stack can be upto 64k on top of that.
The 'standalone' version creates executables like normal ELKS a.out
files but with no operating system calls, just BIOS ones. These
files are suitable for running on a bare machine started by one of
-the boot blocks in the bootblocks subdirectory.
+the boot blocks in the bootblocks subdirectory. If you add a '-d'
+option to the link stage the a.out header will be removed.
The Linux-i386 version generates static Linux OMAGIC a.out programs,
they need neither elksemu nor a.out shared libraries to run. Unfortunatly
diff --git a/bcc/bcc.c b/bcc/bcc.c
index 36024df..be59905 100644
--- a/bcc/bcc.c
+++ b/bcc/bcc.c
@@ -141,6 +141,7 @@ void command_arch P((void));
void command_opts P((int opykey));
void newfilename P((struct file_list * file, int last_stage, int new_extn, int use_o));
void run_unlink P((void));
+void validate_link_opts P((void));
void append_file P((char * filename, int ftype));
void append_option P((char * option, int otype));
void prepend_option P((char * option, int otype));
@@ -200,6 +201,7 @@ char ** argv;
reset_localprefix();
#endif
getargs(argc, argv);
+ validate_link_opts();
default_include = expand_tilde(default_include);
default_libdir0 = expand_tilde(default_libdir0);
@@ -447,6 +449,60 @@ run_link()
}
void
+validate_link_opt(char * option)
+{
+ int err = 0;
+ if (option[0] != '-') return;
+
+ switch(option[1]) {
+ default:
+ err = 1;
+ break;
+ 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 */
+ case 's': /* strip symbols */
+ case 't': /* trace modules linked */
+ case 'z': /* unmapped zero page */
+ case 'N': /* Native format a.out */
+ case 'd': /* Make a headerless outfile */
+ case 'c': /* Write header in CP/M-86 format */
+ case 'y': /* Use a newer symbol table */
+ if (option[2] != 0 && option[2] != '-')
+ err = 1;
+ break;
+ case 'C': /* startfile name */
+ case 'L': /* library path */
+ case 'O': /* library file name */
+ case 'T': /* text base address */
+ case 'D': /* data base address */
+ case 'H': /* heap top address */
+ case 'l': /* library name */
+ case 'o': /* output file name */
+ break;
+ }
+ if (err)
+ fprintf(stderr, "warning: linker option %s not unrecognised.\n", option);
+}
+
+void
+validate_link_opts()
+{
+ struct opt_list * ol;
+ struct file_list * next_file;
+ if (opt_arch>1) return; /* Only check ld86 options */
+
+ for(ol=options; ol; ol=ol->next)
+ if (ol->opttype == 'l')
+ validate_link_opt(ol->opt);
+
+ for(next_file = files; next_file; next_file = next_file->next)
+ validate_link_opt(next_file->file);
+}
+
+void
command_reset()
{
#ifndef MAXPATHLEN
@@ -868,6 +924,8 @@ char ** argv;
opt_x = 1;
append_option("/lib/crt0.o", 'l');
break;
+ default:
+ fatal("Unknown model specifier for -M");
}
if (do_optim)
diff --git a/bcc/codefrag.c b/bcc/codefrag.c
index bdcb850..041a148 100644
--- a/bcc/codefrag.c
+++ b/bcc/codefrag.c
@@ -350,6 +350,7 @@ PUBLIC void sctoi()
if (i386_32)
{
outmovsx();
+ outaccum();
outncregname(BREG);
}
else
diff --git a/bcc/declare.c b/bcc/declare.c
index 40175e6..f61887f 100644
--- a/bcc/declare.c
+++ b/bcc/declare.c
@@ -493,6 +493,10 @@ PRIVATE bool_pt declspec()
++nunsigned;
nextsym();
break;
+ case ASMSYM:
+ nextsym();
+ doasm();
+ break;
default:
goto break2;
}
diff --git a/bcc/exptree.c b/bcc/exptree.c
index 427b5f4..04a4534 100644
--- a/bcc/exptree.c
+++ b/bcc/exptree.c
@@ -397,7 +397,12 @@ struct nodestruct *p2;
if (target->storage == CONSTANT)
{
if (rscalar & CHAR)
+ {
target->offset.offv &= CHMASKTO;
+ if (p2->nodetype == sctype &&
+ target->offset.offv&((~CHMASKTO)>>1))
+ target->offset.offv |= ~CHMASKTO;
+ }
else if (rscalar & SHORT)
{
target->offset.offv &= shortmaskto;
diff --git a/bcc/input.c b/bcc/input.c
index 080c7bc..b89eb78 100644
--- a/bcc/input.c
+++ b/bcc/input.c
@@ -238,6 +238,7 @@ PUBLIC void include()
if (ch == terminator)
{
gch1();
+ blanks();
break;
}
if (charptr >= chartop)
diff --git a/bcc/preproc.c b/bcc/preproc.c
index 62302e8..e292329 100644
--- a/bcc/preproc.c
+++ b/bcc/preproc.c
@@ -40,6 +40,7 @@ struct macroposition
char *paramspot;
bool_t inparam;
indn_t nparam;
+ struct symstruct *symptr;
};
PRIVATE char dummyparam[] = { EOL, 0 };
@@ -51,8 +52,10 @@ PRIVATE struct ifstruct ifstack[MAX_IF];
PRIVATE struct macroposition macrostack[MAX_MACRO];
FORWARD void asmcontrol P((void));
+FORWARD void warningcntl P((void));
FORWARD void control P((void));
FORWARD void defineorundefinestring P((char *str, bool_pt defineflag));
+FORWARD void elifcontrol P((void));
FORWARD void elsecontrol P((void));
FORWARD void endif P((void));
FORWARD fastin_pt getparnames P((void));
@@ -154,6 +157,22 @@ PUBLIC void checknotinif()
}
}
+
+/* This is a major hack. It doesn't handle continued lines.
+ * It does let me avoid wrapping warning directives though. */
+PRIVATE void warningcntl()
+{
+ char *s = lineptr;
+
+ while (*lineptr && (*lineptr != EOL)) {
+ ++lineptr;
+ }
+ write(2, "warning: #warning", 17);
+ write(2, s, lineptr - s);
+ write(2, "\n", 1);
+ ch = *lineptr;
+}
+
/* control() - select and switch to control statement */
PRIVATE void control()
@@ -193,7 +212,7 @@ PRIVATE void control()
}
ctlcase = symptr->offset.offsym;
if (ifstate.ifflag == FALSE &&
- (ctlcase < ELSECNTL || ctlcase > IFNDEFCNTL))
+ (ctlcase < ELIFCNTL || ctlcase > IFNDEFCNTL))
return;
switch (ctlcase)
{
@@ -209,6 +228,9 @@ PRIVATE void control()
case DEFINECNTL:
define();
break;
+ case ELIFCNTL:
+ elifcontrol();
+ break;
case ELSECNTL:
elsecontrol();
break;
@@ -236,6 +258,9 @@ PRIVATE void control()
case UNDEFCNTL:
undef();
break;
+ case WARNINGCNTL:
+ warningcntl();
+ break;
}
}
@@ -344,8 +369,12 @@ ts_s_macstring += 2;
{
gch1();
skipcomment();
+#if 0
/* comment is space in modern cpp's but they have '##' too */
ch = *--lineptr = ' ';
+#else
+ continue;
+#endif
}
}
#ifdef TS
@@ -364,12 +393,13 @@ ts_s_macstring += 2;
&& (--rcp == macstring || *(rcp - 1) != EOL); )
charptr = rcp;
}
- if (charptr >= char1top)
- macstring = growobject(macstring, 2);
+ if (charptr+1 >= char1top)
+ macstring = growobject(macstring, 3);
#ifdef TS
++ts_n_macstring_term;
-ts_s_macstring += 2;
+ts_s_macstring += 3;
#endif
+ *charptr++ = ' '; /* Added to prevent tail recursion on expansion */
*charptr++ = EOL;
*charptr++ = 0;
if (nparnames)
@@ -498,6 +528,29 @@ PUBLIC void docontrol()
}
}
+/* elifcontrol() - process #elif */
+
+PRIVATE void elifcontrol()
+{
+ if (iflevel == 0)
+ {
+ error("elif without if");
+ return;
+ }
+ if (ifstate.elseflag) {
+ register struct ifstruct *ifptr;
+
+ ifptr = &ifstack[(int)--iflevel];
+ ifstate.elseflag = ifptr->elseflag;
+ ifstate.ifflag = ifptr->ifflag;
+
+ ifcontrol(IFCNTL);
+ } else {
+ ifstate.ifflag = ifstate.elseflag;
+ ifstate.elseflag = FALSE;
+ }
+}
+
/* elsecontrol() - process #else */
PRIVATE void elsecontrol()
@@ -547,6 +600,7 @@ PUBLIC void entermac()
return;
}
symptr = gsymptr;
+ symptr->name.namea[0] |= 0x80; /* SMUDGE macro definition */
ngoodparams = 0;
paramhead = NULL;
if (symptr->indcount != 0)
@@ -572,6 +626,7 @@ ts_s_macparam_tot += sizeof *paramlist * nparleft;
{
if (nparleft > 0) /* macro has params, doesn't match bare word */
{
+ symptr->name.namea[0] &= 0x7f; /* UnSMUDGE macro definition */
outstr(symptr->name.namea);
return;
}
@@ -737,6 +792,8 @@ ts_s_macparam_string_tot -= charptr - oldparam;
ch = *(lineptr = symptr->offset.offp);
mpptr->inparam = FALSE;
mpptr->nparam = ngoodparams;
+ mpptr->symptr = symptr;
+ mpptr->symptr->name.namea[0] |= 0x80; /* SMUDGE macro definition */
++maclevel;
}
/*
@@ -853,6 +910,7 @@ PUBLIC void leavemac()
}
else
{
+ mpptr->symptr->name.namea[0] &= 0x7F;/* UnSMUDGE macro definition */
ch = *++lineptr; /* gch1() would mess up next param == EOL-1 */
if (ch != 0)
{
diff --git a/bcc/proto.h b/bcc/proto.h
index d5bbb7d..36d5bdc 100644
--- a/bcc/proto.h
+++ b/bcc/proto.h
@@ -325,6 +325,7 @@ void softop P((op_pt op, struct symstruct *source, struct symstruct *target));
void compound P((void));
void outswoffset P((offset_T offset));
void outswstacklab P((void));
+void doasm P((void));
/* table.c */
struct symstruct *addglb P((char *name, struct typestruct *type));
diff --git a/bcc/scan.h b/bcc/scan.h
index 849610b..d1de894 100644
--- a/bcc/scan.h
+++ b/bcc/scan.h
@@ -171,6 +171,7 @@ enum scan_states
INCLUDECNTL,
LINECNTL,
UNDEFCNTL,
+ WARNINGCNTL,
ELIFCNTL, /* "IF" controls must be contiguous */
ELSECNTL,
diff --git a/bcc/state.c b/bcc/state.c
index c14ff7b..a290e43 100644
--- a/bcc/state.c
+++ b/bcc/state.c
@@ -72,7 +72,6 @@ FORWARD void doswitch P((void));
FORWARD void dowhile P((void));
FORWARD void jumptocases P((void));
FORWARD void statement P((void));
-FORWARD void doasm P((void));
/* --- utility routines --- */
@@ -233,7 +232,7 @@ PUBLIC void compound() /* have just seen "{" */
rbrace();
}
-PRIVATE void doasm()
+PUBLIC void doasm()
{
if (sym == LPAREN) nextsym();
if (sym!=STRINGCONST)
diff --git a/bcc/table.c b/bcc/table.c
index 68cbc6a..203b4fb 100644
--- a/bcc/table.c
+++ b/bcc/table.c
@@ -30,7 +30,7 @@
#define MAXEXPR 500
#endif
#define MAXLOCAL 100
-#define NKEYWORDS 36
+#define NKEYWORDS 38
#ifdef NOFLOAT
#define NSCALTYPES 10
#else
@@ -117,6 +117,7 @@ PRIVATE struct keywordstruct keywords[NKEYWORDS] =
{ "#asm", ASMCNTL, },
{ "#define", DEFINECNTL, },
+ { "#elif", ELIFCNTL, },
{ "#else", ELSECNTL, },
{ "#endasm", ENDASMCNTL, },
{ "#endif", ENDIFCNTL, },
@@ -126,6 +127,7 @@ PRIVATE struct keywordstruct keywords[NKEYWORDS] =
{ "#ifndef", IFNDEFCNTL, },
{ "#line", LINECNTL, },
{ "#undef", UNDEFCNTL, },
+ { "#warning", WARNINGCNTL, },
{ "defined", DEFINEDSYM, }, /* should be deactivated except in #if's */
};
diff --git a/ld/globvar.h b/ld/globvar.h
index 4a66e89..1554b98 100644
--- a/ld/globvar.h
+++ b/ld/globvar.h
@@ -13,6 +13,7 @@ EXTERN struct redlist *redfirst; /* first on list of redefined symbols */
/* K&R _explicitly_ says extern followed by public is OK */
extern char hexdigit[]; /* constant */
extern int headerless; /* Don't output header on exe */
+extern int cpm86; /* Generate CP/M-86 CMD header */
extern bin_off_t text_base_value; /* Base address of text seg */
extern bin_off_t data_base_value; /* Base or alignment of data seg */
diff --git a/ld/ld.c b/ld/ld.c
index 24391ca..29e03e9 100644
--- a/ld/ld.c
+++ b/ld/ld.c
@@ -19,6 +19,7 @@ PUBLIC bin_off_t text_base_value = 0; /* XXX */
PUBLIC bin_off_t data_base_value = 0; /* XXX */
PUBLIC bin_off_t heap_top_value = 0; /* XXX */
PUBLIC int headerless = 0;
+PUBLIC int cpm86 = 0;
PUBLIC char hexdigit[] = "0123456789abcdef";
PRIVATE bool_t flag[128];
@@ -123,6 +124,7 @@ char **argv;
case 'z': /* unmapped zero page */
case 'N': /* Native format a.out */
case 'd': /* Make a headerless outfile */
+ case 'c': /* Write header in CP/M-86 format */
case 'y': /* Use a newer symbol table */
if (arg[2] == 0)
flag[(int) arg[1]] = TRUE;
@@ -237,6 +239,10 @@ char **argv;
headerless = flag['d'];
if( headerless ) flag['s'] = 1;
+ /* CP/M-86 executables can't use symbols. */
+ cpm86 = flag['c'];
+ if ( cpm86 ) flag['s'] = 1;
+
linksyms(flag['r']);
if (outfilename == NUL_PTR)
outfilename = "a.out";
diff --git a/ld/writex86.c b/ld/writex86.c
index 70ecdde..95ff040 100644
--- a/ld/writex86.c
+++ b/ld/writex86.c
@@ -4,6 +4,7 @@
#include "syshead.h"
#include "x86_aout.h"
+#include "x86_cpm86.h"
#include "const.h"
#include "obj.h"
#include "type.h"
@@ -17,7 +18,7 @@
#define ELF_SYMS 0
#endif
-# define FILEHEADERLENGTH (headerless?0:A_MINHDR)
+# define FILEHEADERLENGTH (headerless?0:(cpm86?CPM86_HEADERLEN:A_MINHDR))
/* part of header not counted in offsets */
#define DPSEG 2
@@ -76,6 +77,7 @@ FORWARD void symres P((char *name));
FORWARD void setseg P((fastin_pt newseg));
FORWARD void skip P((unsigned countsize));
FORWARD void writeheader P((void));
+FORWARD void cpm86header P((void));
FORWARD void writenulls P((bin_off_t count));
EXTERN bool_t reloc_output;
@@ -322,7 +324,8 @@ bool_pt argxsym;
setsym("__heap_top", (bin_off_t)heap_top_value);
openout(outfilename);
- writeheader();
+ if (cpm86) cpm86header();
+ else writeheader();
for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
if (modptr->loadflag)
{
@@ -599,6 +602,31 @@ unsigned countsize;
writenulls((bin_off_t) readsize(countsize));
}
+PRIVATE void cpm86header()
+{
+ struct cpm86_exec header;
+ memset(&header, 0, sizeof header);
+
+ if (sepid)
+ {
+ header.ce_group[0].cg_type = CG_CODE;
+ u2c2(header.ce_group[0].cg_len, (15 + etextpadoff) / 16);
+ u2c2(header.ce_group[0].cg_min, (15 + etextpadoff) / 16);
+ header.ce_group[1].cg_type = CG_DATA;
+ u2c2(header.ce_group[1].cg_len, (15 + edataoffset) / 16);
+ u2c2(header.ce_group[1].cg_min, (15 + endoffset ) / 16);
+ u2c2(header.ce_group[1].cg_max, 0x1000);
+ }
+ else
+ {
+ header.ce_group[0].cg_type = CG_CODE;
+ u2c2(header.ce_group[0].cg_len, (15 + edataoffset) / 16);
+ u2c2(header.ce_group[0].cg_min, (15 + endoffset ) / 16);
+ }
+ if( FILEHEADERLENGTH )
+ writeout((char *) &header, FILEHEADERLENGTH);
+}
+
PRIVATE void writeheader()
{
struct exec header;
diff --git a/ld/x86_cpm86.h b/ld/x86_cpm86.h
new file mode 100644
index 0000000..0a858f5
--- /dev/null
+++ b/ld/x86_cpm86.h
@@ -0,0 +1,44 @@
+/* Copyright (C) 2002
+ * This file is part of the ld86 command for Linux-86
+ * It is distributed under the GNU Library General Public License.
+ *
+ * CP/M-86 CMD file header
+ */
+
+#ifndef __CPM86_H
+#define __CPM86_H
+
+typedef char Short16[2];
+
+struct cpm86_group {
+ unsigned char cg_type; /* 1=Code 2=Data */
+ Short16 cg_len; /* Group length, paragraphs */
+ Short16 cg_base; /* Group address, normally 0 for relocatable */
+ Short16 cg_min; /* Minimum size, normally = group length */
+ Short16 cg_max; /* Maximum size, normally 0x1000 (64k) */
+};
+
+
+struct cpm86_exec { /* CP/M-86 header */
+ struct cpm86_group ce_group[8];
+ unsigned char ce_spare[51];
+ Short16 ce_rsxs; /* Record with RSX list */
+ Short16 ce_fixups; /* Record with fixups */
+ unsigned char ce_flags; /* Concurrent CP/M flags */
+};
+
+/* Group types */
+#define CG_EMPTY 0
+#define CG_CODE 1
+#define CG_DATA 2
+#define CG_EXTRA 3
+#define CG_STACK 4
+#define CG_AUX1 5
+#define CG_AUX2 6
+#define CG_AUX3 7
+#define CG_AUX4 8
+#define CG_PURE 9 /* Code that is known to be pure */
+
+#define CPM86_HEADERLEN 0x80
+
+#endif /* _CPM86_H */