what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
+#ifdef _WIN32
#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
#include <signal.h>
#include "common.h"
#include <ctype.h>
#define OPTION_ICODE_IN_ASM "--i-code-in-asm"
#define OPTION_PRINT_SEARCH_DIRS "--print-search-dirs"
#define OPTION_MSVC_ERROR_STYLE "--vc"
-#define OPTION_USE_STDOUT "--use-stdout"
+#define OPTION_USE_STDOUT "--use-stdout"
static const OPTION
optionsTable[] = {
{ 0, OPTION_PEEP_FILE, NULL, "<file> use this extra peep-hole file" },
{ 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
{ 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
- { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
+ { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the float support functions" },
{ 0, OPTION_OUT_FMT_IHX, NULL, NULL },
{ 0, "--out-fmt-s19", &options.out_fmt, NULL },
{ 0, "--cyclomatic", &options.cyclomatic, NULL },
{ 0, OPTION_PRINT_SEARCH_DIRS, &options.printSearchDirs, "display the directories in the compiler's search path"},
{ 0, OPTION_MSVC_ERROR_STYLE, &options.vc_err_style, "messages are compatible with Micro$oft visual studio"},
{ 0, OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
- /* End of options */
-#if 0 /* 10jun03 !OPT_DISABLE_PIC16 */
- { 0, "--no-movff", &options.no_movff, "disable generating MOVFF opcode in PIC16 port"},
- { 0, "--gen-banksel", &options.gen_banksel, "enable the generation of banksel assembler directives in PIC16 port"},
+#if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
+ { 0, "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
#endif
+ /* End of options */
{ 0, NULL }
};
#if !OPT_DISABLE_DS390
&ds390_port,
#endif
-#if !OPT_DISABLE_PIC
- &pic_port,
-#endif
#if !OPT_DISABLE_PIC16
&pic16_port,
#endif
+#if !OPT_DISABLE_PIC
+ &pic_port,
+#endif
#if !OPT_DISABLE_TININative
&tininative_port,
#endif
#endif
#if !OPT_DISABLE_DS400
&ds400_port,
-#endif
+#endif
+#if !OPT_DISABLE_HC08
+ &hc08_port,
+#endif
};
#define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
-#if !OPT_DISABLE_PIC
-extern void picglue ();
-#endif
-#if !OPT_DISABLE_PIC16
-extern void pic16glue();
-#endif
-
/** Sets the port to the one given by the command line option.
@param The name minus the option (eg 'mcs51')
@return 0 on success.
/* printVersionInfo - prints the version info */
/*-----------------------------------------------------------------*/
void
-printVersionInfo ()
+printVersionInfo (void)
{
int i;
/* printUsage - prints command line syntax */
/*-----------------------------------------------------------------*/
void
-printUsage ()
+printUsage (void)
{
int i;
printVersionInfo();
setParseWithComma (set **dest, char *src)
{
char *p;
+ int length;
/* skip the initial white spaces */
while (isspace(*src))
src++;
+
+ /* skip the trailing white spaces */
+ length = strlen(src);
+ while (length && isspace(src[length-1]))
+ src[--length] = '\0';
for (p = strtok(src, ","); p != NULL; p = strtok(NULL, ","))
addSet(dest, Safe_strdup(p));
/** Gets the string argument to this option. If the option is '--opt'
then for input of '--optxyz' or '--opt xyz' returns xyz.
*/
-static char *
+char *
getStringArg(const char *szStart, char **argv, int *pi, int argc)
{
if (argv[*pi][strlen(szStart)])
/** Gets the integer argument to this option using the same rules as
getStringArg.
*/
-static int
+int
getIntArg(const char *szStart, char **argv, int *pi, int argc)
{
return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
case 'M':
{
preProcOnly = 1;
- addSet(&preArgvSet, Safe_strdup("-M"));
- break;
+ if (argv[i][2] == 'M')
+ addSet(&preArgvSet, Safe_strdup("-MM"));
+ else
+ addSet(&preArgvSet, Safe_strdup("-M"));
+ break;
}
case 'C':
{
exit (1);
}
- /* now write the options. JCF: added option 'y' */
- fprintf (lnkfile, "-myux%c\n", (options.out_fmt ? 's' : 'i'));
-
- /* if iram size specified */
- if (options.iram_size)
- fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
-
- /* if xram size specified */
- if (options.xram_size_set)
- fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
-
- /* if code size specified */
- if (options.code_size)
- fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
-
- if (options.debug)
- fprintf (lnkfile, "-z\n");
+ if (TARGET_IS_Z80 || TARGET_IS_GBZ80)
+ {
+ fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
+ (options.out_fmt ? 's' : 'i'), dstFileName);
+ }
+ else /*For all the other ports. Including pics???*/
+ {
+ fprintf (lnkfile, "-myux%c\n", (options.out_fmt ? 's' : 'i'));
+ }
+
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+ {
+ /* if iram size specified */
+ if (options.iram_size)
+ fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
+
+ /* if xram size specified */
+ if (options.xram_size_set)
+ fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
+
+ /* if code size specified */
+ if (options.code_size)
+ fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
+
+ if (options.debug)
+ fprintf (lnkfile, "-z\n");
+ }
#define WRITE_SEG_LOC(N, L) \
segName = Safe_strdup(N); \
fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
if (segName) { Safe_free(segName); }
- /* code segment start */
- WRITE_SEG_LOC (CODE_NAME, options.code_loc);
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+ {
- /* data segment start */
- if(options.data_loc){ /*JCF: If zero, the linker chooses the best place for data*/
- WRITE_SEG_LOC (DATA_NAME, options.data_loc);
- }
+ /* code segment start */
+ WRITE_SEG_LOC (CODE_NAME, options.code_loc);
- /* xdata start */
- WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
+ /* data segment start. If zero, the linker chooses
+ the best place for data*/
+ if(options.data_loc){
+ WRITE_SEG_LOC (DATA_NAME, options.data_loc);
+ }
- /* indirect data */
- if (IDATA_NAME) {
- WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
- }
+ /* xdata start */
+ WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
+
+ /* indirect data */
+ if (IDATA_NAME) {
+ WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+ }
- /* bit segment start */
- WRITE_SEG_LOC (BIT_NAME, 0);
+ /* bit segment start */
+ WRITE_SEG_LOC (BIT_NAME, 0);
- /* JCF: stack start */
- if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
- WRITE_SEG_LOC ("SSEG", options.stack_loc);
+ /* stack start */
+ if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
+ WRITE_SEG_LOC ("SSEG", options.stack_loc);
+ }
+ }
+ else /*For the z80, gbz80*/
+ {
+ WRITE_SEG_LOC ("_CODE", options.code_loc);
+ WRITE_SEG_LOC ("_DATA", options.data_loc);
+ }
+
+ /* If the port has any special linker area declarations, get 'em */
+ if (port->extraAreas.genExtraAreaLinkOptions)
+ {
+ port->extraAreas.genExtraAreaLinkOptions(lnkfile);
}
/* add the extra linker options */
/* other library paths if specified */
for (s = setFirstItem(libPathsSet); s != NULL; s = setNextItem(libPathsSet))
fprintf (lnkfile, "-k %s\n", s);
-
+
/* standard library path */
- if (!options.nostdlib)
+ if (!options.nostdlib)
{
- switch (options.model)
- {
- case MODEL_SMALL:
- c = "small";
- break;
- case MODEL_LARGE:
- c = "large";
- break;
- case MODEL_FLAT24:
- /* c = "flat24"; */
- if (TARGET_IS_DS390)
- {
- c = "ds390";
- }
- else if (TARGET_IS_DS400)
- {
- c = "ds400";
- }
- else
- {
- fprintf(stderr,
- "Add support for your FLAT24 target in %s @ line %d\n",
- __FILE__, __LINE__);
- exit(-1);
- }
- break;
- case MODEL_PAGE0:
- c = "xa51";
- break;
- default:
- werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
- c = "unknown";
- break;
- }
- for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
- mfprintf (lnkfile, getRuntimeVariables(), "-k %s{sep}%s\n", s, c);
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+ {
+ switch (options.model)
+ {
+ case MODEL_SMALL:
+ c = "small";
+ break;
+ case MODEL_LARGE:
+ c = "large";
+ break;
+ case MODEL_FLAT24:
+ /* c = "flat24"; */
+ if (TARGET_IS_DS390)
+ {
+ c = "ds390";
+ }
+ else if (TARGET_IS_DS400)
+ {
+ c = "ds400";
+ }
+ else
+ {
+ fprintf(stderr,
+ "Add support for your FLAT24 target in %s @ line %d\n",
+ __FILE__, __LINE__);
+ exit(-1);
+ }
+ break;
+ case MODEL_PAGE0:
+ c = "xa51";
+ break;
+ default:
+ werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
+ c = "unknown";
+ break;
+ }
+ }
+ else /*for the z80, gbz80*/
+ {
+ if (TARGET_IS_HC08)
+ c = "hc08";
+ else if (TARGET_IS_Z80)
+ c = "z80";
+ else
+ c = "gbz80";
+ }
+ for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
+ mfprintf (lnkfile, getRuntimeVariables(), "-k %s{sep}%s\n", s, c);
+
/* standard library files */
#if !OPT_DISABLE_DS390
- if (options.model == MODEL_FLAT24)
- {
- if (TARGET_IS_DS390)
- {
- fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
- }
- else if (TARGET_IS_DS400)
- {
- fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
- }
- else
- {
- fprintf(stderr,
- "Add support for your FLAT24 target in %s @ line %d\n",
- __FILE__, __LINE__);
- exit(-1);
- }
- }
+ if (options.model == MODEL_FLAT24)
+ {
+ if (TARGET_IS_DS390)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
+ }
+ else if (TARGET_IS_DS400)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
+ }
+ else
+ {
+ fprintf(stderr,
+ "Add support for your FLAT24 target in %s @ line %d\n",
+ __FILE__, __LINE__);
+ exit(-1);
+ }
+ }
#endif
#if !OPT_DISABLE_XA51
#ifdef STD_XA51_LIB
- if (options.model == MODEL_PAGE0)
- {
- fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
- }
+ if (options.model == MODEL_PAGE0)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
+ }
#endif
#endif
- fprintf (lnkfile, "-l %s\n", STD_LIB);
- fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
- fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
- fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80
+ || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+ { /*Why the z80 port is not using the standard libraries?*/
+ fprintf (lnkfile, "-l %s\n", STD_LIB);
+ fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
+ fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
+ fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
+ }
+ else if (TARGET_IS_HC08)
+ {
+ fprintf (lnkfile, "-l hc08\n");
+ }
+ else if (TARGET_IS_Z80)
+ {
+ fprintf (lnkfile, "-l z80\n");
+ }
+ else if (TARGET_IS_GBZ80)
+ {
+ fprintf (lnkfile, "-l gbz80\n");
+ }
}
/* additional libraries if any */
for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
fprintf (lnkfile, "-l %s\n", s);
+ /*For the z80 and gbz80 ports, try to find where crt0.o is...
+ It is very important for this file to be first on the linking proccess
+ so the areas are set in the correct order, expecially _GSINIT*/
+ if ((TARGET_IS_Z80 || TARGET_IS_GBZ80) &&
+ !options.no_std_crt0 && !options.nostdlib) /*For the z80, gbz80*/
+ {
+ char crt0path[PATH_MAX];
+ FILE * crt0fp;
+ for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
+ {
+ sprintf (crt0path, "%s%s%s%scrt0.o",
+ s, DIR_SEPARATOR_STRING, c, DIR_SEPARATOR_STRING);
+
+ crt0fp=fopen(crt0path, "r");
+ if(crt0fp!=NULL)/*Found it!*/
+ {
+ fclose(crt0fp);
+ #ifdef __CYGWIN__
+ {
+ /*The CYGWIN version of the z80-gbz80 linker is getting confused with
+ windows paths, so convert them to the CYGWIN format*/
+ char posix_path[PATH_MAX];
+ void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
+ cygwin_conv_to_full_posix_path(crt0path, posix_path);
+ strcpy(crt0path, posix_path);
+ }
+ #endif
+ fprintf (lnkfile, "%s\n", crt0path);
+ break;
+ }
+ }
+ if(s==NULL) fprintf (stderr, "Warning: couldn't find crt0.o\n");
+ }
+
/* put in the object files */
if (fullSrcFileName)
fprintf (lnkfile, "%s%s\n", dstFileName, port->linker.rel_ext);
strncatz (scratchFileName,
options.out_fmt ? ".S19" : ".ihx",
sizeof(scratchFileName));
+ if (strcmp (fullDstFileName, scratchFileName))
+ unlink (fullDstFileName);
rename (scratchFileName, fullDstFileName);
strncpyz (buffer, fullDstFileName, sizeof(buffer));
strncatz (scratchFileName, ".map", sizeof(scratchFileName));
*q = 0;
strncatz(buffer, ".map", sizeof(buffer));
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
rename (scratchFileName, buffer);
*p = 0;
strncatz (scratchFileName, ".mem", sizeof(scratchFileName));
*q = 0;
strncatz(buffer, ".mem", sizeof(buffer));
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
rename (scratchFileName, buffer);
+ if (options.debug)
+ {
+ *p = 0;
+ strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
+ *q = 0;
+ strncatz(buffer, ".cdb", sizeof(buffer));
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
+ rename (scratchFileName, buffer);
+ /* and the OMF file without extension: */
+ *p = 0;
+ *q = 0;
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
+ rename (scratchFileName, buffer);
+ }
}
if (system_ret)
{
strncatz (scratchFileName,
port->linker.rel_ext,
sizeof(scratchFileName));
+ if (strcmp (scratchFileName, fullDstFileName))
+ unlink (fullDstFileName);
rename (scratchFileName, fullDstFileName);
}
}
exit (1);
}
- if (TARGET_IS_PIC) {
- /* TSD PIC port hack - if the PIC port option is enabled
- and SDCC is used to generate PIC code, then we will
- generate .asm files in gpasm's format instead of SDCC's
- assembler's format
- */
-#if !OPT_DISABLE_PIC
- picglue ();
-#endif
+ if (port->general.do_glue != NULL)
+ (*port->general.do_glue)();
+ else
+ {
+ /* this shouldn't happen */
+ assert(FALSE);
+ /* in case of NDEBUG */
+ glue();
+ }
- } else
- if(TARGET_IS_PIC16) {
- /* PIC16 port misc improvements Vangelis Rokas - 6-May-2003
- Generate .asm files for gpasm (just like PIC target) but use
- pic16glue()
- */
-
-#if !OPT_DISABLE_PIC16
- pic16glue();
-#endif
- } else {
- glue ();
+ if (fatalError) {
+ exit (1);
}
if (!options.c1mode && !noAssemble)