1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126 |
- /*------------------------------------------------------------------*/
- /* */
- /* MC68000 Cross Assembler */
- /* */
- /* Copyright 1985 by Brian R. Anderson */
- /* */
- /* Main program - May 23, 1992 */
- /* */
- /* This program may be copied for personal, non-commercial use */
- /* only, provided that the above copyright notice is included */
- /* on all copies of the source code. Copying for any other use */
- /* without the consent of the author is prohibited. */
- /* */
- /*------------------------------------------------------------------*/
- /* */
- /* Originally published (in Modula-2) in */
- /* Dr. Dobb's Journal, April, May, and June 1986. */
- /* */
- /* AmigaDOS conversion copyright 1991 by Charlie Gibbs. */
- /* */
- /*------------------------------------------------------------------*/
- #define PRIMARY
- #include "A68kdef.h"
- #include "A68kglb.h"
- char *Version = "2.71.F3z (July 29, 2009)";
- int main (argc,argv) int argc; char *argv[];
- {
- char ListFN[MAXFN], EquateFN[MAXFN]; /* File names */
- int makeequ; /* Make an equate file. */
- int keepobj; /* Keep object file with errors. */
- int endfile; /* End-of-file flag */
- long maxheap2; /* Maximum secondary heap size */
- /* int cmderror, dummy; */
- int cmderror; /* using now void in v.2.71.F3d - Kevin Kofler */
- long codesize, datasize, bsssize;
- int *intptr;
- long templong;
- char tempchar[MAXLINE];
- register int i, j;
- struct SymTab **hashptr, **fsp;
- struct FwdBr *fp1, *fp2, *fp3;
- char *vopt[16]; int vopt_num; /* added by Paul Froissart in v.2.71.F3c
- variables for the -v switch */
- char *p; /* Temporary - added by Paul Froissart in v.2.71.F3c
- variable for the -r switch */
- /* dummy = 0; */ /* using now void in v.2.71.F3d - Kevin Kofler */
- Hash = NULL; /* Clear all memory pointers - */
- SymStart = NULL; /* we haven't allocated anything yet. */
- NameStart = NULL;
- RelStart = NULL;
- Heap2 = NULL;
- SymSort = NULL;
- vopt_num=0; /* number of -v switches - added by Paul Froissart
- in v.2.71.F3c */
- optim=-1; /* All optimizations are allowed (variable for the -r switch)
- added by Paul Froissart in v.2.71.F3c*/
- In.fd = Eq.fd = List.fd = Srec.fd = NOFD; /* No files are open yet. */
- In.Buf = Eq.Buf = List.Buf = Srec.Buf = NULL;
- cmderror = FALSE; /* Clear command-line error flag. */
- InclErrs = FALSE;
- SourceFN[0] = '\0'; /* We don't have source name yet. */
- HeaderFN[0] = EquateFN[0] = '\0'; /* No header or equate files yet */
- makeequ = FALSE;
- ListFN[0] = SrecFN[0] = '\0'; /* Indicate default file names. */
- InclList[0] = '\0'; /* Clear the include directory list. */
- IdntName[0] = '\0'; /* Clear program unit name. */
- DataOffset = 32768L; /* Default small data offset */
- LnMax = 60; /* Default page size */
- Quiet = 100; /* Show progress every 100 lines. */
- strcpy (MacSize, "W"); /* Macro call size (\0) */
- XrefList = DumpSym = GotEqur = KeepTabs = keepobj = FALSE;
- Unaligned = FALSE; /* added by Kevin Kofler in v.2.71.F3k */
- AllRelocs = FALSE; /* added by Kevin Kofler in v.2.71.F3l */
- SuppList = TRUE; /* Default to no listing file. */
- HashStats = FALSE; /* Default to no hashing statistics. */
- HashSize = DEFHASH; /* Hash table size default */
- maxheap2 = DEFHEAP2; /* Secondary heap size default */
- DebugStart = NODEF /*32767*/; DebugEnd = 0; /* Disable debug displays. */
-
- isError = FALSE; /* bugfix by Kevin Kofler for the TIGCC team in v.2.71.F3a */
- for (i = 0; i < 256; i++)
- OpPrec[i] = '\0'; /* Set up the operator precedence table. */
- i = (unsigned int) '('; OpPrec[i] = 1;
- i = (unsigned int) ')'; OpPrec[i] = 2;
- i = (unsigned int) '+'; OpPrec[i] = 3;
- i = (unsigned int) '-'; OpPrec[i] = 3;
- i = (unsigned int) '*'; OpPrec[i] = 4;
- i = (unsigned int) '/'; OpPrec[i] = 4;
- i = (unsigned int) '&'; OpPrec[i] = 5;
- i = (unsigned int) '!'; OpPrec[i] = 5;
- i = (unsigned int) '|'; OpPrec[i] = 5;
- i = (unsigned int) '<'; OpPrec[i] = 6;
- i = (unsigned int) '>'; OpPrec[i] = 6;
- for (i = 1; i < argc; i++) { /* Analyze the command line. */
- if (argv[i][0] != '-') {
- if (SourceFN[0] == '\0')
- strcpy (SourceFN, argv[i]); /* Source file name */
- else if (SrecFN[0] == '\0')
- strcpy (SrecFN, argv[i]); /* Object file name */
- else if (ListFN[0] == '\0')
- strcpy (ListFN, argv[i]); /* Listing file name */
- else {
- fprintf (stderr, "Too many file names.\n");
- cmderror = TRUE;
- }
- } else {
- switch (toupper(argv[i][1])) {
- case 'A': /* Output all relocs. */
- AllRelocs = TRUE;
- cmderror |= checkswitch (argv[i], "all relocs");
- break;
- case 'D': /* Dump the symbol table. */
- DumpSym = TRUE;
- strcpy (DumpSymList, &argv[i][2]); /* Selections */
- break;
- case 'E': /* Equate file name */
- makeequ = TRUE;
- if (getfilename (EquateFN, &argv[i][2], "Equate", FALSE))
- cmderror = keepobj = TRUE;
- break;
- case 'F': /* Dump the symbol table. */
- FwdProc = TRUE;
- cmderror |= checkswitch (argv[i], "forward reference");
- break;
- case 'G': /* XREF all unknown globals */
- GlobalXREF = TRUE;
- cmderror |= checkswitch (argv[i], "automatic XREF");
- break;
- case 'H': /* Header file name */
- if (getfilename (HeaderFN, &argv[i][2], "Header", TRUE))
- cmderror = keepobj = TRUE;
- break;
- case 'I': /* Include directories */
- if (argv[i][2]) {
- if (InclList[0])
- strcat (InclList, ","); /* Add to previous list */
- strcat (InclList, &argv[i][2]);
- } else {
- fprintf (stderr, "Include directory list is missing.\n");
- cmderror = keepobj = TRUE;
- }
- break;
- case 'K': /* Keep object code file. */
- keepobj = TRUE;
- cmderror |= checkswitch (argv[i], "object file keep");
- break;
- case 'X': /* Cross-reference listing */
- XrefList = TRUE; /* Falls through to case 'L': */
- case 'L': /* Produce a listing file. */
- SuppList = FALSE;
- if (getfilename (ListFN, &argv[i][2], "List", FALSE))
- cmderror = keepobj = TRUE;
- break;
- case 'M': /* Offset to small data base */
- if (argv[i][2] == '\0') {
- fprintf (stderr, "Small data offset is missing.\n");
- cmderror = keepobj = TRUE;
- break;
- }
- if (!isdigit (argv[i][2])) {
- fprintf (stderr, "Small data offset is invalid.\n");
- cmderror = TRUE;
- break;
- }
- DataOffset = CalcValue (&argv[i][2], 0);
- break;
- case 'N': /* Suppress optimization. */
- NoOpt = TRUE;
- cmderror |= checkswitch (argv[i], "optimization suppress");
- break;
- case 'O': /* Object file name */
- if (getfilename (SrecFN, &argv[i][2], "Object", TRUE))
- cmderror = keepobj = TRUE;
- break;
- case 'P': /* Page depth */
- if (argv[i][2] == '\0') {
- fprintf (stderr, "Page depth is missing.\n");
- cmderror = keepobj = TRUE;
- break;
- }
- if (!isdigit (argv[i][2])) {
- fprintf (stderr, "Page depth is invalid.\n");
- cmderror = TRUE;
- break;
- }
- if ((LnMax = CalcValue (&argv[i][2], 0)) < 10) {
- fprintf (stderr, "Page depth is invalid.\n");
- cmderror = TRUE;
- }
- break;
- case 'Q': /* Quiet console display */
- if (argv[i][2] == '\0') {
- Quiet = 0;
- break;
- }
- if (!isdigit (argv[i][2])) {
- fprintf (stderr, "Quiet interval is invalid.\n");
- cmderror = TRUE;
- break;
- }
- Quiet = CalcValue (&argv[i][2], 0);
- break;
- case 'R': /* Remove optimization - added by Paul Froissart
- in v.2.71.F3c */
- p=&argv[i][2];
- while (*p) switch (tolower(*p++)) {
- case 'a': optim &= ~OPTIM_ADDA; break;
- case 'l': optim &= ~OPTIM_LEA; break;
- case 'm': optim &= ~OPTIM_MOVEM; break;
- default: cmderror |= checkswitch (argv[i],"optimization removal");
- /* a slightly dirty, but correct way to catch invalid options */
- }
- break;
- case 'S': /* Motorola S-format */
- SFormat = TRUE;
- cmderror |= checkswitch (argv[i], "S-format");
- break;
- case 'T': /* Keep tabs in listing. */
- KeepTabs = TRUE;
- cmderror |= checkswitch (argv[i], "tab");
- break;
- case 'U': /* Allow unaligned DC/DCB/DS.W/L and code. */
- Unaligned = TRUE;
- cmderror |= checkswitch (argv[i], "unaligned");
- break;
- case 'V': /* Set value - added by Paul Froissart in v.2.71.F3c
- also checks if more than 16 -v switches (Kevin
- Kofler) */
- if (vopt_num<=15) {
- vopt[vopt_num++]=&argv[i][2];
- if (!argv[i][2]) { cmderror=TRUE; fprintf(stderr,"Invalid SET value switch (-v).\n"); }
- } else {
- cmderror=TRUE; fprintf(stderr,"Too many SET value switches (-v).\n");
- }
- break;
- case 'W': /* Work storage size(s) */
- if (argv[i][2] == '\0') {
- fprintf (stderr, "Work storage size is missing.\n");
- cmderror = keepobj = TRUE;
- break;
- }
- /* if (argv[i][2] != ',') {*/
- if ((argv[i][2] != ',') && (argv[i][2] != ';')) {
- /* also allow ; as separator - Kevin Kofler, v.2.71.F3f */
- GetField (argv[i]+2, tempchar);
- if (!isdigit (tempchar[0])) {
- fprintf (stderr, "Hash table size is invalid.\n");
- cmderror = TRUE;
- break;
- }
- HashSize = CalcValue (tempchar, 0);
- if (HashSize >= 16384) {
- fprintf (stderr, "Hash table size is too big.\n");
- cmderror = TRUE;
- }
- }
- for (j = 2; argv[i][j]; j++) {
- /* if (argv[i][j] == ',') {*/
- if ((argv[i][j] == ',') || (argv[i][j] == ';')) {
- /* also allow ; as separator - Kevin Kofler, v.2.71.F3f */
- /* Find secondary size. */
- if (!isdigit (argv[i][j+1])) {
- fprintf (stderr, "Secondary size is invalid.\n");
- cmderror = TRUE;
- break;
- }
- maxheap2 = CalcValue (&argv[i][j+1], 0);
- if (maxheap2 < MAXLINE)
- maxheap2 = MAXLINE;
- maxheap2 &= ~3L;
- break;
- }
- }
- break;
- case 'Y': /* Display hashing statistics. */
- HashStats = TRUE;
- cmderror |= checkswitch (argv[i], "hash statistics");
- break;
- case 'Z': /* Debug option */
- DebugStart = 0;
- DebugEnd = NODEF /*32767*/;
- /* if (argv[i][2] != ',') {*/
- if ((argv[i][2] != ',') && (argv[i][2] != ';')) {
- /* also allow ; as separator - Kevin Kofler, v.2.71.F3f */
- /* Debug dump starts here. */
- GetField (argv[i]+2, tempchar);
- if (!isdigit (tempchar[0])) {
- fprintf (stderr, "Debug start line is invalid.\n");
- cmderror = TRUE;
- break;
- }
- DebugStart = CalcValue (tempchar, 0);
- }
- for (j = 2; argv[i][j]; j++) {
- /* if (argv[i][j] == ',') {*/
- if ((argv[i][j] == ',') || (argv[i][j] == ';')) {
- /* also allow ; as separator - Kevin Kofler, v.2.71.F3f */
- /* Debug dump ends here. */
- if (!isdigit (argv[i][j+1])) {
- fprintf (stderr, "Debug end line is invalid.\n");
- cmderror = TRUE;
- break;
- }
- DebugEnd = CalcValue (&argv[i][j+1], 0);
- if (DebugEnd == 0)
- DebugEnd = NODEF /*32767*/;
- }
- }
- break;
- default:
- fprintf (stderr, "Unrecognized switch: %c\n", argv[i][1]);
- cmderror = TRUE;
- break;
- }
- }
- }
- if (makeequ)
- defaultfile (EquateFN, ".equ"); /* Default equate file name */
- if (!SuppList)
- defaultfile (ListFN, ".lst"); /* Default list file name */
- else /* If there's no listing, don't bother */
- KeepTabs = TRUE; /* expanding tabs - it's faster. */
- if (SFormat)
- defaultfile (SrecFN, ".s"); /* Default S-format file name */
- else
- defaultfile (SrecFN, ".o"); /* Default object file name */
- /* Check for duplicate file names. */
- if (SourceFN[0]) {
- cmderror |= checkdupfile (SourceFN, "Source", EquateFN, "equate");
- cmderror |= checkdupfile (SourceFN, "Source", ListFN, "listing");
- cmderror |= checkdupfile (SourceFN, "Source", SrecFN, "object");
- } else {
- fprintf (stderr, "Source file name is missing.\n");
- cmderror = TRUE;
- }
- if (EquateFN[0]) {
- cmderror |= checkdupfile (EquateFN, "Equate", ListFN, "listing");
- cmderror |= checkdupfile (EquateFN, "Equate", SrecFN, "object");
- }
- if (ListFN[0]) {
- cmderror |= checkdupfile (ListFN, "Listing", SrecFN, "object");
- }
- /* Open files. */
- if (!cmderror) { /* Source file */
- if ((In.Buf = (char *) malloc (BUFFSIZE)) == NULL)
- quit_cleanup ("Out of memory!\n");
- #ifdef MSDOS
- _fmode = O_BINARY;
- #endif
- if ((In.fd = open (SourceFN, 0)) < 0) {
- fprintf (stderr, "Unable to open source file.\n");
- In.fd = NOFD;
- cmderror = TRUE;
- }
- In.Ptr = In.Lim = In.Buf;
- }
- #ifdef MSDOS
- _fmode = O_TEXT;
- #endif
- if (!cmderror && EquateFN[0]) /* Equate file */
- cmderror |= xopen (EquateFN, &Eq, "equate");
- if (!cmderror && !SuppList) /* Listing file */
- cmderror |= xopen (ListFN, &List, "listing");
- #ifdef MSDOS
- if (!SFormat)
- _fmode = O_BINARY;
- #endif
- if (!cmderror) /* Object code file */
- cmderror |= xopen (SrecFN, &Srec, "object code");
- #ifdef MSDOS
- _fmode = O_BINARY;
- #endif
- if (cmderror) {
- fprintf (stderr, "\n");
- fprintf (stderr, "68000 Assembler - version %s\n", Version);
- fprintf (stderr,
- "Copyright 1985 by Brian R. Anderson\n"
- "AmigaDOS conversion copyright 1991 by Charlie Gibbs.\n"
- "Adapted for use with Fargo by David Ellsworth.\n"
- #ifdef ST_VERSION
- "Atari ST conversion copyright 1990 by Colin Fox and Darren Schebek\n\n"
- #endif ST_VERSION
- #ifdef WIN32
- "Win32 port copyright 2001-2005 by Kevin Kofler for the TIGCC project\n"
- #endif
- "Bugfixes and additions by Julien Muchembled, Paul Froissart and Kevin Kofler\n\n"
- "Usage: a68k <source file>\n"
- " [-a] [-p<page depth>]\n"
- " [-d[[!]<prefix>]] [-q[<quiet interval>]]\n"
- " [-e[<equate file>]] [-r[a][l][m]]\n"
- " [-f] [-s]\n"
- " [-g] [-t]\n"
- " [-h<header file>] [-u]\n"
- " [-i<include dirlist>] [-v<name>[,<value>]]\n"
- " [-k] "
- "[-w[<hash size>][,<heap size>]]\n"
- " [-l[<listing file>]] [-x]\n"
- " [-m<small data offset>] [-y]\n"
- " [-n] "
- "[-z[<debug start>][,<debug end>]]\n"
- " [-o<object file>]\n\n"
- "Heap size default: -w"
- "%ld,%ld\n", (long) DEFHASH, (long) DEFHEAP2);
- SrecFN[0] = '\0'; /* Don't scratch the object file! */
- quit_cleanup ("\n");
- }
- if (Quiet != 0) {
- printf ("68000 Assembler - version %s\n", Version);
- printf ("Copyright 1985 by Brian R. Anderson\n"
- "AmigaDOS conversion copyright 1991 by Charlie Gibbs.\n"
- "Adapted for use with Fargo by David Ellsworth.\n"
- #ifdef ST_VERSION
- "Atari ST conversion copyright 1990 by Colin Fox and Darren Schebek\n\n"
- #endif ST_VERSION
- #ifdef WIN32
- "Win32 port copyright 2001-2005 by Kevin Kofler for the TIGCC project\n"
- #endif
- "Bugfixes and additions by Julien Muchembled, Paul Froissart and Kevin Kofler\n\n"
- "Assembling %s\n\n", SourceFN);
- }
- /* Allocate initial symbol table chunks. */
- templong = sizeof (struct SymTab *) * HashSize;
- Hash = (struct SymTab **) malloc ((unsigned) templong);
- if (Hash == NULL)
- quit_cleanup ("Out of memory!\n");
- for (hashptr = Hash, i = 0; i < HashSize; hashptr++, i++)
- *hashptr = NULL; /* Clear the hash table. */
- SymStart = (struct SymTab *) malloc ((unsigned) CHUNKSIZE);
- if (SymStart == NULL)
- quit_cleanup ("Out of memory!\n");
- SymCurr = SymStart; /* Make the first chunk current. */
- SymCurr->Link = NULL; /* Clear forward pointer. */
- SymLim = SymCurr;
- SymLim++; /* Start of names */
- NameStart = (struct NameChunk *) malloc ((unsigned) CHUNKSIZE);
- if (NameStart == NULL)
- quit_cleanup ("Out of memory!\n");
- NameCurr = NameStart; /* Make the first chunk current. */
- NameCurr->Link = NULL; /* Clear forward pointer. */
- NameLim = (char *) NameCurr + sizeof (char *); /* Start of names */
- /* Allocate the relocation attribute table. */
- RelStart = (struct RelTab *) malloc ((unsigned) CHUNKSIZE);
- if (RelStart == NULL)
- quit_cleanup ("Out of memory!\n");
- RelCurr = RelStart; /* Relocation table */
- RelCurr->Link = NULL; /* No additional chunks */
- RelLast = NULL; /* There are no entries yet. */
- RelLim = RelStart;
- RelLim++; /* First unused space */
- /* Allocate the secondary heap (input files and parser stack). */
- Heap2 = malloc ((unsigned) maxheap2);
- if (Heap2 == NULL)
- quit_cleanup ("Out of memory!\n");
- /* Allocate the INCLUDE skip table. */
- SkipLim = (struct SkipEnt *) malloc ((unsigned) INCSKSIZ);
- if (SkipLim == NULL)
- quit_cleanup ("Out of memory!\n");
- SkipIdx = SkipLim;
- SetFixLim = (struct SetFixup *) ((char *) SkipLim + INCSKSIZ);
- IncStart = 0;
- /* Allocate the forward branch optimization log. */
- if (NoOpt) {
- FwdStart = NULL;
- } else {
- FwdStart = (struct FwdTable *) malloc ((unsigned) FWDSIZE);
- if (FwdStart == NULL)
- quit_cleanup ("Out of memory!\n");
- FwdCurr = FwdStart; /* Make the first chunk current. */
- FwdCurr->Link = NULL; /* Clear forward pointer. */
- FwdLim2 = (int *) ((char *) FwdCurr + sizeof (struct FwdTable *));
- FwdPtr = FwdLim2; /* Current position in pass 2 */
- }
- /*-------------------------------------------------------------------
- Begin Pass 1.
- */
- Pass2 = FALSE;
- startpass ('1', maxheap2);
- NumSyms = 0; /* There's nothing in the symbol table yet. */
- NextHunk = 0L; /* Start in hunk zero. */
- LowInF = InF; /* Initialize secondary heap usage pointers. */
- High2 = NextFNS;
- Low2 = (char *) LowInF;
- FwdLim1 = FwdBranch; /* Forward branch controls */
- FwdFixLimit = FwdBranchFix;
- /* Define ".A68K" as a SET symbol with an absolute value of 1.
- This allows programs to identify this assembler. */
- AddSymTab (".A68K", 1L, (long) ABSHUNK, 0, 4); /* All spellings */
- AddSymTab (".A68k", 1L, (long) ABSHUNK, 0, 4);
- AddSymTab (".a68K", 1L, (long) ABSHUNK, 0, 4);
- AddSymTab (".a68k", 1L, (long) ABSHUNK, 0, 4);
- /* If -a is given, define "__ld_all_relocs" as an XDEF symbol to a dummy label.
- This allows linkers to identify such object files. -- Kevin Kofler, v.2.71.F3l */
- if (AllRelocs) AddSymTab ("__ld_all_relocs", 0L, 0L, 1, 2);
- /* Add -v variables - added by Paul Froissart in 2.71.F3c: */
- while (vopt_num) {
- char *s=vopt[--vopt_num]; long val; /* decrement vopt_num at the
- beginning - Kevin Kofler, v.2.71.F3c */
- /* while (*s && *s!=',') s++;*/
- while ((*s) && (*s!=',') && (*s!=';') && (*s!='=')) s++;
- /* also allow ; and = as separators - Kevin Kofler, v.2.71.F3f */
- if (s==vopt[vopt_num]) /* exit(0x39); */
- quit_cleanup ("Invalid SET value switch (-v).\n");
- /* exit cleanly and with an error message - Kevin Kofler, v.2.71.F3c */
- if (!*s) val=1; else { *s++=0; val=CalcValue(s,0); }
- AddSymTab(vopt[vopt_num],val,(long)ABSHUNK,0,4);
- /* vopt_num--; */ /* see above - Kevin Kofler, v.2.71.F3c */
- }
- endfile = FALSE;
- Dir = None;
- while (!endfile && (Dir != End)) {
- PrevDir = Dir; /* Save previous directive. */
- endfile = LineParts (/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* Get a statement. */
- pass1cont: /* necessary for optional END - Paul Froissart, v.2.71.F3c */
- GetObjectCode (/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* Process the statement. */
- if (IncStart != 0) {
- if ((OpCode[0] != '\0') && (Dir < SkipDir)) {
- IncStart = 0; /* We can't */
- if (SkipLim->Set1 != NULL) { /* skip this */
- SetFixLim = SkipLim->Set1; /* INCLUDE file */
- SetFixLim++; /* in pass 2. */
- }
- }
- }
- if ((HunkType == HunkNone) && (AddrAdv != 0)) {
- DoSection ("", 0, "", 0, "", 0); /* Start unnamed CODE section. */
- MakeHunk = TRUE;
- }
- if ((Label[0] != '\0') /* If the statement is labeled */
- && (Dir != Set) && (Dir != Equr) && (Dir != Reg)) {
- if (!ReadSymTab (Label)) { /* Make a new entry. */
- AddSymTab (Label, AddrCnt, CurrHunk, LineCount, 0);
- } else if ((Sym->Flags & 1) /* If dup., ignore... */
- || (Sym->Defn == NODEF)) { /* else fill in... */
- Sym->Val = AddrCnt; /* Current loc. */
- Sym->Hunk = CurrHunk; /* Hunk number */
- Sym->Defn = LineCount; /* Statement number */
- Sym->Flags &= ~1; /* Clear XREF flag. */
- if (Sym->Flags & 0x80) { /* If it's PUBLIC, */
- Sym->Flags |= 2; /* make it XDEF. */
- }
- }
- else isError=TRUE; /* bugfix by Kevin Kofler for the TIGCC team in
- v.2.71.F3a
- if duplicate, set "error detected" flag */
- if (Dir == Equ) {
- Sym->Val = ObjSrc; /* Equated value */
- Sym->Hunk = Src.Hunk; /* Hunk number */
- }
- if (!NoOpt && (Dir != Equ)) { /* Forward optimization */
- PackFwdBranch (/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* Drop expired entries. */
- fp1 = FwdBranch;
- while (fp1 < FwdLim1) { /* Scan forward branches. */
- if (fp1->FwdSym == Sym) { /* It branched here. */
- if (fp1->Loc != (AddrCnt-4)) { /* Don't make zero displacement! */
- if (fp1->Line < LineCount)
- Sym->Val -= 2; /* Move the label back. */
- AddrCnt -= 2; /* Shorten the program. */
- for (fsp = FwdBranchFix; fsp < FwdFixLimit; fsp++) {
- if (fp1->Loc<(*fsp)->Val) { /* Adjust labels */
- (*fsp)->Val -= 2; /* within range. */
- }
- }
- if ((char *) FwdLim2 >= ((char *) FwdCurr + FWDSIZE)) {
- FwdCurr->Link = /* Get a new chunk. */
- (struct FwdTable *) malloc ((unsigned) FWDSIZE);
- if (FwdCurr->Link == NULL)
- quit_cleanup ("Out of memory!\n");
- FwdCurr = FwdCurr->Link;
- FwdCurr->Link = NULL; /* Make sure it does not link to anything
- It is a freshly allocated block AT THE END of the linked list!
- bugfix submitted by [Pollux] (Paul Froissart) for 2.71.F3a */
- FwdLim2 = (int *)
- ((char *) FwdCurr + sizeof (struct FwdTable *));
- }
- *FwdLim2++ = fp1->Line; /* Flag this branch in pass 2. */
- }
- fp3 = fp2 = fp1;
- fp3++;
- while (fp3 < FwdLim1) { /* Remove processed entry. */
- fp2->Loc = fp3->Loc - 2; /* Locations shifted too! */
- fp2->FwdSym = fp3->FwdSym;
- fp2->Line = fp3->Line;
- fp2++;
- fp3++;
- }
- FwdLim1--; /* Decrement table limit pointer. */
- fp1--; /* Offset increment below. */
- }
- fp1++; /* Check the next entry. */
- }
- if (FwdLim1 > FwdBranch) { /* Store labels within */
- *FwdFixLimit++ = Sym; /* range of fwd. branch. */
- }
- }
- }
- AddrCnt += AddrAdv * DupFact; /* Advance the location counter. */
- if (endfile) { /* END is now optional */
- strcpy(Line," end"); endfile=0; /* Enhancement by Paul Froissart */
- SubArgs(/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); GetParts(/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* in version v2.71.F3c */
- goto pass1cont;
- }
- }
- if ((HunkType == HunkNone) && (NumSyms != 0)) { /* Dummy section */
- DoSection ("", 0, "", 0, "", 0); /* to get XDEF */
- MakeHunk = TRUE; /* symbols if any */
- }
- if (HunkType != HunkNone)
- if (AddrCnt > OrgHigh)
- Sect->Val = AddrCnt; /* End of the last section */
- else
- Sect->Val = OrgHigh; /* We've ORGed higher. */
- if (InclErrs)
- quit_cleanup ("Fatal errors - assembly aborted\n");
- if (Quiet > 0)
- fprintf (stderr, "%d\n", LineCount);
- else if (Quiet < 0)
- fprintf (stderr, "%d\n\n", InF->Line);
- /*----------------------------------------------------------------
- Begin Pass 2.
- */
- Pass2 = TRUE;
- lseek (In.fd, 0L, 0); /* "Rewind" the source file. */
- In.Ptr = In.Lim = In.Buf;
- startpass ('2', maxheap2);
- /* RefLim = (struct Ref *) SymLim; */ /* Cross-reference table */
- RefLim = (struct Ref *) (SymLim+1);
- /* don't overwrite the last symbol - Kevin Kofler, v.2.71.F3h */
- /* Calculate the total size of each section type,
- reset all section pointers to the beginning, and
- write all absolute symbols to an equate file if desired. */
- codesize = datasize = bsssize = 0;
- if (EquateFN[0]) {
- xputs (&Eq, "* Equate file for ");
- xputs (&Eq, SourceFN);
- xputs (&Eq, "\n* Created by");
- xputs (&Eq, " A68k version ");
- xputs (&Eq, Version);
- xputs (&Eq, "\n");
- }
- Sym = SymChunk = SymStart;
- Sym++;
- SymChLim = (struct SymTab *) ((char *) SymChunk + CHUNKSIZE);
- while (Sym) {
- if (Sym->Flags & 0x10) {
- templong = (Sym->Val + 3) & ~3L; /* Hunk size */
- j = (Sym->Hunk & 0x3FFF0000L) >> 16; /* Hunk type */
- if (j == HunkCode) /* Accumulate sizes by type. */
- codesize += templong;
- else if (j == HunkData)
- datasize += templong;
- else
- bsssize += templong;
- Sym->Val = 0L; /* Back to start of all sections */
- }
- if (EquateFN[0]) {
- if (((Sym->Hunk & 0x00007FFFL) == ABSHUNK)
- && ((Sym->Flags == 0) || (Sym->Flags == 2))) {
- xputs (&Eq, Sym->Nam);
- xputs (&Eq, "\tEQU\t$");
- LongPut (&Eq, Sym->Val, 4);
- xputs (&Eq, "\n");
- }
- }
- Sym = NextSym (Sym); /* Try for another symbol table entry. */
- }
- if (EquateFN[0])
- xclose (&Eq);
- /* Write sign-on messages for listing file. */
- LnCnt = LnMax;
- PgCnt = 0;
- if (!SuppList) {
- CheckPage (&List, FALSE); /* Print headings. */
- xputs (&List, "68000 Assembler - version ");
- xputs (&List, Version);
- xputs (&List, "\nCopyright 1985 by Brian R. Anderson.\n");
- xputs (&List, "AmigaDOS conversion copyright 1991");
- xputs (&List, " by Charlie Gibbs.\n\n");
- LnCnt += 4;
- }
- StartSrec (&Srec, IdntName); /* Write object header record. */
- /* Process the second pass. */
- endfile = FALSE;
- Dir = None;
- while (!endfile && (Dir != End)) {
- PrevDir = Dir; /* Save previous directive. */
- endfile = LineParts (/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* Get a statement. */
- /* if (!endfile) { */
- pass2cont: /* necessary for optional END - Paul Froissart, v.2.71.F3c */
- GetObjectCode (/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* Process the statement. */
- if (Label[0] != '\0') { /* If statement is labeled, */
- ReadSymTab (Label); /* check for duplicate defn. */
- if (Sym) /* Check if Sym actually exists -- bugfix by Kevin Kofler for
- the TIGCC Team in v.2.71.F3a. */
- { /* (TIGCC) */
- if (Sym->Defn != LineCount) {
- AddRef (LineCount); /* Got one - flag as reference. */
- if (Dir == Set) {
- if ((Sym->Flags & 4) == 0)
- Error (LabLoc, SymDup); /* Can't SET normal label. */
- } else {
- Error (LabLoc, SymDup); /* Ordinary duplicate */
- }
- } else if (Dir == Set) {
- AddRef (LineCount); /* Flag all SETs as references. */
- } else {
- if (Sym->Val != AddrCnt)
- if ((Dir != Equ) && (Dir != Equr) && (Dir != Reg))
- Error (0, Phase); /* Assembler error */
- }
- } /* (TIGCC) */
- else /* (TIGCC) */
- Error (0, Phase); /* (TIGCC) */
- }
- WriteListLine (&List);
- /* WriteSrecLine (&Srec); */
- WriteSrecLine (); /* removed useless parameter - Kevin Kofler, v.2.71.F3d */
- AddrCnt += AddrAdv * DupFact; /* Advance the location counter. */
- /* } else {
- Error (0, EndErr); ** END statement is missing. **
- WriteListLine (&List); */
- if (endfile) { /* END is now optional */
- strcpy(Line," end"); endfile=0; /* Enhancement by Paul Froissart */
- SubArgs(/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); GetParts(/*dummy*/ /*(using now void in v.2.71.F3d - Kevin Kofler)*/); /* in version v2.71.F3c */
- goto pass2cont;
- }
- }
- if ((HunkType == HunkNone) && (NumSyms != 0)) { /* Dummy section */
- DoSection ("", 0, "", 0, "", 0); /* to get XDEF */
- MakeHunk = TRUE; /* symbols if any */
- }
- /*----------------------------------------------------------------
- Clean up.
- */
- if (HunkType != HunkNone)
- if (AddrCnt > OrgHigh)
- Sect->Val = AddrCnt; /* End of the last section */
- else
- Sect->Val = OrgHigh; /* We've ORGed higher. */
- if (Quiet > 0)
- fprintf (stderr, "%d", LineCount); /* Final line number */
- else if (Quiet < 0)
- fprintf (stderr, "%d\n", InF->Line);
- fflush (stderr); /* Make sure it gets out. */
- close (In.fd); /* We're finished with the source file. */
- In.fd = NOFD;
- free (In.Buf);
- In.Buf = NULL;
- EndSdata (&Srec, EndAddr); /* Write remaining data and end record. */
- xclose (&Srec); /* We're finished with the object file. */
- if ((ErrorCount != 0) && (!keepobj))
- unlink (SrecFN); /* Scratch it if there were errors. */
- RelCurr = RelStart;
- RelStart = NULL;
- while (RelCurr != NULL) {
- RelLim = RelCurr;
- RelCurr = RelCurr->Link;
- free (RelLim); /* Free the relocation table. */
- }
- if (Heap2 != NULL) {
- free (Heap2); /* Free the secondary heap. */
- Heap2 = NULL;
- }
- if (XrefList)
- WriteSymTab (&List); /* List the symbol table. */
- /* Display final error count. */
- if (Quiet != 0)
- fprintf (stderr, "\nEnd of assembly - ");
- if (!SuppList)
- xputs (&List, "\nEnd of assembly - ");
- if (ErrorCount == 0) {
- if (Quiet != 0)
- fprintf (stderr, "no errors were found.\n");
- if (!SuppList)
- xputs (&List, "no errors were found.\n");
- } else if (ErrorCount == 1) {
- if (Quiet != 0)
- fprintf (stderr, "1 error was found.\n");
- if (!SuppList)
- xputs (&List, "1 error was found.\n");
- } else {
- if (Quiet != 0)
- fprintf (stderr, "%d errors were found.\n", ErrorCount);
- if (!SuppList) {
- sprintf (tempchar, "%d errors were found.\n", ErrorCount);
- xputs (&List, tempchar);
- }
- }
- /* Display heap usage. */
- if (Quiet != 0)
- fprintf (stderr, "Heap usage: -w%ld", HashSize);
- if (!SuppList) {
- sprintf (tempchar, "Heap usage: -w%ld", HashSize);
- xputs (&List, tempchar);
- }
- templong = (long) (High2 - Heap2);
- if (Low2 < (char *) LowInF)
- templong += (long) (Heap2 + maxheap2 - Low2);
- else
- templong += (long) (Heap2 + maxheap2 - (char *) LowInF);
- if (Quiet != 0)
- fprintf (stderr, ",%ld\n", templong);
- if (!SuppList) {
- sprintf (tempchar, ",%ld\n", templong);
- xputs (&List, tempchar);
- }
- /* Display the total size of all section types. */
- if (Quiet != 0) {
- fprintf (stderr, "Total hunk sizes: %lx code, ", codesize);
- fprintf (stderr, "%lx data, %lx BSS\n", datasize, bsssize);
- }
- if (!SuppList) {
- sprintf (tempchar, "Total hunk sizes: %lx code, ", codesize);
- xputs (&List, tempchar);
- sprintf (tempchar, "%lx data, %lx BSS\n", datasize, bsssize);
- xputs (&List, tempchar);
- }
- /* Display hashing statistics if required. */
- if (HashStats && (NumSyms != 0)) {
- printf ("\n");
- printf ("HASH CHAIN STATISTICS - %d symbols\n\n", NumSyms);
- templong = (NumSyms + 1) * sizeof (int);
- HashCount = (int *) malloc ((unsigned) templong);
- if (HashCount == NULL)
- quit_cleanup ("Out of memory!\n");
- printf ("Length No. of chains\n");
- printf ("------ -------------\n");
- intptr = HashCount;
- for (i = 0; i <= NumSyms; i++)
- *(intptr++) = 0; /* Clear hash chain length counters. */
- hashptr = Hash;
- for (i = 0; i < HashSize; i++) {
- j = 0;
- if ((Sym = *hashptr) != NULL) {
- j++; /* This chain has at least one entry. */
- while ((Sym = Sym->Link) != NULL) {
- j++; /* Count entries in the chain. */
- }
- }
- intptr = HashCount + j;
- (*intptr)++; /* Bump counter by chain length. */
- hashptr++;
- }
- intptr = HashCount;
- for (i = 0; i <= NumSyms; i++) {
- if (*intptr)
- printf ("%4d %4d\n", i, *intptr);
- intptr++;
- }
- free (HashCount); /* Free hash statistics table. */
- HashCount = NULL;
- }
- /* All done! */
- if (!SuppList) {
- xputs (&List, "\f"); /* One last page eject */
- xclose (&List); /* We're finished with the listing file. */
- }
- quit_cleanup (""); /* Normal termination */
- }
- /*======================================================================*/
- /* */
- /* Subroutines used by the main program */
- /* */
- /*======================================================================*/
- int getfilename (name, arg, desc, needit)
- char *name, *arg, *desc;
- int needit;
- /* If "name" is not a duplicate, copies "arg" to it, else flags
- duplicate using "desc". If "needit" is TRUE, also flags
- an error if "arg" is a null string.
- Returns TRUE if an error is found, FALSE otherwise. */
- {
- if (*name) {
- fprintf (stderr, "%s file is declared more than once.\n", desc);
- return (TRUE);
- }
- if (*arg) {
- strcpy (name, arg);
- return (FALSE);
- }
- if (needit) {
- fprintf (stderr, "%s file name is missing\n", desc);
- return (TRUE);
- }
- return (FALSE);
- }
- int checkswitch (sw, name) char *sw, *name;
- /* Displays an error message and returns TRUE if the argument
- pointed to by "s" is more than two characters long.
- Just returns FALSE otherwise. */
- {
- if (strlen (sw) > 2) {
- fprintf (stderr, "Invalid %s switch (%s).\n", name, sw);
- return (TRUE);
- } else {
- return (FALSE);
- }
- }
- void defaultfile (name, ext) char *name, *ext;
- /* If "name" is a null string, search for the last period in "name"
- (if any) and append "ext".
- If "name" doesn't contain a period, append a period and "ext". */
- {
- char *s;
- if (*name == '\0') { /* If name isn't specified... */
- strcpy (name,SourceFN); /* Start with source file name. */
- s = name+strlen(name); /* Scan backwards for period. */
- while (--s > name) {
- if (*s == '.') {
- *s = '\0'; /* Chop off name extension. */
- break;
- }
- }
- strcat (name, ext); /* Add name extension. */
- }
- }
- int checkdupfile (name1, desc1, name2, desc2)
- char *name1, *desc1, *name2, *desc2;
- /* If "name1" is the same as "name2", display an error message using
- "desc1" and "desc2" and return TRUE. Otherwise, return FALSE. */
- {
- if (strcmp (name1, name2) == 0) {
- fprintf (stderr,
- "%s and %s file names are the same.\n", desc1, desc2);
- return (TRUE);
- } else {
- return (FALSE);
- }
- }
- void startpass (pchar, maxheap2) char pchar; long maxheap2;
- /* Set up to start the next pass. */
- {
- if (Quiet > 0) {
- fprintf (stderr, "PASS %c line ", pchar);
- fflush (stderr);
- } else if (Quiet < 0) {
- fprintf (stderr, "PASS %c\n", pchar);
- }
- NextFNS = Heap2;
- InF = (struct InFCtl *) (Heap2 + maxheap2);
- InF--;
- InFNum = OuterMac = SkipNest = InF->Pos = InF->MCnt = 0;
- InF->Line = 0;
- InF->UPtr = 0;
- InF->NPtr = NextFNS;
- InF->NArg = -1;
- InF->MCnt = 0;
- strcpy (NextFNS, SourceFN);
- ShowFile (FALSE); /* Show source file name. */
- NextFNS += strlen (SourceFN) + 1;
- LineCount = LabLine = MacCount = ErrorCount = 0;
- AddrCnt = CurrHunk = SectStart = EndAddr = 0L;
- HunkType = HunkNone; /* We're not in a hunk yet. */
- HunkFlags = SectLine = HunkSeq = 0;
- ListOff = MakeHunk = InnrFMac = FALSE;
- SmallData = -1;
- TTLstring[0] = '\0'; /* Clear the title string. */
- }
- void quit_cleanup (s) char *s;
- /* Clean up and exit. If "s" doesn't point to a null string, print the
- string as an error message, remove the partially-formed object
- file if it exists, and exit with an error code. */
- {
- if (In.fd != NOFD) /* Close all files... */
- close (In.fd);
- if (In.Buf != NULL) /* and free buffers. */
- free (In.Buf);
- if (Srec.fd != NOFD)
- xclose (&Srec);
- if (List.fd != NOFD)
- xclose (&List);
- if (Eq.fd != NOFD)
- xclose (&Eq);
- if (Hash != NULL)
- free (Hash); /* Free the hash table. */
- SymCurr = SymStart;
- while (SymCurr != NULL) {
- SymLim = SymCurr;
- SymCurr = SymCurr->Link;
- free (SymLim); /* Free the symbol table. */
- }
- NameCurr = NameStart;
- while (NameCurr != NULL) {
- NameLim = (char *) NameCurr;
- NameCurr = NameCurr->Link;
- free (NameLim); /* Free the name table. */
- }
- RelCurr = RelStart;
- while (RelCurr != NULL) {
- RelLim = RelCurr;
- RelCurr = RelCurr->Link;
- free (RelLim); /* Free the relocation table. */
- }
- FwdCurr = FwdStart;
- while (FwdCurr != NULL) {
- FwdLim2 = (int *) FwdCurr;
- FwdCurr = FwdCurr->Link;
- free (FwdLim2); /* Free the forward branch log. */
- }
- if (Heap2 != NULL)
- free (Heap2); /* Free the secondary heap. */
- if (SymSort != NULL)
- free (SymSort); /* Free symbol table sort area. */
- if (HashCount != NULL)
- free (HashCount); /* Free hash statistics table. */
- /* Get rid of leftover AddrDiffs list -- Kevin Kofler, v.2.71.F3l */
- while (AddrDiffs) {
- struct AddrDiff *next=AddrDiffs->Link;
- free(AddrDiffs);
- AddrDiffs=next;
- }
- if (*s) { /* If we have an error message, */
- if (SrecFN[0])
- unlink (SrecFN); /* scratch the object file, */
- fprintf (stderr, "%s", s); /* display the error message, */
- exit (20); /* and die. */
- } else {
- exit (ErrorCount ? 10 : 0); /* Normal termination */
- }
- }
|