diff -Nurd linux86.old/Makefile linux86/Makefile --- linux86.old/Makefile Mon Jul 22 22:35:18 2002 +++ linux86/Makefile Tue Jul 23 08:37:15 2002 @@ -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 @@ 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 -Nurd linux86.old/README linux86/README --- linux86.old/README Sat Jan 19 22:26:25 2002 +++ linux86/README Tue Jul 23 08:46:14 2002 @@ -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 @@ 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 '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 -Nurd linux86.old/bcc/bcc.c linux86/bcc/bcc.c --- linux86.old/bcc/bcc.c Tue May 28 23:45:59 2002 +++ linux86/bcc/bcc.c Tue Jul 23 23:04:52 2002 @@ -141,6 +141,7 @@ 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 @@ 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 @@ } 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 @@ opt_x = 1; append_option("/lib/crt0.o", 'l'); break; + default: + fatal("Unknown model specifier for -M"); } if (do_optim) diff -Nurd linux86.old/bcc/codefrag.c linux86/bcc/codefrag.c --- linux86.old/bcc/codefrag.c Sat Mar 16 10:30:42 2002 +++ linux86/bcc/codefrag.c Tue Jul 23 21:23:08 2002 @@ -350,6 +350,7 @@ if (i386_32) { outmovsx(); + outaccum(); outncregname(BREG); } else diff -Nurd linux86.old/bcc/declare.c linux86/bcc/declare.c --- linux86.old/bcc/declare.c Mon Jul 22 21:33:23 2002 +++ linux86/bcc/declare.c Tue Jul 23 21:00:24 2002 @@ -493,6 +493,10 @@ ++nunsigned; nextsym(); break; + case ASMSYM: + nextsym(); + doasm(); + break; default: goto break2; } diff -Nurd linux86.old/bcc/exptree.c linux86/bcc/exptree.c --- linux86.old/bcc/exptree.c Sun Mar 14 12:23:01 1999 +++ linux86/bcc/exptree.c Tue Jul 23 20:28:47 2002 @@ -397,7 +397,12 @@ 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 -Nurd linux86.old/bcc/input.c linux86/bcc/input.c --- linux86.old/bcc/input.c Sat Jan 12 17:41:47 2002 +++ linux86/bcc/input.c Tue Jul 23 00:17:54 2002 @@ -238,6 +238,7 @@ if (ch == terminator) { gch1(); + blanks(); break; } if (charptr >= chartop) diff -Nurd linux86.old/bcc/preproc.c linux86/bcc/preproc.c --- linux86.old/bcc/preproc.c Sat Jan 12 18:02:18 2002 +++ linux86/bcc/preproc.c Tue Jul 23 21:00:24 2002 @@ -40,6 +40,7 @@ char *paramspot; bool_t inparam; indn_t nparam; + struct symstruct *symptr; }; PRIVATE char dummyparam[] = { EOL, 0 }; @@ -51,8 +52,10 @@ 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 @@ } } + +/* 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 @@ } ctlcase = symptr->offset.offsym; if (ifstate.ifflag == FALSE && - (ctlcase < ELSECNTL || ctlcase > IFNDEFCNTL)) + (ctlcase < ELIFCNTL || ctlcase > IFNDEFCNTL)) return; switch (ctlcase) { @@ -209,6 +228,9 @@ case DEFINECNTL: define(); break; + case ELIFCNTL: + elifcontrol(); + break; case ELSECNTL: elsecontrol(); break; @@ -236,6 +258,9 @@ case UNDEFCNTL: undef(); break; + case WARNINGCNTL: + warningcntl(); + break; } } @@ -344,8 +369,12 @@ { 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 @@ && (--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 @@ } } +/* 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 @@ return; } symptr = gsymptr; + symptr->name.namea[0] |= 0x80; /* SMUDGE macro definition */ ngoodparams = 0; paramhead = NULL; if (symptr->indcount != 0) @@ -572,6 +626,7 @@ { 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 @@ 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 @@ } else { + mpptr->symptr->name.namea[0] &= 0x7F;/* UnSMUDGE macro definition */ ch = *++lineptr; /* gch1() would mess up next param == EOL-1 */ if (ch != 0) { diff -Nurd linux86.old/bcc/proto.h linux86/bcc/proto.h --- linux86.old/bcc/proto.h Mon Jul 22 19:29:10 2002 +++ linux86/bcc/proto.h Tue Jul 23 21:00:24 2002 @@ -325,6 +325,7 @@ 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 -Nurd linux86.old/bcc/scan.h linux86/bcc/scan.h --- linux86.old/bcc/scan.h Mon Jul 22 19:29:10 2002 +++ linux86/bcc/scan.h Tue Jul 23 21:00:24 2002 @@ -171,6 +171,7 @@ INCLUDECNTL, LINECNTL, UNDEFCNTL, + WARNINGCNTL, ELIFCNTL, /* "IF" controls must be contiguous */ ELSECNTL, diff -Nurd linux86.old/bcc/state.c linux86/bcc/state.c --- linux86.old/bcc/state.c Sat Jan 12 17:47:49 2002 +++ linux86/bcc/state.c Tue Jul 23 21:00:24 2002 @@ -72,7 +72,6 @@ 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 @@ rbrace(); } -PRIVATE void doasm() +PUBLIC void doasm() { if (sym == LPAREN) nextsym(); if (sym!=STRINGCONST) diff -Nurd linux86.old/bcc/table.c linux86/bcc/table.c --- linux86.old/bcc/table.c Mon Jul 22 19:29:10 2002 +++ linux86/bcc/table.c Tue Jul 23 21:00:24 2002 @@ -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 @@ { "#asm", ASMCNTL, }, { "#define", DEFINECNTL, }, + { "#elif", ELIFCNTL, }, { "#else", ELSECNTL, }, { "#endasm", ENDASMCNTL, }, { "#endif", ENDIFCNTL, }, @@ -126,6 +127,7 @@ { "#ifndef", IFNDEFCNTL, }, { "#line", LINECNTL, }, { "#undef", UNDEFCNTL, }, + { "#warning", WARNINGCNTL, }, { "defined", DEFINEDSYM, }, /* should be deactivated except in #if's */ }; diff -Nurd linux86.old/ld/globvar.h linux86/ld/globvar.h --- linux86.old/ld/globvar.h Sun Dec 1 17:52:24 1996 +++ linux86/ld/globvar.h Tue Jul 23 22:19:39 2002 @@ -13,6 +13,7 @@ /* 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 -Nurd linux86.old/ld/ld.c linux86/ld/ld.c --- linux86.old/ld/ld.c Wed Mar 20 22:17:57 2002 +++ linux86/ld/ld.c Tue Jul 23 22:20:26 2002 @@ -19,6 +19,7 @@ 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 @@ 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; @@ -236,6 +238,10 @@ /* Headerless executables can't use symbols. */ 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) diff -Nurd linux86.old/ld/writex86.c linux86/ld/writex86.c --- linux86.old/ld/writex86.c Sun Feb 10 10:03:19 2002 +++ linux86/ld/writex86.c Tue Jul 23 22:22:56 2002 @@ -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 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 @@ 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) { @@ -597,6 +600,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() diff -Nurd linux86.old/ld/x86_cpm86.h linux86/ld/x86_cpm86.h --- linux86.old/ld/x86_cpm86.h Thu Jan 1 01:00:00 1970 +++ linux86/ld/x86_cpm86.h Tue Jul 23 22:19:39 2002 @@ -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 */