ELF support for RMAC.
authorShamus Hammons <jlhamm@acm.org>
Fri, 14 Apr 2017 20:52:31 +0000 (15:52 -0500)
committerShamus Hammons <jlhamm@acm.org>
Fri, 14 Apr 2017 20:52:31 +0000 (15:52 -0500)
ggn deserves most of the credit for this, as my job was going through
and tossing out the stuff that wasn't needed. ;-) There might be some
ELFish things that still need fixing; time, as usual, will tell.

40 files changed:
68kgen.c
Vs2015/rmac/rmac.vcxproj
amode.c
amode.h
debug.c
debug.h
direct.c
direct.h
eagen.c
eagen0.c
error.c
error.h
expr.c
expr.h
kwgen.c
listing.c
listing.h
mach.c
mach.h
macro.c
macro.h
makefile
mark.c
mark.h
object.c
object.h
parmode.h
procln.c
procln.h
riscasm.c
riscasm.h
rmac.c
rmac.h
sect.c
sect.h
symbol.c
symbol.h
token.c
token.h
version.h

index c5ea85f9756627958871e19b6dbe28670de7e5ca..a51b105c45e90eed4b96d792ce0240bd51382f76 100644 (file)
--- a/68kgen.c
+++ b/68kgen.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // 68KGEN.C - Tool to Generate 68000 Opcode Table
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // 68KGEN.C - Tool to Generate 68000 Opcode Table
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
index e03e65d6fa0d2ed53a9ee57dcc4569912cdd3d10..a127bd8f874fb7c054a7b5ecc383ec28529ef3ff 100644 (file)
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
-    <OutDir>$(SolutionDir)\..\</OutDir>
+    <OutDir>$(SolutionDir)\..</OutDir>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
diff --git a/amode.c b/amode.c
index b09b2da57cb63fc4b6880e4e320c9f0d9811d1c6..f0734ea5916dc8f6c86007954062fd162372b1e6 100644 (file)
--- a/amode.c
+++ b/amode.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // AMODE.C - Addressing Modes
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // AMODE.C - Addressing Modes
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -78,7 +78,7 @@ int amode(int acount)
        #define CHK_FOR_DISPn CheckForDisp0
        #include "parmode.h"
 
        #define CHK_FOR_DISPn CheckForDisp0
        #include "parmode.h"
 
-       // If caller wants only one mode, return just one (ignore comma); 
+       // If caller wants only one mode, return just one (ignore comma);
        // If there is no second addressing mode (no comma), then return just one anyway.
        nmodes = 1;
 
        // If there is no second addressing mode (no comma), then return just one anyway.
        nmodes = 1;
 
@@ -146,7 +146,7 @@ int reglist(WORD * a_rmask)
 
                        if (*tok >= KW_D0 && *tok <= KW_A7)
                                cnt = *tok++ & 15;
 
                        if (*tok >= KW_D0 && *tok <= KW_A7)
                                cnt = *tok++ & 15;
-                       else 
+                       else
                                return error("register list syntax");
 
                        if (cnt < r)
                                return error("register list syntax");
 
                        if (cnt < r)
@@ -154,7 +154,7 @@ int reglist(WORD * a_rmask)
 
                        cnt -= r;
                }
 
                        cnt -= r;
                }
-               else 
+               else
                        cnt = 0;
 
                while (cnt-- >= 0)
                        cnt = 0;
 
                while (cnt-- >= 0)
diff --git a/amode.h b/amode.h
index eba0e5f7af1685a7a72b2f119cba66917a08c97a..d0eb7706be6aeb5f830bee8394e415908a74154a 100644 (file)
--- a/amode.h
+++ b/amode.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // AMODE.H - Addressing Modes
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // AMODE.H - Addressing Modes
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -39,7 +39,7 @@
 #define M_DREG       0x00000001L               // Dn
 #define M_AREG       0x00000002L               // An
 #define M_AIND       0x00000004L               // (An)
 #define M_DREG       0x00000001L               // Dn
 #define M_AREG       0x00000002L               // An
 #define M_AIND       0x00000004L               // (An)
-#define M_APOSTINC   0x00000008L               // (An)+ 
+#define M_APOSTINC   0x00000008L               // (An)+
 #define M_APREDEC    0x00000010L               // -(An)
 #define M_ADISP      0x00000020L               // (d16,An) d16(An)
 #define M_AINDEXED   0x00000040L               // (d8,An,Xn) d8(An,Xn)
 #define M_APREDEC    0x00000010L               // -(An)
 #define M_ADISP      0x00000020L               // (d16,An) d16(An)
 #define M_AINDEXED   0x00000040L               // (d8,An,Xn) d8(An,Xn)
diff --git a/debug.c b/debug.c
index 7e60196089b68d11d0c6dbdf823e68a77e70d284..6359cfbc2bddf5909807c3d65d20262d876fa9fe 100644 (file)
--- a/debug.c
+++ b/debug.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DEBUG.C - Debugging Messages
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DEBUG.C - Debugging Messages
-// Copyright (C) 199x Landon Dyer, 2011-2012 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -43,8 +43,7 @@ TOKEN * printexpr(TOKEN * tp)
                        switch ((int)*tp++)
                        {
                        case SYMBOL:
                        switch ((int)*tp++)
                        {
                        case SYMBOL:
-//                             printf("`%s' ", ((SYM *)*tp)->sname);
-                               printf("`%s' ", symbolPtr[*tp]->sname);
+                               printf("'%s' ", symbolPtr[*tp]->sname);
                                tp++;
                                break;
                        case CONST:
                                tp++;
                                break;
                        case CONST:
@@ -61,7 +60,6 @@ TOKEN * printexpr(TOKEN * tp)
                }
        }
 
                }
        }
 
-//     printf(";\n");
        return tp + 1;
 }
 
        return tp + 1;
 }
 
@@ -88,28 +86,24 @@ int chdump(CHUNK * ch, int format)
 int fudump(CHUNK * ch)
 {
        PTR p;
 int fudump(CHUNK * ch)
 {
        PTR p;
-       char * ep;
-       WORD attr, esiz;
-       WORD line, file;
-       LONG loc;
 
        for(; ch!=NULL;)
        {
                p.cp = ch->chptr;
 
        for(; ch!=NULL;)
        {
                p.cp = ch->chptr;
-               ep = ch->chptr + ch->ch_size;
+               uint8_t * ep = ch->chptr + ch->ch_size;
 
                while (p.cp < ep)
                {
 
                while (p.cp < ep)
                {
-                       attr = *p.wp++;
-                       loc = *p.lp++;
-                       file = *p.wp++;
-                       line = *p.wp++;
+                       uint16_t attr = *p.wp++;
+                       uint32_t loc = *p.lp++;
+                       uint16_t file = *p.wp++;
+                       uint16_t line = *p.wp++;
 
                        printf("$%04X $%08X %d.%d: ", (int)attr, loc, (int)file, (int)line);
 
                        if (attr & FU_EXPR)
                        {
 
                        printf("$%04X $%08X %d.%d: ", (int)attr, loc, (int)file, (int)line);
 
                        if (attr & FU_EXPR)
                        {
-                               esiz = *p.wp++;
+                               uint16_t esiz = *p.wp++;
                                printf("(%d long) ", (int)esiz);
                                p.tk = printexpr(p.tk);
                        }
                                printf("(%d long) ", (int)esiz);
                                p.tk = printexpr(p.tk);
                        }
@@ -155,7 +149,7 @@ int mudump(void)
                        mch, (mch->mcptr.lw), mch->mcalloc, (mch->mcused));
 
                p = mch->mcptr;
                        mch, (mch->mcptr.lw), mch->mcalloc, (mch->mcused));
 
                p = mch->mcptr;
-               
+
                for(;;)
                {
                        w = *p.wp++;
                for(;;)
                {
                        w = *p.wp++;
@@ -192,7 +186,7 @@ int mudump(void)
 // 0 - bytes
 // 1 - words
 // 2 - longwords
 // 0 - bytes
 // 1 - words
 // 2 - longwords
-// 
+//
 // if `base' is not -1, then print it at the start of each line, incremented
 // accordingly.
 //
 // if `base' is not -1, then print it at the start of each line, incremented
 // accordingly.
 //
@@ -209,7 +203,7 @@ int mdump(char * start, LONG count, int flg, LONG base)
                        {
                                printf("  ");
 
                        {
                                printf("  ");
 
-                               while(j < i)
+                               while (j < i)
                                visprt(start[j++]);
 
                                putchar('\n');
                                visprt(start[j++]);
 
                                putchar('\n');
@@ -225,7 +219,7 @@ int mdump(char * start, LONG count, int flg, LONG base)
                {
                case 0:
                        printf("%02X ", start[i] & 0xff);
                {
                case 0:
                        printf("%02X ", start[i] & 0xff);
-                       ++i;
+                       i++;
                        break;
                case 1:
                        printf("%02X%02X ", start[i] & 0xff, start[i+1] & 0xff);
                        break;
                case 1:
                        printf("%02X%02X ", start[i] & 0xff, start[i+1] & 0xff);
@@ -250,12 +244,12 @@ int mdump(char * start, LONG count, int flg, LONG base)
        {
                k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
 
        {
                k = ((16 - (i - j)) / (1 << (flg & 3))) * siztab[flg & 3];
 
-               while(k--)
+               while (k--)
                        putchar(' ');
 
                printf("  ");
 
                        putchar(' ');
 
                printf("  ");
 
-               while(j < i)
+               while (j < i)
                        visprt(start[j++]);
 
                putchar('\n');
                        visprt(start[j++]);
 
                putchar('\n');
@@ -291,34 +285,34 @@ int dumptok(TOKEN * tk)
                case STRING:                                       // STRING <address>
                        printf("STRING='%s'", string[*tk++]);
                        break;
                case STRING:                                       // STRING <address>
                        printf("STRING='%s'", string[*tk++]);
                        break;
-               case SYMBOL:                                       // SYMBOL <address> 
+               case SYMBOL:                                       // SYMBOL <address>
                        printf("SYMBOL='%s'", string[*tk++]);
                        break;
                        printf("SYMBOL='%s'", string[*tk++]);
                        break;
-               case EOL:                                          // End of line 
+               case EOL:                                          // End of line
                        printf("EOL");
                        break;
                case TKEOF:                                        // End of file (or macro)
                        printf("TKEOF");
                        break;
                        printf("EOL");
                        break;
                case TKEOF:                                        // End of file (or macro)
                        printf("TKEOF");
                        break;
-               case DEQUALS:                                      // == 
+               case DEQUALS:                                      // ==
                        printf("DEQUALS");
                        break;
                        printf("DEQUALS");
                        break;
-               case DCOLON:                                       // :: 
+               case DCOLON:                                       // ::
                        printf("DCOLON");
                        break;
                        printf("DCOLON");
                        break;
-               case GE:                                           // >= 
+               case GE:                                           // >=
                        printf("GE");
                        break;
                        printf("GE");
                        break;
-               case LE:                                           // <= 
+               case LE:                                           // <=
                        printf("LE");
                        break;
                        printf("LE");
                        break;
-               case NE:                                           // <> or != 
+               case NE:                                           // <> or !=
                        printf("NE");
                        break;
                        printf("NE");
                        break;
-               case SHR:                                          // >> 
+               case SHR:                                          // >>
                        printf("SHR");
                        break;
                        printf("SHR");
                        break;
-               case SHL:                                          // << 
+               case SHL:                                          // <<
                        printf("SHL");
                        break;
                default:
                        printf("SHL");
                        break;
                default:
@@ -338,9 +332,7 @@ int dumptok(TOKEN * tk)
 //
 int dump_everything(void)
 {
 //
 int dump_everything(void)
 {
-       int i;
-
-       for(i=1; i<NSECTS; i++)
+       for(int i=1; i<NSECTS; i++)
        {
                if (sect[i].scattr & SUSED)
                {
        {
                if (sect[i].scattr & SUSED)
                {
@@ -357,7 +349,7 @@ int dump_everything(void)
 
        printf("\nMarks:\n");
        mudump();                                                               // Dump marks
 
        printf("\nMarks:\n");
        mudump();                                                               // Dump marks
-//     printf("Total memory allocated=$%X\n", amemtot);
 
        return 0;
 }
 
        return 0;
 }
+
diff --git a/debug.h b/debug.h
index 456f94575386aacd44dc9b003891bdbf84112d27..7c738cc232bdae444c0c4a1eb3b4d9dc9cf2ee91 100644 (file)
--- a/debug.h
+++ b/debug.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DEBUG.H - Debugging Messages
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DEBUG.H - Debugging Messages
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
index 6237ce2e418d715c464cedab0813ff6a1842b7c0..b2e67998e863a7a216e16b8b8b4f2bd8dd39599d 100644 (file)
--- a/direct.c
+++ b/direct.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DIRECT.C - Directive Handling
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DIRECT.C - Directive Handling
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -77,8 +77,8 @@ int (*dirtab[])() = {
        d_title,                        // 44 title
        d_subttl,                       // 45 subttl
        eject,                          // 46 eject
        d_title,                        // 44 title
        d_subttl,                       // 45 subttl
        eject,                          // 46 eject
-       d_error,                        // 47 error 
-       d_warn,                         // 48 warn 
+       d_error,                        // 47 error
+       d_warn,                         // 48 warn
        d_noclear,                      // 49 .noclear
        d_equrundef,            // 50 .equrundef/.regundef
        d_ccundef,                      // 51 .ccundef
        d_noclear,                      // 49 .noclear
        d_equrundef,            // 50 .equrundef/.regundef
        d_ccundef,                      // 51 .ccundef
@@ -141,7 +141,7 @@ int d_org(void)
 {
        VALUE address;
 
 {
        VALUE address;
 
-       if (!rgpu && !rdsp) 
+       if (!rgpu && !rdsp)
                return error(".org permitted only in gpu/dsp section");
 
        orgaddr = 0;
                return error(".org permitted only in gpu/dsp section");
 
        orgaddr = 0;
@@ -184,7 +184,7 @@ int d_print(void)
                        sprintf(prntstr, "%s", string[tok[1]]);
                        printf("%s", prntstr);
 
                        sprintf(prntstr, "%s", string[tok[1]]);
                        printf("%s", prntstr);
 
-                       if (list_fd) 
+                       if (list_fd)
                                unused = write(list_fd, prntstr, (LONG)strlen(prntstr));
 
                        tok += 2;
                                unused = write(list_fd, prntstr, (LONG)strlen(prntstr));
 
                        tok += 2;
@@ -222,9 +222,9 @@ int d_print(void)
                        {
                                switch(outtype)
                                {
                        {
                                switch(outtype)
                                {
-                               case 0: strcpy(format, "%X"); break; 
-                               case 1: strcpy(format, "%d" ); break; 
-                               case 2: strcpy(format, "%u" ); break; 
+                               case 0: strcpy(format, "%X"); break;
+                               case 1: strcpy(format, "%d" ); break;
+                               case 2: strcpy(format, "%u" ); break;
                                }
 
                                if (wordlong)
                                }
 
                                if (wordlong)
@@ -234,7 +234,7 @@ int d_print(void)
 
                                printf("%s", prntstr);
 
 
                                printf("%s", prntstr);
 
-                               if (list_fd) 
+                               if (list_fd)
                                        unused = write(list_fd, prntstr, (LONG)strlen(prntstr));
 
                                formatting = 0;
                                        unused = write(list_fd, prntstr, (LONG)strlen(prntstr));
 
                                formatting = 0;
@@ -341,7 +341,7 @@ int d_noclear(void)
 }
 
 
 }
 
 
-// 
+//
 // Include binary file
 //
 int d_incbin(void)
 // Include binary file
 //
 int d_incbin(void)
@@ -420,7 +420,7 @@ allright:
 }
 
 
 }
 
 
-// 
+//
 // Set RISC register banks
 //
 int d_regbank0(void)
 // Set RISC register banks
 //
 int d_regbank0(void)
@@ -468,7 +468,7 @@ static inline void SkipBytes(unsigned bytesToSkip)
 int d_even(void)
 {
        unsigned skip = (rgpu || rdsp ? orgaddr : sloc) & 0x01;
 int d_even(void)
 {
        unsigned skip = (rgpu || rdsp ? orgaddr : sloc) & 0x01;
-       
+
        if (skip)
        {
                if ((scattr & SBSS) == 0)
        if (skip)
        {
                if ((scattr & SBSS) == 0)
@@ -581,7 +581,7 @@ int d_unimpl(void)
 }
 
 
 }
 
 
-// 
+//
 // Return absolute (not TDB) and defined expression or return an error
 //
 int abs_expr(VALUE * a_eval)
 // Return absolute (not TDB) and defined expression or return an error
 //
 int abs_expr(VALUE * a_eval)
@@ -642,7 +642,7 @@ int d_include(void)
        char buf[128];
        char buf1[128];
 
        char buf[128];
        char buf1[128];
 
-       if (*tok == STRING)                     // Leave strings ALONE 
+       if (*tok == STRING)                     // Leave strings ALONE
                fn = string[*++tok];
        else if (*tok == SYMBOL)        // Try to append ".s" to symbols
        {
                fn = string[*++tok];
        else if (*tok == SYMBOL)        // Try to append ".s" to symbols
        {
@@ -650,7 +650,7 @@ int d_include(void)
                fext(buf, ".s", 0);
                fn = &buf[0];
        }
                fext(buf, ".s", 0);
                fn = &buf[0];
        }
-       else                                            // Punt if no STRING or SYMBOL 
+       else                                            // Punt if no STRING or SYMBOL
                return error("missing filename");
 
        // Make sure the user didn't try anything like:
                return error("missing filename");
 
        // Make sure the user didn't try anything like:
@@ -660,14 +660,15 @@ int d_include(void)
 
        // Attempt to open the include file in the current directory, then (if that
        // failed) try list of include files passed in the enviroment string or by
 
        // Attempt to open the include file in the current directory, then (if that
        // failed) try list of include files passed in the enviroment string or by
-       // the "-d" option.
+       // the "-i" option.
        if ((j = open(fn, 0)) < 0)
        {
                for(i=0; nthpath("RMACPATH", i, buf1)!=0; i++)
                {
                        j = strlen(buf1);
 
        if ((j = open(fn, 0)) < 0)
        {
                for(i=0; nthpath("RMACPATH", i, buf1)!=0; i++)
                {
                        j = strlen(buf1);
 
-                       if (j > 0 && buf1[j - 1] != SLASHCHAR)  // Append path char if necessary 
+                       // Append path char if necessary
+                       if (j > 0 && buf1[j - 1] != SLASHCHAR)
                                strcat(buf1, SLASHSTRING);
 
                        strcat(buf1, fn);
                                strcat(buf1, SLASHSTRING);
 
                        strcat(buf1, fn);
@@ -727,7 +728,7 @@ int globl1(char * p)
                sy->sattr = GLOBAL;
 //printf("glob1: Making global symbol: attr=%04X, eattr=%08X, %s\n", sy->sattr, sy->sattre, sy->sname);
        }
                sy->sattr = GLOBAL;
 //printf("glob1: Making global symbol: attr=%04X, eattr=%08X, %s\n", sy->sattr, sy->sattre, sy->sname);
        }
-       else 
+       else
                sy->sattr |= GLOBAL;
 
        return OK;
                sy->sattr |= GLOBAL;
 
        return OK;
@@ -846,7 +847,7 @@ int d_ds(WORD siz)
        if (as68_flag == 0 && (scattr & SBSS) == 0)
                return error(".ds permitted only in BSS");
 
        if (as68_flag == 0 && (scattr & SBSS) == 0)
                return error(".ds permitted only in BSS");
 
-       if (siz != SIZB && (sloc & 1))                            // Automatic .even 
+       if ((siz != SIZB) && (sloc & 1))        // Automatic .even
                auto_even();
 
        if (abs_expr(&eval) != OK)
                auto_even();
 
        if (abs_expr(&eval) != OK)
@@ -865,7 +866,7 @@ int d_ds(WORD siz)
                listvalue(eval);
                eval *= siz;
                sloc += eval;
                listvalue(eval);
                eval *= siz;
                sloc += eval;
-               just_bss = 1;                                         // No data deposited (8-bit CPU mode)
+               just_bss = 1;                                   // No data deposited (8-bit CPU mode)
        }
        else
        {
        }
        else
        {
@@ -878,17 +879,13 @@ int d_ds(WORD siz)
 
 
 //
 
 
 //
-// dc.b, dc.w / dc, dc.l
+// dc.b, dc.w / dc, dc.l, dc.i
 //
 int d_dc(WORD siz)
 {
        WORD eattr;
        VALUE eval;
 //
 int d_dc(WORD siz)
 {
        WORD eattr;
        VALUE eval;
-       WORD tdb;
-       WORD defined;
-       LONG i;
-       char * p;
-       int movei = 0; // movei flag for dc.i
+       uint8_t * p;
 
        if ((scattr & SBSS) != 0)
                return error("illegal initialization of section");
 
        if ((scattr & SBSS) != 0)
                return error("illegal initialization of section");
@@ -904,24 +901,26 @@ int d_dc(WORD siz)
                || (rdsp && (orgaddr >= 0xF1B000) && (orgaddr <= 0xF1CFFFF))))
                warn("depositing LONGs on a non-long address in local RAM");
 
                || (rdsp && (orgaddr >= 0xF1B000) && (orgaddr <= 0xF1CFFFF))))
                warn("depositing LONGs on a non-long address in local RAM");
 
-       for(;; ++tok)
+       for(;; tok++)
        {
                // dc.b 'string' [,] ...
                if (siz == SIZB && *tok == STRING && (tok[2] == ',' || tok[2] == EOL))
                {
        {
                // dc.b 'string' [,] ...
                if (siz == SIZB && *tok == STRING && (tok[2] == ',' || tok[2] == EOL))
                {
-                       i = strlen(string[tok[1]]);
+                       uint32_t i = strlen(string[tok[1]]);
 
 
-                       if ((challoc - ch_size) < i) 
+                       if ((challoc - ch_size) < i)
                                chcheck(i);
 
                                chcheck(i);
 
-                       for(p=string[tok[1]]; *p!=EOS; ++p)
+                       for(p=string[tok[1]]; *p!=EOS; p++)
                                D_byte(*p);
 
                        tok += 2;
                        goto comma;
                }
 
                                D_byte(*p);
 
                        tok += 2;
                        goto comma;
                }
 
-               if (*tok == 'I')
+               int movei = 0; // MOVEI flag for dc.i
+
+               if (*tok == DOTI)
                {
                        movei = 1;
                        tok++;
                {
                        movei = 1;
                        tok++;
@@ -929,11 +928,13 @@ int d_dc(WORD siz)
                }
 
                // dc.x <expression>
                }
 
                // dc.x <expression>
-               if (expr(exprbuf, &eval, &eattr, NULL) != OK)
+               SYM * esym = 0;
+
+               if (expr(exprbuf, &eval, &eattr, &esym) != OK)
                        return 0;
 
                        return 0;
 
-               tdb = (WORD)(eattr & TDB);
-               defined = (WORD)(eattr & DEFINED);
+               uint16_t tdb = eattr & TDB;
+               uint16_t defined = eattr & DEFINED;
 
                if ((challoc - ch_size) < 4)
                        chcheck(4);
 
                if ((challoc - ch_size) < 4)
                        chcheck(4);
@@ -948,15 +949,15 @@ int d_dc(WORD siz)
                        }
                        else
                        {
                        }
                        else
                        {
-                               if (tdb)
-                                       return error("non-absolute byte value");
-
                                if (eval + 0x100 >= 0x200)
                                {
                                        sprintf(buffer, "%s (value = $%X)", range_error, eval);
                                        return error(buffer);
                                }
 
                                if (eval + 0x100 >= 0x200)
                                {
                                        sprintf(buffer, "%s (value = $%X)", range_error, eval);
                                        return error(buffer);
                                }
 
+                               if (tdb)
+                                       return error("non-absolute byte value");
+
                                D_byte(eval);
                        }
 
                                D_byte(eval);
                        }
 
@@ -970,13 +971,13 @@ int d_dc(WORD siz)
                        }
                        else
                        {
                        }
                        else
                        {
-                               if (tdb)
-                                       rmark(cursect, sloc, tdb, MWORD, NULL);
-
                                if (eval + 0x10000 >= 0x20000)
                                        return error(range_error);
 
                                if (eval + 0x10000 >= 0x20000)
                                        return error(range_error);
 
-                               // Deposit 68000 or 6502 (byte-reversed) word 
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
+
+                               // Deposit 68000 or 6502 (byte-reversed) word
                                D_word(eval);
                        }
 
                                D_word(eval);
                        }
 
@@ -994,16 +995,16 @@ int d_dc(WORD siz)
                        else
                        {
                                if (tdb)
                        else
                        {
                                if (tdb)
-                                       rmark(cursect, sloc, tdb, MLONG, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
 
-                               if (movei) 
-                                       eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
+                               if (movei)
+                                       eval = WORDSWAP32(eval);
 
                                D_long(eval);
                        }
                        break;
                }
 
                                D_long(eval);
                        }
                        break;
                }
-               
+
 comma:
                if (*tok != ',')
                        break;
 comma:
                if (*tok != ',')
                        break;
@@ -1046,9 +1047,9 @@ int d_dcb(WORD siz)
 
 //
 // Generalized initialization directive
 
 //
 // Generalized initialization directive
-// 
+//
 // .init[.siz] [#count,] expression [.size] , ...
 // .init[.siz] [#count,] expression [.size] , ...
-// 
+//
 // The size suffix on the ".init" directive becomes the default size of the
 // objects to deposit. If an item is preceeded with a sharp (immediate) sign
 // and an expression, it specifies a repeat count. The value to be deposited
 // The size suffix on the ".init" directive becomes the default size of the
 // objects to deposit. If an item is preceeded with a sharp (immediate) sign
 // and an expression, it specifies a repeat count. The value to be deposited
@@ -1092,9 +1093,9 @@ int d_init(WORD def_siz)
                case DOTB: siz = SIZB; break;
                case DOTW: siz = SIZB; break;
                case DOTL: siz = SIZL; break;
                case DOTB: siz = SIZB; break;
                case DOTW: siz = SIZB; break;
                case DOTL: siz = SIZL; break;
-               default: 
+               default:
                        siz = def_siz;
                        siz = def_siz;
-                       --tok;
+                       tok--;
                        break;
                }
 
                        break;
                }
 
@@ -1105,7 +1106,7 @@ int d_init(WORD def_siz)
                case EOL:
                        return 0;
                case ',':
                case EOL:
                        return 0;
                case ',':
-                       ++tok;
+                       tok++;
                        continue;
                default:
                        return error(comma_error);
                        continue;
                default:
                        return error(comma_error);
@@ -1160,7 +1161,7 @@ int dep_block(VALUE count, WORD siz, VALUE eval, WORD eattr, TOKEN * exprbuf)
                        else
                        {
                                if (tdb)
                        else
                        {
                                if (tdb)
-                                       rmark(cursect, sloc, tdb, MWORD, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                                if (eval + 0x10000 >= 0x20000)
                                        return error(range_error);
 
                                if (eval + 0x10000 >= 0x20000)
                                        return error(range_error);
@@ -1179,7 +1180,7 @@ int dep_block(VALUE count, WORD siz, VALUE eval, WORD eattr, TOKEN * exprbuf)
                        else
                        {
                                if (tdb)
                        else
                        {
                                if (tdb)
-                                       rmark(cursect, sloc, tdb, MLONG, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
                                D_long(eval);
                        }
 
                                D_long(eval);
                        }
@@ -1263,7 +1264,7 @@ int d_68000(void)
 {
        rgpu = rdsp = 0;
        // Switching from gpu/dsp sections should reset any ORG'd Address
 {
        rgpu = rdsp = 0;
        // Switching from gpu/dsp sections should reset any ORG'd Address
-       orgactive = 0;                               
+       orgactive = 0;
        orgwarning = 0;
        SaveSection();
        SwitchSection(TEXT);
        orgwarning = 0;
        SaveSection();
        SwitchSection(TEXT);
@@ -1325,12 +1326,12 @@ int d_dsp(void)
 
 //
 // .cargs [#offset], symbol[.size], ...
 
 //
 // .cargs [#offset], symbol[.size], ...
-// 
+//
 // Lists of registers may also be mentioned; they just take up space. Good for
 // "documentation" purposes:
 // Lists of registers may also be mentioned; they just take up space. Good for
 // "documentation" purposes:
-// 
+//
 // .cargs a6, .arg1, .arg2, .arg3...
 // .cargs a6, .arg1, .arg2, .arg3...
-// 
+//
 // Symbols thus created are ABS and EQUATED.
 //
 int d_cargs(void)
 // Symbols thus created are ABS and EQUATED.
 //
 int d_cargs(void)
@@ -1438,12 +1439,12 @@ int d_cargs(void)
 
 //
 // .cstruct [#offset], symbol[.size], ...
 
 //
 // .cstruct [#offset], symbol[.size], ...
-// 
+//
 // Lists of registers may also be mentioned; they just take up space. Good for
 // "documentation" purposes:
 // Lists of registers may also be mentioned; they just take up space. Good for
 // "documentation" purposes:
-// 
+//
 // .cstruct a6, .arg1, .arg2, .arg3...
 // .cstruct a6, .arg1, .arg2, .arg3...
-// 
+//
 // Symbols thus created are ABS and EQUATED. Note that this is for
 // compatibility with VBCC and the Remover's library. Thanks to GroovyBee for
 // the suggestion.
 // Symbols thus created are ABS and EQUATED. Note that this is for
 // compatibility with VBCC and the Remover's library. Thanks to GroovyBee for
 // the suggestion.
@@ -1576,7 +1577,6 @@ int undmac1(char * p)
        SYM * symbol = lookup(p, MACRO, 0);
 
        // If the macro symbol exists, cause it to disappear
        SYM * symbol = lookup(p, MACRO, 0);
 
        // If the macro symbol exists, cause it to disappear
-//     if ((sy = lookup(p, MACRO, 0)) != NULL)
        if (symbol != NULL)
                symbol->stype = (BYTE)SY_UNDEF;
 
        if (symbol != NULL)
                symbol->stype = (BYTE)SY_UNDEF;
 
@@ -1626,7 +1626,7 @@ int d_opt(void)
                        if (ParseOptimization(tmpstr) != OK)
                        {
                                char temperr[256];
                        if (ParseOptimization(tmpstr) != OK)
                        {
                                char temperr[256];
-                               sprintf(temperr, "unknown optimisation flag '%s'", tmpstr);
+                               sprintf(temperr, "unknown optimization flag '%s'", tmpstr);
                                return error(temperr);
                        }
                }
                                return error(temperr);
                        }
                }
index 2c5ce3a71eabcf022a2dfc53f3cd09c624c6ff42..6ce7d4519c3efd8518a4520d24099e2737723f7a 100644 (file)
--- a/direct.h
+++ b/direct.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DIRECT.H - Directive Handling
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // DIRECT.H - Directive Handling
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -43,7 +43,7 @@ int ExitMacro(void);
 int d_list(void);
 int d_nlist(void);
 int d_title(void);
 int d_list(void);
 int d_nlist(void);
 int d_title(void);
-int d_subttl(void);  
+int d_subttl(void);
 int eject(void);
 int d_error(char *);
 int d_warn(char *);
 int eject(void);
 int d_error(char *);
 int d_warn(char *);
diff --git a/eagen.c b/eagen.c
index d230c1b2cb96f9f31be9f168bf8cf951fd2886f2..e94c21bba0dcb7598305420dab7296d12dd74f25 100644 (file)
--- a/eagen.c
+++ b/eagen.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EAGEN.C - Effective Address Code Generation
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EAGEN.C - Effective Address Code Generation
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -21,6 +21,7 @@
 #define aNexpr    a0expr
 #define aNixreg   a0ixreg
 #define aNixsiz   a0ixsiz
 #define aNexpr    a0expr
 #define aNixreg   a0ixreg
 #define aNixsiz   a0ixsiz
+#define AnESYM    a0esym
 #include "eagen0.c"
 
 #define eaNgen    ea1gen
 #include "eagen0.c"
 
 #define eaNgen    ea1gen
@@ -30,4 +31,5 @@
 #define aNexpr    a1expr
 #define aNixreg   a1ixreg
 #define aNixsiz   a1ixsiz
 #define aNexpr    a1expr
 #define aNixreg   a1ixreg
 #define aNixsiz   a1ixsiz
+#define AnESYM    a1esym
 #include "eagen0.c"
 #include "eagen0.c"
index 88ebdb3bee2cee83a1425694a3cfd5e8b61f2cfb..1c359b9d4d056108123165e8edfd846a3b699620 100644 (file)
--- a/eagen0.c
+++ b/eagen0.c
@@ -2,20 +2,16 @@
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EAGEN0.C - Effective Address Code Generation
 //            Generated Code for eaN (Included twice by "eagen.c")
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EAGEN0.C - Effective Address Code Generation
 //            Generated Code for eaN (Included twice by "eagen.c")
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 
 int eaNgen(WORD siz)
 {
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 
 int eaNgen(WORD siz)
 {
-       WORD w;
-       VALUE v;
-       WORD tdb;
-
-       v = aNexval;
-       w = (WORD)(aNexattr & DEFINED);
-       tdb = (WORD)(aNexattr & TDB);
+       VALUE v = aNexval;
+       WORD w = (WORD)(aNexattr & DEFINED);
+       WORD tdb = (WORD)(aNexattr & TDB);
 
        switch (amN)
        {
 
        switch (amN)
        {
@@ -35,18 +31,16 @@ int eaNgen(WORD siz)
                // expr(An)
                if (w)
                {
                // expr(An)
                if (w)
                {
-                       // Just deposit it 
+                       // Just deposit it
                        if (tdb)
                        if (tdb)
-                               rmark(cursect, sloc, tdb, MWORD, NULL);
+                               MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                        if ((v == 0) && optim_flags[OPT_INDIRECT_DISP])
                        {
 
                        if ((v == 0) && optim_flags[OPT_INDIRECT_DISP])
                        {
-                               // If expr is 0, size optimise the opcode.
-                               // Generally the lower 6 bits of the opcode
-                               // for expr(ax) are 101rrr where rrr=the
-                               // number of the register, then followed by
-                               // a word containing 'expr'. We need to change
-                               // that to 010rrr.
+                               // If expr is 0, size optimise the opcode. Generally the lower
+                               // 6 bits of the opcode for expr(ax) are 101rrr where rrr=the
+                               // number of the register, then followed by a word containing
+                               // 'expr'. We need to change that to 010rrr.
                                if ((siz & 0x8000) == 0)
                                {
                                        chptr_opcode[0] &= ((0xFFC7 >> 8) & 255); // mask off bits
                                if ((siz & 0x8000) == 0)
                                {
                                        chptr_opcode[0] &= ((0xFFC7 >> 8) & 255); // mask off bits
@@ -56,9 +50,8 @@ int eaNgen(WORD siz)
                                }
                                else
                                {
                                }
                                else
                                {
-                                       // Special case for move ea,ea:
-                                       // there are two ea fields there and
-                                       // we get a signal if it's the second ea field
+                                       // Special case for move ea,ea: there are two ea fields
+                                       // there and we get a signal if it's the second ea field
                                        // from m_ea - siz's 16th bit is set
                                        chptr_opcode[0] &= ((0xFE3F >> 8) & 255); // mask off bits
                                        chptr_opcode[1] &= 0xFE3F & 255;          // mask off bits
                                        // from m_ea - siz's 16th bit is set
                                        chptr_opcode[0] &= ((0xFE3F >> 8) & 255); // mask off bits
                                        chptr_opcode[1] &= 0xFE3F & 255;          // mask off bits
@@ -79,8 +72,8 @@ int eaNgen(WORD siz)
                }
                else
                {
                }
                else
                {
-                       // Arrange for fixup later on 
-                       AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+                       // Arrange for fixup later on
+                       AddFixup(FU_WORD | FU_SEXT, sloc, aNexpr);
                        D_word(0);
                }
 
                        D_word(0);
                }
 
@@ -88,7 +81,7 @@ int eaNgen(WORD siz)
        case PCDISP:
                if (w)
                {
        case PCDISP:
                if (w)
                {
-                       // Just deposit it 
+                       // Just deposit it
                        if ((aNexattr & TDB) == cursect)
                                v -= (VALUE)sloc;
                        else if ((aNexattr & TDB) != ABS)
                        if ((aNexattr & TDB) == cursect)
                                v -= (VALUE)sloc;
                        else if ((aNexattr & TDB) != ABS)
@@ -101,8 +94,8 @@ int eaNgen(WORD siz)
                }
                else
                {
                }
                else
                {
-                       // Arrange for fixup later on 
-                       AddFixup(FU_WORD|FU_SEXT|FU_PCREL, sloc, aNexpr);
+                       // Arrange for fixup later on
+                       AddFixup(FU_WORD | FU_SEXT | FU_PCREL, sloc, aNexpr);
                        D_word(0);
                }
 
                        D_word(0);
                }
 
@@ -113,21 +106,21 @@ int eaNgen(WORD siz)
 
                if (aNexattr & DEFINED)
                {
 
                if (aNexattr & DEFINED)
                {
-                       // Deposit a byte... 
+                       // Deposit a byte...
                        if (tdb)
                        if (tdb)
-                               // Can't mark bytes 
+                               // Can't mark bytes
                                return error(abs_error);
 
                        if (v + 0x80 >= 0x180)
                                return error(range_error);
 
                                return error(abs_error);
 
                        if (v + 0x80 >= 0x180)
                                return error(range_error);
 
-                       w |= v & 0xff;
+                       w |= v & 0xFF;
                        D_word(w);
                }
                else
                {
                        // Fixup the byte later
                        D_word(w);
                }
                else
                {
                        // Fixup the byte later
-                       AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
+                       AddFixup(FU_BYTE | FU_SEXT, sloc + 1, aNexpr);
                        D_word(w);
                }
 
                        D_word(w);
                }
 
@@ -138,8 +131,8 @@ int eaNgen(WORD siz)
 
                if (aNexattr & DEFINED)
                {
 
                if (aNexattr & DEFINED)
                {
-                       // Deposit a byte... 
-                       if ((aNexattr & TDB) == cursect) 
+                       // Deposit a byte...
+                       if ((aNexattr & TDB) == cursect)
                                v -= (VALUE)sloc;
                        else if ((aNexattr & TDB) != ABS)
                                error(rel_error);
                                v -= (VALUE)sloc;
                        else if ((aNexattr & TDB) != ABS)
                                error(rel_error);
@@ -152,8 +145,8 @@ int eaNgen(WORD siz)
                }
                else
                {
                }
                else
                {
-                       // Fixup the byte later 
-                       AddFixup(FU_WBYTE|FU_SEXT|FU_PCREL, sloc, aNexpr);
+                       // Fixup the byte later
+                       AddFixup(FU_WBYTE | FU_SEXT | FU_PCREL, sloc, aNexpr);
                        D_word(w);
                }
 
                        D_word(w);
                }
 
@@ -174,7 +167,7 @@ int eaNgen(WORD siz)
                        }
                        else
                        {
                        }
                        else
                        {
-                               AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
+                               AddFixup(FU_BYTE | FU_SEXT, sloc + 1, aNexpr);
                                D_word(0);
                        }
 
                                D_word(0);
                        }
 
@@ -183,17 +176,17 @@ int eaNgen(WORD siz)
                case SIZN:
                        if (w)
                        {
                case SIZN:
                        if (w)
                        {
-                               if (tdb)
-                                       rmark(cursect, sloc, tdb, MWORD, NULL);
-
                                if (v + 0x10000 >= 0x20000)
                                        return error(range_error);
 
                                if (v + 0x10000 >= 0x20000)
                                        return error(range_error);
 
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
+
                                D_word(v);
                        }
                        else
                        {
                                D_word(v);
                        }
                        else
                        {
-                               AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+                               AddFixup(FU_WORD | FU_SEXT, sloc, aNexpr);
                                D_word(0);
                        }
 
                                D_word(0);
                        }
 
@@ -202,7 +195,7 @@ int eaNgen(WORD siz)
                        if (w)
                        {
                                if (tdb)
                        if (w)
                        {
                                if (tdb)
-                                       rmark(cursect, sloc, tdb, MLONG, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
                                D_long(v);
                        }
 
                                D_long(v);
                        }
@@ -220,10 +213,10 @@ int eaNgen(WORD siz)
 
                break;
        case ABSW:
 
                break;
        case ABSW:
-               if (w)
+               if (w) // Defined
                {
                        if (tdb)
                {
                        if (tdb)
-                               rmark(cursect, sloc, tdb, MWORD, NULL);
+                               MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                        if (v + 0x8000 >= 0x10000)
                                return error(range_error);
 
                        if (v + 0x8000 >= 0x10000)
                                return error(range_error);
@@ -232,16 +225,16 @@ int eaNgen(WORD siz)
                }
                else
                {
                }
                else
                {
-                       AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+                       AddFixup(FU_WORD | FU_SEXT, sloc, aNexpr);
                        D_word(0);
                }
 
                break;
        case ABSL:
                        D_word(0);
                }
 
                break;
        case ABSL:
-               if (w)
+               if (w) // Defined
                {
                        if (tdb)
                {
                        if (tdb)
-                               rmark(cursect, sloc, tdb, MLONG, NULL);
+                               MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
                        D_long(v);
                }
 
                        D_long(v);
                }
@@ -260,7 +253,7 @@ int eaNgen(WORD siz)
        case PCMPRE:
                return error("unsupported 68020 addressing mode");
        default:
        case PCMPRE:
                return error("unsupported 68020 addressing mode");
        default:
-               // Bad addressing mode in ea gen 
+               // Bad addressing mode in ea gen
                interror(3);
        }
 
                interror(3);
        }
 
@@ -275,4 +268,5 @@ int eaNgen(WORD siz)
 #undef aNexpr
 #undef aNixreg
 #undef aNixsiz
 #undef aNexpr
 #undef aNixreg
 #undef aNixsiz
+#undef AnESYM
 
 
diff --git a/error.c b/error.c
index 83a6f372f73e869e6e3a9abc2ec9c12ffe0c16a9..196e4a900aa987009d5182fc63acf1dd7e6c7c89 100644 (file)
--- a/error.c
+++ b/error.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // ERROR.C - Error Handling
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // ERROR.C - Error Handling
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
diff --git a/error.h b/error.h
index 06d9e466f0ad4eafe9a43ecd50724788617393b9..693fe51ed94f871143801bafedb5d7c37821641b 100644 (file)
--- a/error.h
+++ b/error.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // ERROR.H - Error Handling
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // ERROR.H - Error Handling
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
diff --git a/expr.c b/expr.c
index 063066ede1dd58ba9265ae1bba965d5789d4593e..b7bf4b1a95b1237a244a8ae12ff619255b4cdaa1 100644 (file)
--- a/expr.c
+++ b/expr.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EXPR.C - Expression Analyzer
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EXPR.C - Expression Analyzer
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -17,7 +17,7 @@
 #include "symbol.h"
 #include "token.h"
 
 #include "symbol.h"
 #include "token.h"
 
-#define DEF_KW                                         // Declare keyword values 
+#define DEF_KW                                         // Declare keyword values
 #include "kwtab.h"                                     // Incl generated keyword tables & defs
 
 // N.B.: The size of tokenClass should be identical to the largest value of
 #include "kwtab.h"                                     // Incl generated keyword tables & defs
 
 // N.B.: The size of tokenClass should be identical to the largest value of
@@ -29,22 +29,22 @@ static WORD evattr[EVSTACKSIZE];    // Evaluator attribute stack
 // Token-class initialization list
 char itokcl[] = {
        0,                                                              // END
 // Token-class initialization list
 char itokcl[] = {
        0,                                                              // END
-       CONST, SYMBOL, 0,                               // ID 
+       CONST, SYMBOL, 0,                               // ID
        '(', '[', '{', 0,                               // OPAR
        '(', '[', '{', 0,                               // OPAR
-       ')', ']', '}', 0,                               // CPAR 
+       ')', ']', '}', 0,                               // CPAR
        CR_DEFINED, CR_REFERENCED,              // SUNARY (special unary)
        CR_STREQ, CR_MACDEF,
        CR_DEFINED, CR_REFERENCED,              // SUNARY (special unary)
        CR_STREQ, CR_MACDEF,
-       CR_DATE, CR_TIME, 
+       CR_DATE, CR_TIME,
        CR_ABSCOUNT, 0,
        '!', '~', UNMINUS, 0,                   // UNARY
        CR_ABSCOUNT, 0,
        '!', '~', UNMINUS, 0,                   // UNARY
-       '*', '/', '%', 0,                               // MULT 
-       '+', '-', 0,                                    // ADD 
-       SHL, SHR, 0,                                    // SHIFT 
-       LE, GE, '<', '>', NE, '=', 0,   // REL 
-       '&', 0,                                                 // AND 
-       '^', 0,                                                 // XOR 
-       '|', 0,                                                 // OR 
-       1                                                               // (the end) 
+       '*', '/', '%', 0,                               // MULT
+       '+', '-', 0,                                    // ADD
+       SHL, SHR, 0,                                    // SHIFT
+       LE, GE, '<', '>', NE, '=', 0,   // REL
+       '&', 0,                                                 // AND
+       '^', 0,                                                 // XOR
+       '|', 0,                                                 // OR
+       1                                                               // (the end)
 };
 
 const char missym_error[] = "missing symbol";
 };
 
 const char missym_error[] = "missing symbol";
@@ -55,7 +55,7 @@ static TOKEN * evalTokenBuffer;               // Deposit tokens here (this is really a
                                                                        // pointer to exprbuf from direct.c)
                                                                        // (Can also be from others, like
                                                                        // riscasm.c)
                                                                        // pointer to exprbuf from direct.c)
                                                                        // (Can also be from others, like
                                                                        // riscasm.c)
-static symbolNum;                                      // Pointer to the entry in symbolPtr[]
+static int symbolNum;                          // Pointer to the entry in symbolPtr[]
 
 
 //
 
 
 //
@@ -88,7 +88,7 @@ void InitExpression(void)
        {
                if (*p == 0)
                        i++;
        {
                if (*p == 0)
                        i++;
-               else 
+               else
                        tokenClass[(int)(*p)] = (char)i;
        }
 
                        tokenClass[(int)(*p)] = (char)i;
        }
 
@@ -105,7 +105,7 @@ int expr0(void)
 
        if (expr1() != OK)
                return ERROR;
 
        if (expr1() != OK)
                return ERROR;
-       
+
        while (tokenClass[*tok] >= MULT)
        {
                t = *tok++;
        while (tokenClass[*tok] >= MULT)
        {
                t = *tok++;
@@ -211,7 +211,7 @@ getsym:
                        break;
                }
        }
                        break;
                }
        }
-       else 
+       else
                return expr2();
 
        return OK;
                return expr2();
 
        return OK;
@@ -244,7 +244,7 @@ int expr2(void)
                // Check register bank usage
                if (sy->sattre & EQUATEDREG)
                {
                // Check register bank usage
                if (sy->sattre & EQUATEDREG)
                {
-                       if ((regbank == BANK_0) && (sy->sattre & BANK_1) && !altbankok)   
+                       if ((regbank == BANK_0) && (sy->sattre & BANK_1) && !altbankok)
                                warns("equated symbol \'%s\' cannot be used in register bank 0", sy->sname);
 
                        if ((regbank == BANK_1) && (sy->sattre & BANK_0) && !altbankok)
                                warns("equated symbol \'%s\' cannot be used in register bank 0", sy->sname);
 
                        if ((regbank == BANK_1) && (sy->sattre & BANK_0) && !altbankok)
@@ -395,7 +395,7 @@ if (symbol)
                        // Check register bank usage
                        if (symbol->sattre & EQUATEDREG)
                        {
                        // Check register bank usage
                        if (symbol->sattre & EQUATEDREG)
                        {
-                               if ((regbank == BANK_0) && (symbol->sattre & BANK_1) && !altbankok)   
+                               if ((regbank == BANK_0) && (symbol->sattre & BANK_1) && !altbankok)
                                        warns("equated symbol '%s' cannot be used in register bank 0", symbol->sname);
 
                                if ((regbank == BANK_1) && (symbol->sattre & BANK_0) && !altbankok)
                                        warns("equated symbol '%s' cannot be used in register bank 0", symbol->sname);
 
                                if ((regbank == BANK_1) && (symbol->sattre & BANK_0) && !altbankok)
@@ -425,7 +425,7 @@ be converted from a linked list into an array).
 All that extra crap that was put into the svalue when doing the equr stuff is
 thrown away right here. What the hell is it for?
 */
 All that extra crap that was put into the svalue when doing the equr stuff is
 thrown away right here. What the hell is it for?
 */
-                       if (symbol->sattre & EQUATEDREG) 
+                       if (symbol->sattre & EQUATEDREG)
                                *a_value &= 0x1F;
 
                        *a_attr = (WORD)(symbol->sattr & ~GLOBAL);
                                *a_value &= 0x1F;
 
                        *a_attr = (WORD)(symbol->sattr & ~GLOBAL);
@@ -484,7 +484,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym)
                case SYMBOL:
 //printf("evexpr(): SYMBOL\n");
                        sy = symbolPtr[*tk++];
                case SYMBOL:
 //printf("evexpr(): SYMBOL\n");
                        sy = symbolPtr[*tk++];
-                       sy->sattr |= REFERENCED;                // Set "referenced" bit 
+                       sy->sattr |= REFERENCED;                // Set "referenced" bit
 
                        if (!(sy->sattr & DEFINED))
                        {
 
                        if (!(sy->sattr & DEFINED))
                        {
@@ -508,7 +508,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym)
                        }
                        else
                        {
                        }
                        else
                        {
-                               *++sval = 0;                            // 0 for undefined symbols 
+                               *++sval = 0;                            // 0 for undefined symbols
                        }
 
                        *++sattr = (WORD)(sy->sattr & ~GLOBAL); // Push attribs
                        }
 
                        *++sattr = (WORD)(sy->sattr & ~GLOBAL); // Push attribs
@@ -526,20 +526,20 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym)
                        break;
 
                        // Binary "+" and "-" matrix:
                        break;
 
                        // Binary "+" and "-" matrix:
-                       // 
+                       //
                        //                ABS    Sect     Other
                        //     ----------------------------
                        //   ABS     |  ABS   |  Sect  |  Other |
                        //   Sect    |  Sect  |  [1]   |  Error |
                        //   Other   |  Other |  Error |  [1]   |
                        //      ----------------------------
                        //                ABS    Sect     Other
                        //     ----------------------------
                        //   ABS     |  ABS   |  Sect  |  Other |
                        //   Sect    |  Sect  |  [1]   |  Error |
                        //   Other   |  Other |  Error |  [1]   |
                        //      ----------------------------
-                       // 
+                       //
                        //   [1] + : Error
                        //       - : ABS
                case '+':
 //printf("evexpr(): +\n");
                        --sval;                                                 // Pop value
                        //   [1] + : Error
                        //       - : ABS
                case '+':
 //printf("evexpr(): +\n");
                        --sval;                                                 // Pop value
-                       --sattr;                                                // Pop attrib 
+                       --sattr;                                                // Pop attrib
 //printf("--> N+N: %i + %i = ", *sval, sval[1]);
                        *sval += sval[1];                               // Compute value
 //printf("%i\n", *sval);
 //printf("--> N+N: %i + %i = ", *sval, sval[1]);
                        *sval += sval[1];                               // Compute value
 //printf("%i\n", *sval);
@@ -553,7 +553,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym)
                case '-':
 //printf("evexpr(): -\n");
                        --sval;                                                 // Pop value
                case '-':
 //printf("evexpr(): -\n");
                        --sval;                                                 // Pop value
-                       --sattr;                                                // Pop attrib 
+                       --sattr;                                                // Pop attrib
 //printf("--> N-N: %i - %i = ", *sval, sval[1]);
                        *sval -= sval[1];                               // Compute value
 //printf("%i\n", *sval);
 //printf("--> N-N: %i - %i = ", *sval, sval[1]);
                        *sval -= sval[1];                               // Compute value
 //printf("%i\n", *sval);
@@ -599,8 +599,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                // are in the same segment, but that's the only requirement.
                case LE:
 //printf("evexpr(): LE\n");
                // are in the same segment, but that's the only requirement.
                case LE:
 //printf("evexpr(): LE\n");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
@@ -610,8 +610,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        break;
                case GE:
 //printf("evexpr(): GE\n");
                        break;
                case GE:
 //printf("evexpr(): GE\n");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
@@ -621,8 +621,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        break;
                case '>':
 //printf("evexpr(): >\n");
                        break;
                case '>':
 //printf("evexpr(): >\n");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
@@ -632,8 +632,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        break;
                case '<':
 //printf("evexpr(): <\n");
                        break;
                case '<':
 //printf("evexpr(): <\n");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
@@ -643,8 +643,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        break;
                case NE:
 //printf("evexpr(): NE\n");
                        break;
                case NE:
 //printf("evexpr(): NE\n");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
@@ -654,8 +654,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        break;
                case '=':
 //printf("evexpr(): =\n");
                        break;
                case '=':
 //printf("evexpr(): =\n");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
 
                        if ((*sattr & TDB) != (sattr[1] & TDB))
                                error(seg_error);
@@ -675,15 +675,15 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                        switch ((int)tk[-1])
                        {
                        case '*':
                        switch ((int)tk[-1])
                        {
                        case '*':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
 //printf("--> NxN: %i x %i = ", *sval, sval[1]);
                                *sval *= sval[1];
 //printf("%i\n", *sval);
                                break;
                        case '/':
 //printf("--> NxN: %i x %i = ", *sval, sval[1]);
                                *sval *= sval[1];
 //printf("%i\n", *sval);
                                break;
                        case '/':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
 
                                if (sval[1] == 0)
                                        return error("divide by zero");
 
                                if (sval[1] == 0)
                                        return error("divide by zero");
@@ -697,8 +697,8 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
 //printf("%i\n", *sval);
                                break;
                        case '%':
 //printf("%i\n", *sval);
                                break;
                        case '%':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
 
                                if (sval[1] == 0)
                                        return error("mod (%) by zero");
 
                                if (sval[1] == 0)
                                        return error("mod (%) by zero");
@@ -706,28 +706,28 @@ printf("EVEXPR (-): sym1 = %X, sym2 = %X\n", attr, sattr[1]);
                                *sval %= sval[1];
                                break;
                        case SHL:
                                *sval %= sval[1];
                                break;
                        case SHL:
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval <<= sval[1];
                                break;
                        case SHR:
                                *sval <<= sval[1];
                                break;
                        case SHR:
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval >>= sval[1];
                                break;
                        case '&':
                                *sval >>= sval[1];
                                break;
                        case '&':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval &= sval[1];
                                break;
                        case '^':
                                *sval &= sval[1];
                                break;
                        case '^':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval ^= sval[1];
                                break;
                        case '|':
                                *sval ^= sval[1];
                                break;
                        case '|':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval |= sval[1];
                                break;
                        default:
                                *sval |= sval[1];
                                break;
                        default:
diff --git a/expr.h b/expr.h
index 96b8e2a99746e9913a36832911cda1f3b414ddaa..ebba6594656c1b3cadf3c129cde5673c43aa2951 100644 (file)
--- a/expr.h
+++ b/expr.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EXPR.H - Expression Analyzer
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // EXPR.H - Expression Analyzer
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
diff --git a/kwgen.c b/kwgen.c
index b644b106ffac2ae27e7722e25d4d9b1b3e45f15e..55bd32a849a0390d95f55d06af8755346341fefe 100644 (file)
--- a/kwgen.c
+++ b/kwgen.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // KWGEN.C - Keyword & Mnemonic Definition and State Machine Creation Tool
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // KWGEN.C - Keyword & Mnemonic Definition and State Machine Creation Tool
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -421,3 +421,4 @@ void panic(char * s)
        fprintf(stderr, "Panic: %s\n", s);
        exit(1);
 }
        fprintf(stderr, "Panic: %s\n", s);
        exit(1);
 }
+
index 4fadfefb4278efba66037ec9ab65224e2a080554..3d632560ab89ccf8ce561a29b8d9fb6e10628f74 100644 (file)
--- a/listing.c
+++ b/listing.c
 #include "error.h"
 
 char * list_fname;                                     // Listing filename
 #include "error.h"
 
 char * list_fname;                                     // Listing filename
-char subttl[TITLESIZ];                         // Current subtitle
-int listing;                                           // Listing level 
+uint8_t subttl[TITLESIZ];                      // Current subtitle
+int listing;                                           // Listing level
 int pagelen = 61;                                      // Lines on a page
 int nlines;                                                    // #lines on page so far
 int pagelen = 61;                                      // Lines on a page
 int nlines;                                                    // #lines on page so far
-LONG lsloc;                                                    // `sloc' at start of line 
+LONG lsloc;                                                    // `sloc' at start of line
 
 // Private
 static int lcursect;                           // `cursect' at start of line
 
 // Private
 static int lcursect;                           // `cursect' at start of line
-static int llineno;                                    // `curlineno' at start of line 
-static int pageno;                                     // Current page number 
+static int llineno;                                    // `curlineno' at start of line
+static int pageno;                                     // Current page number
 static int pagewidth;                          // #columns on a page
 static int subflag;                                    // 0, don't do .eject on subttl (set 1)
 static char lnimage[IMAGESIZ];         // Image of output line
 static char title[TITLESIZ];           // Current title
 static int pagewidth;                          // #columns on a page
 static int subflag;                                    // 0, don't do .eject on subttl (set 1)
 static char lnimage[IMAGESIZ];         // Image of output line
 static char title[TITLESIZ];           // Current title
-static char datestr[20];                       // Current date dd-mon-yyyy 
+static char datestr[20];                       // Current date dd-mon-yyyy
 static char timestr[20];                       // Current time hh:mm:ss [am|pm]
 static char buf[IMAGESIZ];                     // Buffer for numbers
 static long unused;                                    // For supressing 'write' warnings
 static char timestr[20];                       // Current time hh:mm:ss [am|pm]
 static char buf[IMAGESIZ];                     // Buffer for numbers
 static long unused;                                    // For supressing 'write' warnings
@@ -80,7 +80,7 @@ VALUE dos_date(void)
 }
 
 
 }
 
 
-// 
+//
 // Return GEMDOS format time
 //
 VALUE dos_time(void)
 // Return GEMDOS format time
 //
 VALUE dos_time(void)
@@ -160,7 +160,7 @@ void lnfill(char * dest, int len, char chr)
 }
 
 
 }
 
 
-// 
+//
 // Create listing file with the appropriate name
 //
 void list_setup(void)
 // Create listing file with the appropriate name
 //
 void list_setup(void)
@@ -176,7 +176,7 @@ void list_setup(void)
        }
 
        list_fname = NULL;
        }
 
        list_fname = NULL;
-       
+
        if ((list_fd = open(fnbuf, _OPEN_FLAGS, _PERM_MODE)) < 0)
                cantcreat(fnbuf);
 }
        if ((list_fd = open(fnbuf, _OPEN_FLAGS, _PERM_MODE)) < 0)
                cantcreat(fnbuf);
 }
@@ -348,13 +348,13 @@ nochunk:
                                strcpy(buf, "xx");
                                p++;            // Advance anyway
                        }
                                strcpy(buf, "xx");
                                p++;            // Advance anyway
                        }
-                       else 
+                       else
                                sprintf(buf, "%02x", *p++ & 0xff);
 
                        strncpy(lnimage + col, buf, 2);
                }
 
                                sprintf(buf, "%02x", *p++ & 0xff);
 
                        strncpy(lnimage + col, buf, 2);
                }
 
-               // Flush partial line 
+               // Flush partial line
                if (col > DATA_COL)
                {
                        uc_ln(lnimage);
                if (col > DATA_COL)
                {
                        uc_ln(lnimage);
@@ -441,7 +441,7 @@ int d_subttl(void)
 
        tok += 2;
 
 
        tok += 2;
 
-       // Always eject on pages 2+ 
+       // Always eject on pages 2+
        if (ejectok && (subflag || pageno > 1))
                eject();
 
        if (ejectok && (subflag || pageno > 1))
                eject();
 
@@ -459,7 +459,7 @@ int d_title(void)
 {
        if (*tok != STRING)
                return error("missing string");
 {
        if (*tok != STRING)
                return error("missing string");
-       
+
 //     strcpy(title, (char*)tok[1]);
        strcpy(title, string[tok[1]]);
        tok += 2;
 //     strcpy(title, (char*)tok[1]);
        strcpy(title, string[tok[1]]);
        tok += 2;
index 457ff1fd7b96d6379933e04c1b2eb72553db4eea..e447f35a41059aed1b1ea6ad789e82e73ac6559d 100644 (file)
--- a/listing.h
+++ b/listing.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // LISTING.H - Listing Output
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // LISTING.H - Listing Output
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -31,6 +31,7 @@ extern LONG lsloc;
 
 // Prototypes
 void InitListing(void);
 
 // Prototypes
 void InitListing(void);
+int eject(void);
 void ship_ln(const char *);
 void taglist(char);
 void println(const char *);
 void ship_ln(const char *);
 void taglist(char);
 void println(const char *);
diff --git a/mach.c b/mach.c
index 7c91979c0a351f97fcc2b46835465fc1fc1abcff..69be7ea471873d11f8735b52dc75f09f7b52e192 100644 (file)
--- a/mach.c
+++ b/mach.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACH.C - Code Generation
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACH.C - Code Generation
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -19,7 +19,7 @@
 #include "kwtab.h"
 
 
 #include "kwtab.h"
 
 
-// Fucntion prototypes 
+// Fucntion prototypes
 int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
 int m_self(WORD, WORD);
 int m_abcd(WORD, WORD);
 int m_unimp(WORD, WORD), m_badmode(WORD, WORD), m_bad6mode(WORD, WORD), m_bad6inst(WORD, WORD);
 int m_self(WORD, WORD);
 int m_abcd(WORD, WORD);
@@ -59,8 +59,8 @@ extern int ea1gen(WORD);
 
 // Include code tables
 MNTAB machtab[] = {
 
 // Include code tables
 MNTAB machtab[] = {
-//   { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0 
-   { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0 
+//   { (WORD)-1, (unsigned long)-1L, (unsigned long)-1L, 0x0000, 0, m_badmode }, // 0
+   { 0xFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000, 0, m_badmode }, // 0
    #include "68ktab.h"
    {  0,  0L,  0L, 0x0000, 0, m_unimp   }            // Last entry
 };
    #include "68ktab.h"
    {  0,  0L,  0L, 0x0000, 0, m_unimp   }            // Last entry
 };
@@ -72,18 +72,18 @@ WORD reg_9[8] = {
 
 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
 WORD siz_6[] = {
 
 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
 WORD siz_6[] = {
-       (WORD)-1,                                        // n/a 
+       (WORD)-1,                                        // n/a
        0,                                               // SIZB
        0,                                               // SIZB
-       1<<6, (WORD)-1,                                  // SIZW, n/a 
-       2<<6, (WORD)-1, (WORD)-1, (WORD)-1,              // SIZL, n/a, n/a, n/a 
-       1<<6                                             // SIZN 
+       1<<6, (WORD)-1,                                  // SIZW, n/a
+       2<<6, (WORD)-1, (WORD)-1, (WORD)-1,              // SIZL, n/a, n/a, n/a
+       1<<6                                             // SIZN
 };
 
 // Byte/word/long size for MOVE instrs
 WORD siz_12[] = {
    (WORD)-1,
 };
 
 // Byte/word/long size for MOVE instrs
 WORD siz_12[] = {
    (WORD)-1,
-   0x1000,                                           // Byte 
-   0x3000, (WORD)-1,                                 // Word 
+   0x1000,                                           // Byte
+   0x3000, (WORD)-1,                                 // Word
    0x2000, (WORD)-1, (WORD)-1, (WORD)-1,             // Long
    0x3000                                            // Word (SIZN)
 };
    0x2000, (WORD)-1, (WORD)-1, (WORD)-1,             // Long
    0x3000                                            // Word (SIZN)
 };
@@ -133,59 +133,59 @@ int m_self(WORD inst, WORD usused)
 
 //
 // Do one EA in bits 0..5
 
 //
 // Do one EA in bits 0..5
-// 
+//
 // Bits in `inst' have the following meaning:
 // Bits in `inst' have the following meaning:
-// 
+//
 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
 // of the instr.
 // Bit zero specifies which ea (ea0 or ea1) to generate in the lower six bits
 // of the instr.
-// 
+//
 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
 // is generated after the instruction. Regardless of bit 0's value, ea0 is
 // always deposited in memory before ea1.
 // If bit one is set, the OTHER ea (the one that wasn't generated by bit zero)
 // is generated after the instruction. Regardless of bit 0's value, ea0 is
 // always deposited in memory before ea1.
-// 
+//
 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
 // If bit two is set, standard size bits are set in the instr in bits 6 and 7.
-// 
+//
 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
 // of the instr.
 //
 int m_ea(WORD inst, WORD siz)
 {
 // If bit four is set, bit three specifies which eaXreg to place in bits 9..11
 // of the instr.
 //
 int m_ea(WORD inst, WORD siz)
 {
-       WORD flg = inst;                                        // Save flag bits 
-       inst &= ~0x3F;                                          // Clobber flag bits in instr 
+       WORD flg = inst;                                        // Save flag bits
+       inst &= ~0x3F;                                          // Clobber flag bits in instr
 
 
-       // Install "standard" instr size bits 
+       // Install "standard" instr size bits
        if (flg & 4)
                inst |= siz_6[siz];
 
        if (flg & 16)
        {
        if (flg & 4)
                inst |= siz_6[siz];
 
        if (flg & 16)
        {
-               // OR-in register number 
+               // OR-in register number
                if (flg & 8)
                if (flg & 8)
-                       inst |= reg_9[a1reg];           // ea1reg in bits 9..11 
+                       inst |= reg_9[a1reg];           // ea1reg in bits 9..11
                else
                else
-                       inst |= reg_9[a0reg];           // ea0reg in bits 9..11 
+                       inst |= reg_9[a0reg];           // ea0reg in bits 9..11
        }
 
        if (flg & 1)
        {
        }
 
        if (flg & 1)
        {
-               // Use am1 
-               inst |= am1 | a1reg;                    // Get ea1 into instr 
-               D_word(inst);                                   // Deposit instr 
+               // Use am1
+               inst |= am1 | a1reg;                    // Get ea1 into instr
+               D_word(inst);                                   // Deposit instr
 
 
-               // Generate ea0 if requested 
+               // Generate ea0 if requested
                if (flg & 2)
                        ea0gen(siz);
 
                if (flg & 2)
                        ea0gen(siz);
 
-               ea1gen(siz);                                    // Generate ea1 
+               ea1gen(siz);                                    // Generate ea1
        }
        else
        {
        }
        else
        {
-               // Use am0 
-               inst |= am0 | a0reg;                    // Get ea0 into instr 
-               D_word(inst);                                   // Deposit instr 
-               ea0gen(siz);                                    // Generate ea0 
+               // Use am0
+               inst |= am0 | a0reg;                    // Get ea0 into instr
+               D_word(inst);                                   // Deposit instr
+               ea0gen(siz);                                    // Generate ea0
 
 
-               // Generate ea1 if requested 
+               // Generate ea1 if requested
                if (flg & 2)
                        ea1gen(siz);
        }
                if (flg & 2)
                        ea1gen(siz);
        }
@@ -202,7 +202,7 @@ int m_abcd(WORD inst, WORD siz)
 {
        if (inst & 1)
        {
 {
        if (inst & 1)
        {
-               // Install size bits 
+               // Install size bits
                inst--;
                inst |= siz_6[siz];
        }
                inst--;
                inst |= siz_6[siz];
        }
@@ -221,7 +221,7 @@ int m_adda(WORD inst, WORD siz)
 {
        inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
        D_word(inst);
 {
        inst |= am0 | a0reg | lwsiz_8[siz] | reg_9[a1reg];
        D_word(inst);
-       ea0gen(siz);    // Generate EA 
+       ea0gen(siz);    // Generate EA
 
        return 0;
 }
 
        return 0;
 }
@@ -230,19 +230,19 @@ int m_adda(WORD inst, WORD siz)
 //
 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
 //
 // If bit 0 of `inst' is 1, install size bits in bits 6..7 of instr.
 // If bit 1 of `inst' is 1, install a1reg in bits 9..11 of instr.
-// 
+//
 int m_reg(WORD inst, WORD siz)
 {
        if (inst & 1)
 int m_reg(WORD inst, WORD siz)
 {
        if (inst & 1)
-               // Install size bits 
+               // Install size bits
                inst |= siz_6[siz];
 
        if (inst & 2)
                inst |= siz_6[siz];
 
        if (inst & 2)
-               // Install other register (9..11) 
+               // Install other register (9..11)
                inst |= reg_9[a1reg];
 
                inst |= reg_9[a1reg];
 
-       inst &= ~7;                     // Clear off crufty bits 
-       inst |= a0reg;          // Install first register 
+       inst &= ~7;                     // Clear off crufty bits
+       inst |= a0reg;          // Install first register
        D_word(inst);
 
        return 0;
        D_word(inst);
 
        return 0;
@@ -318,11 +318,11 @@ int m_bitop(WORD inst, WORD siz)
 {
        // Enforce instruction sizes
        if (am1 == DREG)
 {
        // Enforce instruction sizes
        if (am1 == DREG)
-       {                               // X,Dn must be .n or .l 
+       {                               // X,Dn must be .n or .l
                if (siz & (SIZB | SIZW))
                        return error(siz_error);
        }
                if (siz & (SIZB | SIZW))
                        return error(siz_error);
        }
-       else if (siz & (SIZW | SIZL))   // X,ea must be .n or .b 
+       else if (siz & (SIZW | SIZL))   // X,ea must be .n or .b
                return error(siz_error);
 
        // Construct instr and EAs
                return error(siz_error);
 
        // Construct instr and EAs
@@ -331,7 +331,7 @@ int m_bitop(WORD inst, WORD siz)
        if (am0 == IMMED)
        {
                D_word(inst);
        if (am0 == IMMED)
        {
                D_word(inst);
-               ea0gen(SIZB);                           // Immediate bit number 
+               ea0gen(SIZB);                           // Immediate bit number
        }
        else
        {
        }
        else
        {
@@ -339,7 +339,7 @@ int m_bitop(WORD inst, WORD siz)
                D_word(inst);
        }
 
                D_word(inst);
        }
 
-       // ea to bit-munch 
+       // ea to bit-munch
        ea1gen(SIZB);
 
        return 0;
        ea1gen(SIZB);
 
        return 0;
@@ -386,14 +386,14 @@ int m_exg(WORD inst, WORD siz)
        siz = siz;
 
        if (am0 == DREG && am1 == DREG)
        siz = siz;
 
        if (am0 == DREG && am1 == DREG)
-               m = 0x0040;                                           // Dn,Dn 
+               m = 0x0040;                                           // Dn,Dn
        else if (am0 == AREG && am1 == AREG)
        else if (am0 == AREG && am1 == AREG)
-               m = 0x0048;                                           // An,An 
+               m = 0x0048;                                           // An,An
        else
        {
                if (am0 == AREG)
        else
        {
                if (am0 == AREG)
-               {                                     // Dn,An or An,Dn 
-                       m = a1reg;                                         // Get AREG into a1reg 
+               {                                     // Dn,An or An,Dn
+                       m = a1reg;                                         // Get AREG into a1reg
                        a1reg = a0reg;
                        a0reg = m;
                }
                        a1reg = a0reg;
                        a0reg = m;
                }
@@ -425,7 +425,7 @@ int m_link(WORD inst, WORD siz)
 //
 // Handle MOVE <C_ALL> <C_ALTDATA>
 //        MOVE <C_ALL> <M_AREG>
 //
 // Handle MOVE <C_ALL> <C_ALTDATA>
 //        MOVE <C_ALL> <M_AREG>
-// 
+//
 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
 //
 int m_move(WORD inst, WORD size)
 // Optimize MOVE.L #<smalldata>,D0 to a MOVEQ
 //
 int m_move(WORD inst, WORD size)
@@ -467,9 +467,9 @@ int m_usp(WORD inst, WORD siz)
        siz = siz;
 
        if (am0 == AM_USP)
        siz = siz;
 
        if (am0 == AM_USP)
-               inst |= a1reg;          // USP, An 
+               inst |= a1reg;          // USP, An
        else
        else
-               inst |= a0reg;          // An, USP 
+               inst |= a0reg;          // An, USP
 
        D_word(inst);
 
 
        D_word(inst);
 
@@ -484,11 +484,11 @@ int m_moveq(WORD inst, WORD siz)
 {
        siz = siz;
 
 {
        siz = siz;
 
-       // Arrange for future fixup 
+       // Arrange for future fixup
        if (!(a0exattr & DEFINED))
        {
                AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
        if (!(a0exattr & DEFINED))
        {
                AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
-               a0exval = 0; 
+               a0exval = 0;
        }
        else if (a0exval + 0x100 >= 0x200)
                return error(range_error);
        }
        else if (a0exval + 0x100 >= 0x200)
                return error(range_error);
@@ -515,7 +515,7 @@ int m_movep(WORD inst, WORD siz)
 
                if (am1 == AIND)
                        D_word(0)
 
                if (am1 == AIND)
                        D_word(0)
-               else 
+               else
                        ea1gen(siz);
        }
        else
                        ea1gen(siz);
        }
        else
@@ -525,7 +525,7 @@ int m_movep(WORD inst, WORD siz)
 
                if (am0 == AIND)
                        D_word(0)
 
                if (am0 == AIND)
                        D_word(0)
-               else 
+               else
                        ea0gen(siz);
        }
 
                        ea0gen(siz);
        }
 
@@ -555,7 +555,7 @@ int m_br(WORD inst, WORD siz)
                {
                        if (optim_flags[OPT_BSR_BCC_S] && v != 0 && v + 0x80 < 0x100)
                        {
                {
                        if (optim_flags[OPT_BSR_BCC_S] && v != 0 && v + 0x80 < 0x100)
                        {
-                               // Fits in .B 
+                               // Fits in .B
                                inst |= v & 0xFF;
                                D_word(inst);
                                if (sbra_flag)
                                inst |= v & 0xFF;
                                D_word(inst);
                                if (sbra_flag)
@@ -564,7 +564,7 @@ int m_br(WORD inst, WORD siz)
                        }
                        else
                        {
                        }
                        else
                        {
-                               // Fits in .W 
+                               // Fits in .W
                                if (v + 0x8000 > 0x10000)
                                        return error(range_error);
 
                                if (v + 0x8000 > 0x10000)
                                        return error(range_error);
 
@@ -598,14 +598,14 @@ int m_br(WORD inst, WORD siz)
 
        if (siz == SIZB)
        {
 
        if (siz == SIZB)
        {
-               // .B 
+               // .B
                AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
                D_word(inst);
                return 0;
        }
        else
        {
                AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
                D_word(inst);
                return 0;
        }
        else
        {
-               // .W 
+               // .W
                D_word(inst);
                AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
                D_word(0);
                D_word(inst);
                AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
                D_word(0);
@@ -624,7 +624,7 @@ int m_addq(WORD inst, WORD siz)
 
        if (a0exattr & DEFINED)
        {
 
        if (a0exattr & DEFINED)
        {
-               if (a0exval > 8 ||      a0exval == 0)                       // Range in 1..8 
+               if (a0exval > 8 ||      a0exval == 0)                       // Range in 1..8
                        return error(range_error);
 
                inst |= (a0exval & 7) << 9;
                        return error(range_error);
 
                inst |= (a0exval & 7) << 9;
@@ -660,7 +660,7 @@ int m_trap(WORD inst, WORD siz)
                inst |= a0exval;
                D_word(inst);
        }
                inst |= a0exval;
                D_word(inst);
        }
-       else 
+       else
                return error(undef_error);
 
        return 0;
                return error(undef_error);
 
        return 0;
@@ -685,7 +685,7 @@ int m_movem(WORD inst, WORD siz)
 
        if (*tok == '#')
        {
 
        if (*tok == '#')
        {
-               // Handle #<expr>, ea 
+               // Handle #<expr>, ea
                tok++;
 
                if (abs_expr(&eval) != OK)
                tok++;
 
                if (abs_expr(&eval) != OK)
@@ -700,7 +700,7 @@ int m_movem(WORD inst, WORD siz)
 
        if (*tok >= KW_D0 && *tok <= KW_A7)
        {
 
        if (*tok >= KW_D0 && *tok <= KW_A7)
        {
-               // <rlist>, ea 
+               // <rlist>, ea
                if (reglist(&rmask) < 0)
                        return 0;
 
                if (reglist(&rmask) < 0)
                        return 0;
 
@@ -728,7 +728,7 @@ immed1:
        }
        else
        {
        }
        else
        {
-               // ea, <rlist> 
+               // ea, <rlist>
                if (amode(0) < 0)
                        return 0;
 
                if (amode(0) < 0)
                        return 0;
 
@@ -742,7 +742,7 @@ immed1:
 
                if (*tok == '#')
                {
 
                if (*tok == '#')
                {
-                       // ea, #<expr> 
+                       // ea, #<expr>
                        tok++;
 
                        if (abs_expr(&eval) != OK)
                        tok++;
 
                        if (abs_expr(&eval) != OK)
diff --git a/mach.h b/mach.h
index f10ff310f54e4da05d69e7dae867b5bc1266b301..46b5db3cd6a3c6f68ca4f9d1aee0162a8cb2b2c6 100644 (file)
--- a/mach.h
+++ b/mach.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACH.H - Code Generation
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACH.H - Code Generation
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -12,7 +12,7 @@
 #include "rmac.h"
 #include "amode.h"
 
 #include "rmac.h"
 #include "amode.h"
 
-// Globals, Externals etc
+// Exported variables
 extern char seg_error[];
 extern char undef_error[];
 extern char rel_error[];
 extern char seg_error[];
 extern char undef_error[];
 extern char rel_error[];
@@ -21,3 +21,4 @@ extern char abs_error[];
 extern MNTAB machtab[];
 
 #endif // __MACH_H__
 extern MNTAB machtab[];
 
 #endif // __MACH_H__
+
diff --git a/macro.c b/macro.c
index 0807e74b033f38080fd0ceb2ad4b21bcf3c00f4a..2af59975c5a7d39e8459164c1b2a85118f3c90d5 100644 (file)
--- a/macro.c
+++ b/macro.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACRO.C - Macro Definition and Invocation
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACRO.C - Macro Definition and Invocation
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 #include "token.h"
 
 
 #include "token.h"
 
 
-LONG curuniq;                                                          // Current macro's unique number
-//TOKEN ** argp;                                                               // Free spot in argptrs[]
-int macnum;                                                                    // Unique number for macro definition
-TOKEN * argPtrs[128];                                          // 128 arguments ought to be enough for anyone
+LONG curuniq;                          // Current macro's unique number
+int macnum;                                    // Unique number for macro definition
+TOKEN * argPtrs[128];          // 128 arguments ought to be enough for anyone
 static int argp;
 
 static int argp;
 
-static LONG macuniq;                                           // Unique-per-macro number
-static SYM * curmac;                                           // Macro currently being defined
-//static char ** curmln;                                               // Previous macro line (or NULL)
-static VALUE argno;                                                    // Formal argument count 
+static LONG macuniq;           // Unique-per-macro number
+static SYM * curmac;           // Macro currently being defined
+static VALUE argno;                    // Formal argument count
 
 
-static LONG * firstrpt;                                                // First .rept line 
-static LONG * nextrpt;                                         // Last .rept line 
-static int rptlevel;                                           // .rept nesting level 
+static LONG * firstrpt;                // First .rept line
+static LONG * nextrpt;         // Last .rept line
+static int rptlevel;           // .rept nesting level
 
 
 //
 
 
 //
@@ -150,7 +148,7 @@ features of the language. Seems like we can do better here.
                        *curmln = p.cp;
 
                curmln = (char **)p.cp;
                        *curmln = p.cp;
 
                curmln = (char **)p.cp;
-               return 1;                                                       // Keep looking 
+               return 1;                                                       // Keep looking
 #else
                if (curmac->lineList == NULL)
                {
 #else
                if (curmac->lineList == NULL)
                {
@@ -239,11 +237,11 @@ int defr1(char * ln, int kwno)
 
        switch (kwno)
        {
 
        switch (kwno)
        {
-       case 0:                                                                         // .endr 
+       case 0:                                                                         // .endr
                if (--rptlevel == 0)
                return(0);
                goto addln;
                if (--rptlevel == 0)
                return(0);
                goto addln;
-       case 1:                                                                         // .rept 
+       case 1:                                                                         // .rept
                rptlevel++;
        default:
 //MORE stupidity here...
                rptlevel++;
        default:
 //MORE stupidity here...
@@ -256,7 +254,7 @@ WARNING(!!! Casting (char *) as LONG !!!)
                *p = 0;
 
                strcpy((char *)(p + 1), ln);
                *p = 0;
 
                strcpy((char *)(p + 1), ln);
-               
+
                if (nextrpt == NULL)
                {
                        firstrpt = p;           // First line of rept statement
                if (nextrpt == NULL)
                {
                        firstrpt = p;           // First line of rept statement
@@ -310,14 +308,14 @@ int defrept(void)
 // Hand off lines of text to the function `lnfunc' until a line containing one
 // of the directives in `dirlist' is encountered. Return the number of the
 // keyword encountered (0..n)
 // Hand off lines of text to the function `lnfunc' until a line containing one
 // of the directives in `dirlist' is encountered. Return the number of the
 // keyword encountered (0..n)
-// 
+//
 // `dirlist' contains null-seperated terminated keywords.  A final null
 // terminates the list. Directives are compared to the keywords without regard
 // to case.
 // `dirlist' contains null-seperated terminated keywords.  A final null
 // terminates the list. Directives are compared to the keywords without regard
 // to case.
-// 
+//
 // If `lnfunc' is NULL, then lines are simply skipped.
 // If `lnfunc' returns an error, processing is stopped.
 // If `lnfunc' is NULL, then lines are simply skipped.
 // If `lnfunc' returns an error, processing is stopped.
-// 
+//
 // `lnfunc' is called with an argument of -1 for every line but the last one,
 // when it is called with an argument of the keyword number that caused the
 // match.
 // `lnfunc' is called with an argument of -1 for every line but the last one,
 // when it is called with an argument of the keyword number that caused the
 // match.
@@ -328,7 +326,7 @@ int lncatch(int (* lnfunc)(), char * dirlist)
        int k;
 
        if (lnfunc != NULL)
        int k;
 
        if (lnfunc != NULL)
-               lnsave++;                                                               // Tell tokenizer to keep lines 
+               lnsave++;                                                               // Tell tokenizer to keep lines
 
        for(;;)
        {
 
        for(;;)
        {
@@ -359,7 +357,7 @@ int lncatch(int (* lnfunc)(), char * dirlist)
 
                if (p != NULL)
                {
 
                if (p != NULL)
                {
-                       if (*p == '.')                                          // ignore leading '.'s 
+                       if (*p == '.')                                          // ignore leading '.'s
                                p++;
 
                        k = kwmatch(p, dirlist);
                                p++;
 
                        k = kwmatch(p, dirlist);
@@ -438,7 +436,7 @@ int InvokeMacro(SYM * mac, WORD siz)
 //     argp = 0;
        DEBUG printf("InvokeMacro: argp: %d -> ", argp);
 
 //     argp = 0;
        DEBUG printf("InvokeMacro: argp: %d -> ", argp);
 
-       INOBJ * inobj = a_inobj(SRC_IMACRO);            // Alloc and init IMACRO 
+       INOBJ * inobj = a_inobj(SRC_IMACRO);            // Alloc and init IMACRO
        IMACRO * imacro = inobj->inobj.imacro;
        imacro->im_siz = siz;
        WORD nargs = 0;
        IMACRO * imacro = inobj->inobj.imacro;
        imacro->im_siz = siz;
        WORD nargs = 0;
@@ -447,7 +445,6 @@ int InvokeMacro(SYM * mac, WORD siz)
        TOKEN * dest;
        int stringNum = 0;
        int argumentNum = 0;
        TOKEN * dest;
        int stringNum = 0;
        int argumentNum = 0;
-//     int i;
 
        for(dry_run=1; ; dry_run--)
        {
 
        for(dry_run=1; ; dry_run--)
        {
@@ -457,7 +454,7 @@ int InvokeMacro(SYM * mac, WORD siz)
                                nargs++;
                        else
                        {
                                nargs++;
                        else
                        {
-#if 0                          
+#if 0
                                *argptr++ = p;
 #else
                                argPtrs[argp++] = p;
                                *argptr++ = p;
 #else
                                argPtrs[argp++] = p;
@@ -569,7 +566,7 @@ streams, we can alleviate this problem.]
 //                     argp += nargs;
 #endif
                }
 //                     argp += nargs;
 #endif
                }
-               else 
+               else
                        break;
        }
 
                        break;
        }
 
diff --git a/macro.h b/macro.h
index bca6d2f578008e11f7ed13cc88abb03db5298e9b..3884ac7aae4583f011a6450e2e9c91da71b0a641 100644 (file)
--- a/macro.h
+++ b/macro.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACRO.H - Macro Definition and Invocation
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MACRO.H - Macro Definition and Invocation
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
index cd52ffe9bc983b00ec0018d1be59cb0a7567b3ae..8eef37062297f6be65a12b0155d7e0ade3b5e80e 100644 (file)
--- a/makefile
+++ b/makefile
@@ -8,7 +8,7 @@ rm = /bin/rm -f
 CC = $(CROSS)gcc
 HOSTCC = gcc
 
 CC = $(CROSS)gcc
 HOSTCC = gcc
 
-CFLAGS = -std=c99 -g -D__GCCUNIX__ -I. -O2
+CFLAGS = -std=c99 -D_DEFAULT_SOURCE -g -D__GCCUNIX__ -I. -O2
 
 SRCS = amode.c debug.c direct.c eagen.c error.c expr.c listing.c mach.c macro.c mark.c object.c procln.c riscasm.c rmac.c sect.c symbol.c token.c 
 
 
 SRCS = amode.c debug.c direct.c eagen.c error.c expr.c listing.c mach.c macro.c mark.c object.c procln.c riscasm.c rmac.c sect.c symbol.c token.c 
 
diff --git a/mark.c b/mark.c
index 81a4d87293bf6b596171641f43e47bae5fc66fc1..6c40c304292586e6b0c2f620aef5c071a9597f77 100644 (file)
--- a/mark.c
+++ b/mark.c
 #include "error.h"
 #include "object.h"
 #include "riscasm.h"
 #include "error.h"
 #include "object.h"
 #include "riscasm.h"
+#include "sect.h"
 
 
 
 
+#define MARK_ALLOC_INCR 1024           // # bytes to alloc for more mark space
+#define MIN_MARK_MEM    (3 * sizeof(uint16_t) + 1 * sizeof(uint32_t) + sizeof(SYM *))
+
 MCHUNK * firstmch;             // First mark chunk
 MCHUNK * curmch;               // Current mark chunk
 PTR markptr;                   // Deposit point in current mark chunk
 MCHUNK * firstmch;             // First mark chunk
 MCHUNK * curmch;               // Current mark chunk
 PTR markptr;                   // Deposit point in current mark chunk
-LONG mcalloc;                  // #bytes alloc'd to current mark chunk
-LONG mcused;                   // #bytes used in current mark chunk
+uint32_t mcalloc;              // # bytes alloc'd to current mark chunk
+uint32_t mcused;               // # bytes used in current mark chunk
 uint16_t curfrom;              // Current "from" section
 uint16_t curfrom;              // Current "from" section
-LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag);
 
 
-//
-//  Imports
-//
-extern int prg_flag;   // 1, write ".PRG" relocatable executable
+// Table to convert from TDB to fixup triad
+static uint8_t mark_tr[] = {
+       0,              // (N/A)
+       2,              // TEXT relocatable
+       1, 0,   // DATA relocatable
+       3               // BSS relocatable
+};
 
 //#define DEBUG_IMAGE_MARKING
 
 
 //#define DEBUG_IMAGE_MARKING
 
@@ -36,6 +42,7 @@ void InitMark(void)
        firstmch = curmch = NULL;
        mcalloc = mcused = 0;
        curfrom = 0;
        firstmch = curmch = NULL;
        mcalloc = mcused = 0;
        curfrom = 0;
+       sect[TEXT].relocs = sect[DATA].relocs = sect[BSS].relocs = 0;
 }
 
 
 }
 
 
@@ -47,37 +54,44 @@ void StopMark(void)
        if (curmch)
        {
                *markptr.wp = MCHEND;           // Mark end of block
        if (curmch)
        {
                *markptr.wp = MCHEND;           // Mark end of block
-               curmch->mcused = mcused;        // Update #used in mark block
+               curmch->mcused = mcused;        // Update # used in mark block
        }
 }
 
 
 //
        }
 }
 
 
 //
-// Mark a word or longword relocatable
+// Mark a word or longword as relocatable
+//
+// Record is either 2, 3, or 4 pieces of data long. A mark is of the form:
+// .W    <to+flags>    section mark is relative to, and flags in upper byte
+// .L    <loc>         location of mark in "from" section
+// .W    [from]                new from section (if different from current)
+// .L    [symbol]      symbol involved in external reference (if any)
 //
 //
-int rmark(uint16_t from, uint32_t loc, uint16_t to, uint16_t size, SYM * symbol)
+uint32_t MarkRelocatable(uint16_t section, uint32_t loc, uint16_t to, uint16_t flags, SYM * symbol)
 {
 #ifdef DEBUG_IMAGE_MARKING
 {
 #ifdef DEBUG_IMAGE_MARKING
-printf("rmark: from=%i, loc=$%X, to=$%X, size=$%x, symbol=$%X\n", from, loc, to, size, symbol);
+printf("MarkRelocatable: section=%i, loc=$%X, to=$%X, flags=$%x, symbol=$%X\n", section, loc, to, flags, symbol);
 if (symbol)
        printf("      symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
 #endif
 
        if ((mcalloc - mcused) < MIN_MARK_MEM)
 if (symbol)
        printf("      symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
 #endif
 
        if ((mcalloc - mcused) < MIN_MARK_MEM)
-               amark();
+               AllocateMark();
 
 
-       uint16_t flags = (size | to);
+       // Set up flags
+       flags |= to;
 
 
-       if (from != curfrom)
+       if (section != curfrom)
                flags |= MCHFROM;
 
        if (symbol != NULL)
                flags |= MSYMBOL;
 
        //
                flags |= MCHFROM;
 
        if (symbol != NULL)
                flags |= MSYMBOL;
 
        //
-       //  Complain about some things are not allowed in `-p' mode:
-       //    o marks that aren't to LONGs;
-       //    o external references.
+       // Complain about some things are not allowed in '-p' (PRG) mode:
+       //  o Marks that aren't to LONGs
+       //  o External references
        //
        if (prg_flag)
        {
        //
        if (prg_flag)
        {
@@ -86,18 +100,19 @@ if (symbol)
 
                if (symbol != NULL)
                        errors("illegal external reference (in .PRG mode) to '%s'",
 
                if (symbol != NULL)
                        errors("illegal external reference (in .PRG mode) to '%s'",
-                                  symbol->sname);
+                               symbol->sname);
        }
 
        }
 
-       mcused += sizeof(WORD) + sizeof(LONG);
+       // Dump crap into the mark
        *markptr.wp++ = flags;
        *markptr.lp++ = loc;
        *markptr.wp++ = flags;
        *markptr.lp++ = loc;
+       mcused += sizeof(uint16_t) + sizeof(uint32_t);
 
        if (flags & MCHFROM)
        {
 
        if (flags & MCHFROM)
        {
-               curfrom = from;
-               *markptr.wp++ = from;
-               mcused += sizeof(WORD);
+               curfrom = section;
+               *markptr.wp++ = section;
+               mcused += sizeof(uint16_t);
        }
 
        if (flags & MSYMBOL)
        }
 
        if (flags & MSYMBOL)
@@ -106,6 +121,11 @@ if (symbol)
                mcused += sizeof(SYM *);
        }
 
                mcused += sizeof(SYM *);
        }
 
+       // Increment # of relocs in this section
+       sect[section].relocs++;
+
+       // Not sure what this is about (making sure the next mark is clear until
+       // it's marked as the end--I think)...
        *markptr.wp = 0x0000;
 
        return 0;
        *markptr.wp = 0x0000;
 
        return 0;
@@ -115,29 +135,28 @@ if (symbol)
 //
 // Allocate another chunk of mark space
 //
 //
 // Allocate another chunk of mark space
 //
-int amark(void)
+uint32_t AllocateMark(void)
 {
 {
-//     MCHUNK * p;
-
        // Alloc mark block header (and data) and set it up.
        // Alloc mark block header (and data) and set it up.
-//     p = (MCHUNK *)amem((long)(sizeof(MCHUNK)) + MARK_ALLOC_INCR);
-       MCHUNK * p = (MCHUNK *)malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR);
+       MCHUNK * p = malloc(sizeof(MCHUNK) + MARK_ALLOC_INCR);
        p->mcnext = NULL;
        p->mcalloc = MARK_ALLOC_INCR;
        p->mcnext = NULL;
        p->mcalloc = MARK_ALLOC_INCR;
-       p->mcptr.cp = (char *)(((char *)p) + sizeof(MCHUNK));
+       p->mcptr.cp = (uint8_t *)p + sizeof(MCHUNK);
+       p->mcused = 0;
+
+       if (firstmch == NULL)
+               firstmch = p;
 
        if (curmch)
        {
 
        if (curmch)
        {
-               // Link onto previous chunk 
-               *markptr.wp++ = MCHEND;         // Mark end of block 
+               // Link onto previous chunk
+               *markptr.wp++ = MCHEND;         // Mark end of block
                curmch->mcused = mcused;
                curmch->mcnext = p;
        }
 
                curmch->mcused = mcused;
                curmch->mcnext = p;
        }
 
-       if (!firstmch)
-               firstmch = p;
-
-       curmch = p;                                             // Setup global vars 
+       // Setup global vars
+       curmch = p;
        markptr = p->mcptr;
        mcalloc = MARK_ALLOC_INCR;
        mcused = 0;
        markptr = p->mcptr;
        mcalloc = MARK_ALLOC_INCR;
        mcused = 0;
@@ -146,73 +165,48 @@ int amark(void)
 }
 
 
 }
 
 
-/*
- *  Table to convert from TDB to fixup triad
- *
- */
-static char mark_tr[] = {
-       0,                              /* (n/a) */
-       2,                              /* TEXT relocatable */
-       1, 0,                           /* DATA relocatable */
-       3                               /* BSS relocatable */
-};
-
-
-/*
- *  Make mark image for Alcyon .o file
- *  okflag     --  1, ok to deposit reloc information
- */
-LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
+//
+// Make mark image for Alcyon .o file
+// okflag: 1, ok to deposit reloc information
+//
+uint32_t MarkImage(register uint8_t * mp, uint32_t siz, uint32_t tsize, int okflag)
 {
 {
-       MCHUNK * mch;           /* -> mark chunk */
-       register PTR p;         /* source point from within mark chunk */
-       WORD from;                      /* section fixups are currently FROM */
-       register WORD w;        /* a word (temp) */
-       LONG loc;                       /* location (temp) */
-       LONG lastloc;           /* last location fixed up (RELMOD) */
-       SYM * symbol;           /* -> symbols (temp) */
-       char * wp;                      /* pointer into raw relocation information */
-       register char * dp;     /* deposit point for RELMOD information */
-       int firstp;                     /* 1, first relocation (RELMOD) */
-       LONG diff;                      /* difference to relocate (RELMOD) */
+       uint16_t from = 0;              // Section fixups are currently FROM
+       uint32_t loc;                   // Location (temp)
+       uint32_t lastloc;               // Last location fixed up (RELMOD)
+       uint8_t * wp;                   // Pointer into raw relocation information
+       register uint8_t * dp;  // Deposit point for RELMOD information
 
        if (okflag)
 
        if (okflag)
-               //clear(mp, siz);               /* zero relocation buffer */
-               memset(mp, 0, siz);             /* zero relocation buffer */
-
-       from = 0;
+               memset(mp, 0, siz);             // zero relocation buffer
 
 
-       for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
+       for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
        {
        {
-               for(p=mch->mcptr;;)
+               for(PTR p=mch->mcptr;;)
                {
                {
-                       w = *p.wp++;            /* w = next mark entry */
+                       uint16_t w = *p.wp++;// w = next mark entry
 
 
-                       if (w & MCHEND)         /* (end of mark chunk) */
+                       if (w & MCHEND)         // (end of mark chunk)
                                break;
 
                                break;
 
-                       /*
-                        *  Get mark record
-                        */
-                       symbol = NULL;
-                       loc = *p.lp++;          /* mark location */
+                       // Get mark record
+                       SYM * symbol = NULL;
+                       loc = *p.lp++;          // mark location
 
 
-                       if (w & MCHFROM)        /* maybe change "from" section */
+                       if (w & MCHFROM)        // maybe change "from" section
                                from = *p.wp++;
 
                                from = *p.wp++;
 
-                       if (w & MSYMBOL)        /* maybe includes a symbol */
+                       if (w & MSYMBOL)        // maybe includes a symbol
                                symbol = *p.sy++;
 
                                symbol = *p.sy++;
 
-                       /*
-                        *  Compute mark position in relocation information;
-                        *  in RELMOD mode, get address of data to fix up.
-                        */
+                       // Compute mark position in relocation information; in RELMOD mode,
+                       // get address of data to fix up.
                        if (from == DATA)
                                loc += tsize;
 
                        if (from == DATA)
                                loc += tsize;
 
-                       wp = (char *)(mp + loc);
+                       wp = (uint8_t *)(mp + loc);
 
 
-                       if (okflag && (w & MLONG)) /* indicate first word of long */
+                       if (okflag && (w & MLONG)) // indicate first word of long
                        {
                                wp[1] = 5;
                                wp += 2;
                        {
                                wp[1] = 5;
                                wp += 2;
@@ -220,15 +214,13 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
 
                        if (symbol)
                        {
 
                        if (symbol)
                        {
-                               /*
-                                *  Deposit external reference
-                                */
+                               // Deposit external reference
                                if (okflag)
                                {
                                        if (w & MPCREL)
                                if (okflag)
                                {
                                        if (w & MPCREL)
-                                               w = 6;          /* pc-relative fixup */
+                                               w = 6;          // PC-relative fixup
                                        else
                                        else
-                                               w = 4;          /* absolute fixup */
+                                               w = 4;          // Absolute fixup
 
                                        w |= symbol->senv << 3;
                                        *wp++ = w >> 8;
 
                                        w |= symbol->senv << 3;
                                        *wp++ = w >> 8;
@@ -237,27 +229,19 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                        }
                        else
                        {
                        }
                        else
                        {
-                               /*
-                                *  Deposit section-relative mark;
-                                *  in RELMOD mode, fix it up in the chunk,
-                                *  kind of like a sleazoid linker.
-                                *
-                                *  In RELMOD mode, marks to words (MWORDs) "cannot happen,"
-                                *  checks are made when mark() is called, so we don't have
-                                *  to check again here.
-                                */
+                               // Deposit section-relative mark; in RELMOD mode, fix it up in
+                               // the chunk, kind of like a sleazoid linker.
+                               //
+                               // In RELMOD mode, marks to words (MWORDs) "cannot happen,"
+                               // checks are made when mark() is called, so we don't have to
+                               // check again here.
                                w &= TDB;
 
                                if (okflag)
                                        wp[1] = mark_tr[w];
                                else if (prg_flag && (w & (DATA | BSS)))
                                {
                                w &= TDB;
 
                                if (okflag)
                                        wp[1] = mark_tr[w];
                                else if (prg_flag && (w & (DATA | BSS)))
                                {
-                                       dp = wp;
-                                       diff = ((LONG)(*dp++ & 0xff)) << 24;
-                                       diff |= ((LONG)(*dp++ & 0xff)) << 16;
-                                       diff |= ((LONG)(*dp++ & 0xff)) << 8;
-                                       diff |= (LONG)(*dp & 0xff);
-
+                                       uint32_t diff = GETBE32(wp, 0);
 #ifdef DO_DEBUG
                                        DEBUG printf("diff=%lx ==> ", diff);
 #endif
 #ifdef DO_DEBUG
                                        DEBUG printf("diff=%lx ==> ", diff);
 #endif
@@ -266,11 +250,7 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                                        if (w == BSS)
                                                diff += sect[DATA].sloc;
 
                                        if (w == BSS)
                                                diff += sect[DATA].sloc;
 
-                                       dp = wp;
-                                       *dp++ = (char)(diff >> 24);
-                                       *dp++ = (char)(diff >> 16);
-                                       *dp++ = (char)(diff >> 8);
-                                       *dp = (char)diff;
+                                       SETBE32(wp, 0, diff)
 #ifdef DO_DEBUG
                                        DEBUG printf("%lx\n", diff);
 #endif
 #ifdef DO_DEBUG
                                        DEBUG printf("%lx\n", diff);
 #endif
@@ -279,15 +259,12 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                }
        }
 
                }
        }
 
-       /*
-        *  Generate ".PRG" relocation information in place in
-        *  the relocation words (the ``RELMOD'' operation).
-        */
+       // Generate ".PRG" relocation information in place in the relocation words
+       // (the "RELMOD" operation).
        if (okflag && prg_flag)
        {
        if (okflag && prg_flag)
        {
-               firstp = 1;
-               wp = mp;
-               dp = mp;
+               int firstp = 1;
+               wp = dp = mp;
 
                for(loc=0; loc<siz;)
                {
 
                for(loc=0; loc<siz;)
                {
@@ -295,44 +272,40 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                        {
                                if (firstp)
                                {
                        {
                                if (firstp)
                                {
-                                       *dp++ = (char)(loc >> 24);
-                                       *dp++ = (char)(loc >> 16);
-                                       *dp++ = (char)(loc >> 8);
-                                       *dp++ = (char)loc;
+                                       SETBE32(dp, 0, loc);
+                                       dp += 4;
                                        firstp = 0;
                                }
                                else
                                {
                                        firstp = 0;
                                }
                                else
                                {
-                                       for(diff=loc-lastloc; diff>254; diff-= 254)
+                                       uint32_t diff;
+
+                                       for(diff=loc-lastloc; diff>254; diff-=254)
                                                *dp++ = 1;
 
                                                *dp++ = 1;
 
-                                       *dp++ = (char)diff;
+                                       *dp++ = (uint8_t)diff;
                                }
 
                                }
 
-                               wp += 4;
                                lastloc = loc;
                                loc += 4;
                                lastloc = loc;
                                loc += 4;
+                               wp += 4;
                        }
                        }
-                       else 
+                       else
                        {
                                loc += 2;
                                wp += 2;
                        }
                }
 
                        {
                                loc += 2;
                                wp += 2;
                        }
                }
 
-               /*
-                *  Terminate relocation list with 0L (if there was no
-                *  relocation) or 0.B (if relocation information was
-                *  written).
-                */
+               // Terminate relocation list with 0L (if there was no relocation) or
+               // 0.B (if relocation information was written).
                if (!firstp)
                        *dp++ = 0;
                if (!firstp)
                        *dp++ = 0;
-               else for (firstp = 0; firstp < 4; ++firstp)
-                       *dp++ = 0;
+               else
+                       for(firstp=0; firstp<4; firstp++)
+                               *dp++ = 0;
 
 
-               /*
-                *  Return size of relocation information
-                */
+               // Return size of relocation information
                loc = dp - mp;
                return loc;
        }
                loc = dp - mp;
                return loc;
        }
@@ -344,211 +317,230 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
 //
 // Make mark image for BSD .o file
 //
 //
 // Make mark image for BSD .o file
 //
-uint32_t bsdmarkimg(char * mp, LONG siz, LONG tsize, int reqseg)
+// Assumptions about mark records (for BSD): if there is a symbol, the mark is
+// for an undefined symbol, otherwise it's just a normal TDB relocation.
+// N.B.: tsize is only used if reqseg is DATA
+//
+uint32_t MarkBSDImage(uint8_t * mp, uint32_t siz, uint32_t tsize, int reqseg)
 {
 {
-       MCHUNK * mch;                           // Mark chunk
-       PTR p;                                          // Source point from within mark chunk
-       uint16_t from;                          // Section fixups are currently FROM
-       uint16_t w;                                     // A word (temp)
-       uint32_t loc;                           // Location (temp) 
-       SYM * symbol;                           // Symbols (temp)
-       uint8_t * wp;                           // Pointer into raw relocation info
-       uint8_t * dp;                           // Deposit point for RELMOD info
-       uint32_t diff;                          // Difference to relocate (RELMOD)
-       uint32_t raddr, rflag = 0;      // BSD relocation address and flags
-       uint32_t rsize;                         // Relocation size
-       int validsegment = 0;           // Valid segment being processed
+       uint16_t from = 0;                      // Section fixups are currently FROM
+       uint32_t rsize = 0;                     // Relocation table size (written to mp)
+       int validsegment = 0;           // We are not yet in a valid segment...
 
 #ifdef DEBUG_IMAGE_MARKING
 
 #ifdef DEBUG_IMAGE_MARKING
-printf("bsdmarkimg():\n");
+printf("MarkBSDImage():\n");
 #endif
 #endif
-       // Initialise relocation size
-       rsize = 0;
+       // Initialize relocation table point (for D_foo macros)
        chptr = mp;
        chptr = mp;
-       from = 0;
 
 
-       for(mch=firstmch; mch!=NULL; mch=mch->mcnext)
+       // Run through all the relocation mark chunks
+       for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
        {
        {
-               for(p=mch->mcptr;;)
+               for(PTR p=mch->mcptr;;)
                {
                {
-                       w = *p.wp++;                    // Next mark entry
+                       SYM * symbol = NULL;
+                       uint16_t w = *p.wp++;   // Next mark entry
 
 
+                       // If we hit the end of a chunk, go get the next one
                        if (w & MCHEND)
                        if (w & MCHEND)
-                               break;                          // End of mark chunk
+                               break;
 
 
-                       // Get mark record
-                       symbol = NULL;
-                       loc = *p.lp++;                  // Mark location
+                       // Get the rest of the mark record
+                       uint32_t loc = *p.lp++; // Mark location
 
 
+                       // Maybe change "from" section
                        if (w & MCHFROM)
                        {
                        if (w & MCHFROM)
                        {
-                               // Maybe change "from" section
                                from = *p.wp++;
 
                                from = *p.wp++;
 
-                               if (obj_format == BSD)
-                               {
-                                       if (reqseg == TEXT)
-                                       {
-                                               // Requested segment is TEXT
-                                               if (from == TEXT)
-                                                       validsegment = 1; 
-                                               else
-                                                       validsegment = 0;
-                                       }
-                                       else
-                                       {
-                                               // Requested segment is DATA
-                                               if (from == DATA)
-                                                       validsegment = 1; 
-                                               else
-                                                       validsegment = 0;
-                                       }
-                               }
+                               if (((reqseg == TEXT) && (from == TEXT))
+                                       || ((reqseg == DATA) && (from == DATA)))
+                                       validsegment = 1;
+                               else
+                                       validsegment = 0;
                        }
 
                        }
 
-                       if (w & MSYMBOL)                        // Maybe includes a symbol
+                       // Maybe includes a symbol
+                       if (w & MSYMBOL)
                                symbol = *p.sy++;
 
                                symbol = *p.sy++;
 
-                       if (obj_format == BSD)
-                       {
-                               raddr = loc;                    // Set relocation address
+                       if (!validsegment)
+                               continue;
 
 
-                               if (validsegment)
 #ifdef DEBUG_IMAGE_MARKING
 #ifdef DEBUG_IMAGE_MARKING
-{
 printf(" validsegment: raddr = $%08X\n", raddr);
 #endif
 printf(" validsegment: raddr = $%08X\n", raddr);
 #endif
-                                       D_long(raddr);          // Write relocation address
-#ifdef DEBUG_IMAGE_MARKING
-}
-#endif
-
-                               if (w & MPCREL)
-                                       rflag = 0x000000A0;     // PC-relative fixup
-                               else
-                                       rflag = 0x00000040;     // Absolute fixup
-
-// This flag tells the linker to WORD swap the LONG when doing the fixup.
-                               if (w & MMOVEI)
-//{
-//printf("bsdmarkimg: ORing $01 to rflag (MMOVEI) [symbol=%s]...\n", symbol->sname);
-                                       rflag |= 0x00000001;
-//}
-                       }
+                       uint32_t rflag = 0x00000040;    // Absolute relocation
 
 
-                       // Compute mark position in relocation information;
-                       // in RELMOD mode, get address of data to fix up.
-                       if (from == DATA)
-                               loc += tsize;
+                       if (w & MPCREL)
+                               rflag = 0x000000A0;                     // PC-relative relocation
 
 
-                       wp = (uint8_t *)(mp + loc);
+                       // This flag tells the linker to WORD swap the LONG when doing the
+                       // relocation.
+                       if (w & MMOVEI)
+                               rflag |= 0x00000001;
 
 
-                       if (symbol)
+                       if (symbol != NULL)
                        {
                                // Deposit external reference
                        {
                                // Deposit external reference
-                               if (obj_format == BSD)
-                               {
-                                       rflag |= 0x00000010;                    // Set external reloc flag bit
-                                       rflag |= (symbol->senv << 8);   // Put symbol index in flags
-
-// Looks like this is completely unnecessary (considering it does the wrong thing!)
-#if 0
-                                       if (symbol->sattre & RISCSYM)
-{
-printf("bsdmarkimg: ORing $01 to rflag (RISCSYM) [symbol=%s]...\n", symbol->sname);
-                                               rflag |= 0x00000001;
-}
-#endif
+                               rflag |= 0x00000010;                    // Set external reloc flag bit
+                               rflag |= (symbol->senv << 8);   // Put symbol index in flags
 
 
-                                       if (validsegment)
-                                       {
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(2): rflag = $%08X\n", rflag);
 #endif
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(2): rflag = $%08X\n", rflag);
 #endif
-                                               D_long(rflag);                          // Write relocation flags
-                                               rsize += 8;                                     // Increment relocation size
-                                       }
-                               }
                        }
                        else
                        {
                        }
                        else
                        {
-                               if (obj_format == BSD)
-                               {
 #ifdef DEBUG_IMAGE_MARKING
 printf("  w = $%04X\n", w);
 #endif
 #ifdef DEBUG_IMAGE_MARKING
 printf("  w = $%04X\n", w);
 #endif
-                                       w &= TDB;                                               // Set reloc flags to segment
+                               w &= TDB;                               // Set reloc flags to segment
 
 
-                                       switch (w)
-                                       {
-                                       case TEXT: rflag |= 0x00000400; break;
-                                       case DATA: rflag |= 0x00000600; break;
-                                       case BSS:  rflag |= 0x00000800; break;
-                                       }
+                               switch (w)
+                               {
+                               case TEXT: rflag |= 0x00000400; break;
+                               case DATA: rflag |= 0x00000600; break;
+                               case BSS:  rflag |= 0x00000800; break;
+                               }
 
 
-                                       if (validsegment)
-                                       {
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(3): rflag = $%08X\n", rflag);
 #endif
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(3): rflag = $%08X\n", rflag);
 #endif
-                                               D_long(rflag);                          // Write relocation flags
-                                               rsize += 8;                                     // Increment relocation size
-                                       }
-
-                                       w &= TDB;
-
-                                       if (validsegment)
-                                       {
-                                               if (w & (DATA|BSS))
-                                               {
-                                                       dp = objImage + BSDHDRSIZE + loc;
-                                                       diff = ((LONG)(*dp++ & 0xFF)) << 24;
-                                                       diff |= ((LONG)(*dp++ & 0xFF)) << 16;
-                                                       diff |= ((LONG)(*dp++ & 0xFF)) << 8;
-                                                       diff |= (LONG)(*dp & 0xFF);
-                                                       DEBUG printf("diff=%ux ==> ", diff);
+                               // Fix relocation by adding in start of TEXT segment, since it's
+                               // currently relative to the start of the DATA (or BSS) segment
+                               if (w & (DATA | BSS))
+                               {
+                                       uint8_t * dp = objImage + BSDHDRSIZE + loc;
+
+                                       // Bump the start of the section if it's DATA (& not TEXT)
+                                       if (from == DATA)
+                                               dp += tsize;
+
+                                       uint32_t diff = GETBE32(dp, 0);
+                                       DEBUG printf("diff=%uX ==> ", diff);
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(4): diff = $%08X --> ", diff);
 #endif
 #ifdef DEBUG_IMAGE_MARKING
 printf("  validsegment(4): diff = $%08X --> ", diff);
 #endif
-       
-                                                       if (rflag & 0x01)
-                                                               diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
+                                       if (rflag & 0x01)
+                                               diff = WORDSWAP32(diff);
 
 
-                                                       diff += sect[TEXT].sloc;
+                                       diff += sect[TEXT].sloc;
 
 
-                                                       if (w == BSS)
-                                                               diff += sect[DATA].sloc;
+                                       if (w == BSS)
+                                               diff += sect[DATA].sloc;
 
 
-                                                       if (rflag & 0x01)
-                                                               diff = ((diff >> 16) & 0x0000FFFF) | ((diff << 16) & 0xFFFF0000);
+                                       if (rflag & 0x01)
+                                               diff = WORDSWAP32(diff);
 
 
-                                                       dp = objImage + BSDHDRSIZE + loc;
-                                                       *dp++ = (char)(diff >> 24);
-                                                       *dp++ = (char)(diff >> 16);
-                                                       *dp++ = (char)(diff >> 8);
-                                                       *dp = (char)diff;
-                                                       DEBUG printf("%ux\n", diff);
+                                       SETBE32(dp, 0, diff);
+                                       DEBUG printf("%uX\n", diff);
 #ifdef DEBUG_IMAGE_MARKING
 printf("$%08X\n", diff);
 #endif
 #ifdef DEBUG_IMAGE_MARKING
 printf("$%08X\n", diff);
 #endif
-                                               }
-                                       }
                                }
                        }
                                }
                        }
+
+                       D_long(loc);            // Write relocation address
+                       D_long(rflag);          // Write relocation flags
+                       rsize += 0x08;          // Increment relocation size
                }
        }
 
                }
        }
 
-       // Return relocation size
-       if (obj_format == BSD)
+       // Return relocation table's size
 #ifdef DEBUG_IMAGE_MARKING
 #ifdef DEBUG_IMAGE_MARKING
-{
 printf("  rsize = $%X\n", rsize);
 #endif
 printf("  rsize = $%X\n", rsize);
 #endif
-               return rsize;                                        
-#ifdef DEBUG_IMAGE_MARKING
+       return rsize;
 }
 }
-#endif
 
 
-       return siz;
+
+//
+// Make relocation record for ELF .o file.
+// Returns the size of the relocation record.
+//
+uint32_t CreateELFRelocationRecord(uint8_t * buf, uint8_t * secBuf, uint16_t section)
+{
+       uint16_t from = 0;              // Section fixups are currently FROM
+       uint32_t rsize = 0;             // Size of the relocation table
+
+       // Setup pointer for D_long/word/byte macros
+       chptr = buf;
+
+       for(MCHUNK * mch=firstmch; mch!=NULL; mch=mch->mcnext)
+       {
+               for(register PTR p=mch->mcptr;;)
+               {
+                       register uint16_t w = *p.wp++;  // w = next mark entry
+
+                       if (w & MCHEND)         // (end of mark chunk)
+                               break;
+
+                       // Get mark record
+                       SYM * symbol = NULL;
+                       uint16_t symFlags = 0;
+                       uint32_t r_offset = *p.lp++;    // Mark's location
+
+                       if (w & MCHFROM)                // Maybe change "from" section
+                               from = *p.wp++;
+
+                       if (w & MSYMBOL)                // Maybe includes a symbol
+                       {
+                               symbol = *p.sy++;
+
+                               if (symbol)
+                                       symFlags = symbol->sattr;
+                       }
+
+                       // Create relocation record for ELF object, if the mark is in the
+                       // current section.
+                       if (from & section)
+                       {
+                               uint32_t r_sym = 0;
+                               uint32_t r_type = 0;
+                               uint32_t r_addend = 0;
+
+                               // Since we're chucking all symbols here for ELF objects by
+                               // default (cf. sect.c), we discriminate here (normally, if
+                               // there is a symbol in the mark record, it means an undefined
+                               // symbol) :-P
+                               if (symbol && !(symFlags & DEFINED) && (symFlags & GLOBAL))
+                                       r_sym = symbol->senv + extraSyms;
+                               else if (w & TEXT)
+                                       r_sym = elfHdrNum[ES_TEXT];     // Mark TEXT segment
+                               else if (w & DATA)
+                                       r_sym = elfHdrNum[ES_DATA];     // Mark DATA segment
+                               else if (w & BSS)
+                                       r_sym = elfHdrNum[ES_BSS];      // Mark BSS segment
+
+                               // Set the relocation type next
+                               if (w & MPCREL)
+                                       r_type = 5;  // R_68K_PC16
+                               // N.B.: Since we've established that (from & section) is non-
+                               //       zero, this condition will *never* be satisfied... :-P
+                               //       It might be better to check the symbol's senv; that is,
+                               //       if this is a real problem that needs addressing...
+                               else if ((from & section) == 0)
+                                       // In the case of a section referring to a label in another
+                                       // section (for example text->data) use a R_68K_PC32 mark.
+                                       r_type = 4;  // R_68K_PC32
+                               else
+                                       r_type = 1;  // R_68K_32
+
+                               if (symbol != NULL)
+                                       r_addend = symbol->svalue;    // Mark offset into section
+                               else
+                                       r_addend = GETBE32(secBuf + r_offset, 0);
+
+                               // Deposit the relocation record
+                               D_long(r_offset);
+                               D_long((r_sym << 8) | r_type);
+                               D_long(r_addend);
+                               rsize += 0x0C;
+                       }
+               }
+       }
+
+       return rsize;
 }
 
 }
 
diff --git a/mark.h b/mark.h
index e53ae6583f373ec344bae61bf3ac310444256c6e..2a6dbe90bf01bb049452dd183873738b2a92916e 100644 (file)
--- a/mark.h
+++ b/mark.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MARK.H - A record of things that are defined relative to any of the sections
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // MARK.H - A record of things that are defined relative to any of the sections
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 #define __MARK_H__
 
 #include "rmac.h"
 #define __MARK_H__
 
 #include "rmac.h"
-#include "sect.h"
 
 
-#define MARK_ALLOC_INCR 1024           // # bytes to alloc for more mark space 
-#define MIN_MARK_MEM    (3 * sizeof(WORD) + 2 * sizeof(LONG))
+// A mark is of the form:
+// .W    <to+flags>    section mark is relative to, and flags in upper byte
+// .L    <loc>         location of mark in "from" section
+// .W    [from]                new from section
+// .L[L] [symbol]      symbol involved in external reference (LL for 64-bit pointers)
+#define MCHUNK struct _mchunk
+MCHUNK {
+   MCHUNK * mcnext;                            // Next mark chunk
+   PTR mcptr;                                  // Vector of marks
+   uint16_t mcalloc;                   // # marks allocted to mark block
+   uint16_t mcused;                            // # marks used in block
+};
 
 
-// Globals, externals, etc.
+#define MWORD        0x0000            // Marked word
+#define MLONG        0x0100            // Marked long
+#define MMOVEI       0x0200            // Mark RISC MOVEI instruction
+#define MGLOBAL      0x0800            // Mark contains global
+#define MPCREL       0x1000            // Mark is PC-relative
+#define MCHEND       0x2000            // Indicates end of mark chunk
+#define MSYMBOL      0x4000            // Mark includes symbol pointer
+#define MCHFROM      0x8000            // Mark includes change-to-from
+
+// Exported variables
 extern MCHUNK * firstmch;
 
 // Exported functions
 void InitMark(void);
 void StopMark(void);
 extern MCHUNK * firstmch;
 
 // Exported functions
 void InitMark(void);
 void StopMark(void);
-int rmark(uint16_t, uint32_t, uint16_t, uint16_t, SYM *);
-int amark(void);
-LONG bsdmarkimg(char *, LONG, LONG, int);
+uint32_t MarkRelocatable(uint16_t, uint32_t, uint16_t, uint16_t, SYM *);
+uint32_t AllocateMark(void);
+uint32_t MarkImage(register uint8_t * mp, uint32_t siz, uint32_t tsize, int okflag);
+uint32_t MarkBSDImage(uint8_t *, uint32_t, uint32_t, int);
+uint32_t CreateELFRelocationRecord(uint8_t *, uint8_t *, uint16_t section);
 
 #endif // __MARK_H__
 
 
 #endif // __MARK_H__
 
index 4614c38d66ed373eed028d7f0ed9a849f1282017..cbedaab6b0b2cdf5907af53d377a42cb4dc5b8ab 100644 (file)
--- a/object.c
+++ b/object.c
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // OBJECT.C - Writing Object Files
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // OBJECT.C - Writing Object Files
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 
 #include "object.h"
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 
 #include "object.h"
-#include "sect.h"
-#include "symbol.h"
-#include "mark.h"
 #include "error.h"
 #include "error.h"
-#include "riscasm.h"
 #include "mark.h"
 #include "mark.h"
+#include "riscasm.h"
+#include "sect.h"
+#include "symbol.h"
+
+
+//#define DEBUG_ELF
+
+uint32_t symsize = 0;                  // Size of BSD/ELF symbol table
+uint32_t strindx = 0x00000004; // BSD/ELF string table index
+uint8_t * strtable;                            // Pointer to the symbol string table
+uint8_t * objImage;                            // Global object image pointer
+int elfHdrNum[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+uint32_t extraSyms;
+
+static uint16_t tdb_tab[] = {
+       0,                              // absolute
+       AL_TEXT,                // TEXT segment based
+       AL_DATA, 0,             // DATA segment based
+       AL_BSS                  // BSS segment based
+};
+
+uint32_t PRGFLAGS;     /* PRGFLAGS as defined in Atari Compendium Chapter 2
+Definition             Bit(s)  Meaning
+--------------- ------- --------------------------------------------------------
+PF_FASTLOAD            0               If set, clear only the BSS area on program load,
+                                               otherwise clear the entire heap.
+PF_TTRAMLOAD   1               If set, the program may be loaded into alternative RAM,
+                                               otherwise it must be loaded into standard RAM.
+PF_TTRAMMEM            2               If set, the program's Malloc() requests may be satisfied
+                                               from alternative RAM, otherwise they must be satisfied
+                                               from standard RAM.
+-                              3               Currently unused
+See left.              4 & 5   If these bits are set to 0 (PF_PRIVATE), the processes'
+                                               entire memory space will be considered private
+                                               (when memory protection is enabled).If these bits are
+                                               set to 1 (PF_GLOBAL), the processes' entire memory space
+                                               will be readable and writable by any process (i.e.
+                                               global). If these bits are set to 2 (PF_SUPERVISOR), the
+                                               processes' entire memory space will only be readable and
+                                               writable by itself and any other process in supervisor
+                                               mode.If these bits are set to 3 (PF_READABLE), the
+                                               processes' entire memory space will be readable by any
+                                               application but only writable by itself.
+-                              6-15    Currently unused
+*/
+
+
+//
+// Add entry to symbol table
+// If 'globflag' is 1, make the symbol global
+// If in .PRG mode, adjust symbol values for fake link
+//
+uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag)
+{
+       // Copy symbol name to buffer (first 8 chars or less)
+       register uint8_t * s = sym->sname;
+       register int i;
+
+       for(i=0; i<8 && *s; i++)
+               *buf++ = *s++;
+
+       while (i++ < 8)
+               *buf++ = '\0';
+
+       //
+       // Construct and deposit flag word
+       //
+       // o  all symbols are AL_DEFINED
+       // o  install T/D/B/A base
+       //   o  install 'equated'
+       //   o  commons (COMMON) are AL_EXTERN, but not BSS
+       // o  exports (DEFINED) are AL_GLOBAL
+       // o  imports (~DEFINED) are AL_EXTERN
+       //
+       register uint16_t w1 = sym->sattr;
+       register uint16_t w = AL_DEFINED | tdb_tab[w1 & TDB];
+
+       if (w1 & EQUATED)               // Equated
+               w |= AL_EQUATED;
+
+       if (w1 & COMMON)
+       {
+               w |= AL_EXTERN | AL_GLOBAL;     // Common symbol
+               w &= ~AL_BSS;           // They're not BSS in Alcyon object files
+       }
+       else if (w1 & DEFINED)
+       {
+               if (globflag)           // Export the symbol
+                       w |= AL_GLOBAL;
+       }
+       else
+               w |= AL_EXTERN;         // Imported symbol
+
+       SETBE16(buf, 0, w);
+       buf += 2;
+       register uint32_t z = sym->svalue;
+
+       if (prg_flag)                   // Relocate value in .PRG segment
+       {
+               w1 &= DATA | BSS;
 
 
-/*
- *  Imports
- */
-extern int obj_format;         // object file format to write
-extern int prg_flag;           // generate Atari ST direct executable
+               if (w1)
+                       z += sect[TEXT].sloc;
 
 
-LONG symsize = 0;                      // Size of BSD symbol table
-LONG strindx = 0x00000004;     // BSD string table index
-char * strtable;                       // Pointer to the symbol string table
-char * objImage;                       // Global object image pointer
+               if (w1 & BSS)
+                       z += sect[DATA].sloc;
+       }
+
+       SETBE32(buf, 0, z);             // Deposit symbol value
+       buf += 4;
+
+       return buf;
+}
 
 
 //
 // Add an entry to the BSD symbol table
 //
 
 
 //
 // Add an entry to the BSD symbol table
 //
-char * constr_bsdsymtab(char * buf, SYM * sym, int globflag)
+uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag)
 {
 {
-       chptr = buf;                                            // Point to buffer for deposit longs
+       chptr = buf;                                            // Point to buffer for depositing longs
        D_long(strindx);                                        // Deposit the symbol string index
 
        D_long(strindx);                                        // Deposit the symbol string index
 
-       WORD w1 = sym->sattr;                           // Obtain symbol attribute
-       int w2 = sym->sattre;
-       LONG z = 0;                                                     // Initialise resulting symbol flags
+       uint16_t w1 = sym->sattr;                       // Obtain symbol attributes
+       uint32_t z = 0;                                         // Initialize resulting symbol flags
 
        if (w1 & EQUATED)
 
        if (w1 & EQUATED)
-       {                                       
+       {
                z = 0x02000000;                                 // Set equated flag
        }
        else
                z = 0x02000000;                                 // Set equated flag
        }
        else
@@ -56,20 +153,16 @@ char * constr_bsdsymtab(char * buf, SYM * sym, int globflag)
                z |= 0x01000000;                                // Set global flag if requested
 
        D_long(z);                                                      // Deposit symbol attribute
                z |= 0x01000000;                                // Set global flag if requested
 
        D_long(z);                                                      // Deposit symbol attribute
-
        z = sym->svalue;                                        // Obtain symbol value
        z = sym->svalue;                                        // Obtain symbol value
-       w1 &= DATA | BSS;                                       // Determine DATA or BSS flag
 
 
-       if (w1)                                                   
+       if (w1 & (DATA | BSS))
                z += sect[TEXT].sloc;                   // If DATA or BSS add TEXT segment size
 
                z += sect[TEXT].sloc;                   // If DATA or BSS add TEXT segment size
 
-       if (w1 & BSS) 
+       if (w1 & BSS)
                z += sect[DATA].sloc;                   // If BSS add DATA segment size
 
        D_long(z);                                                      // Deposit symbol value
                z += sect[DATA].sloc;                   // If BSS add DATA segment size
 
        D_long(z);                                                      // Deposit symbol value
-
        strcpy(strtable + strindx, sym->sname);
        strcpy(strtable + strindx, sym->sname);
-
        strindx += strlen(sym->sname) + 1;      // Incr string index incl null terminate
        buf += 12;                                                      // Increment buffer to next record
        symsize += 12;                                          // Increment symbol table size
        strindx += strlen(sym->sname) + 1;      // Incr string index incl null terminate
        buf += 12;                                                      // Increment buffer to next record
        symsize += 12;                                          // Increment symbol table size
@@ -78,129 +171,104 @@ char * constr_bsdsymtab(char * buf, SYM * sym, int globflag)
 }
 
 
 }
 
 
-/*
- *  Alcyon symbol flags
- */
-#define        AL_DEFINED      0x8000
-#define        AL_EQUATED      0x4000
-#define        AL_GLOBAL       0x2000
-#define        AL_EQUREG       0x1000
-#define        AL_EXTERN       0x0800
-#define        AL_DATA         0x0400
-#define        AL_TEXT         0x0200
-#define        AL_BSS          0x0100
-#define        AL_FILE         0x0080
-
-LONG PRGFLAGS;         /* PRGFLAGS as defined in Atari Compendium Chapter 2 */
-                                       /* Definition   Bit(s)  Meaning */
-                                       /* PF_FASTLOAD  0               If set, clear only the BSS area on program load,              */
-                                       /*                                              otherwise clear the entire heap.                              */
-                                       /* PF_TTRAMLOAD 1               If set, the program may be loaded into alternative RAM,       */
-                                       /*                                              otherwise it must be loaded into standard RAM.                */
-                                       /* PF_TTRAMMEM  2               If set, the program's Malloc() requests may be satisfied      */
-                                       /*                                              from alternative RAM, otherwise they must be satisfied        */
-                                       /*                                              from standard RAM.                                            */
-                                       /* -                    3               Currently unused.                                             */
-                                       /* See left.    4 & 5   If these bits are set to 0 (PF_PRIVATE), the processes'       */
-                                       /*                                              entire memory space will be considered private                */
-                                       /*                                              (when memory protection is enabled).If these bits are         */
-                                       /*                                              set to 1 (PF_GLOBAL), the processes' entire memory space      */
-                                       /*                                              will be readable and writable by any process (i.e. global).   */
-                                       /*                                              If these bits are set to 2 (PF_SUPERVISOR), the processes'    */
-                                       /*                                              entire memory space will only be readable and writable by     */
-                                       /*                                              itself and any other process in supervisor mode.If these      */
-                                       /*                                              bits are set to 3 (PF_READABLE), the processes' entire memory */
-                                       /*                                              space will be readable by any application but only            */
-                                       /*                                              writable by itself.                                           */
-                                       /* -                    6-15    Currently unused.                                             */
-
-static WORD tdb_tab[] = {
-       0,                              /* absolute */
-       AL_TEXT,                /* TEXT segment based */
-       AL_DATA, 0,             /* DATA segment based */
-       AL_BSS                  /* BSS segment based */
-};
-
-
-#define HDRSIZE 0x1C           /* size of Alcyon header */
-
-
-/*
- *  Add entry to symbol table;
- *  if `globflag' is 1, make the symbol global;
- *  if in .PRG mode, adjust symbol values for fake link.
- *
- */
-char * constr_symtab(register char * buf, SYM * sym, int globflag)
+//
+// Add entry to ELF symbol table; if `globflag' is 1, make the symbol global
+//
+uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag)
 {
 {
-       register int i;
-       register char * s;
-       register WORD w;
-       register LONG z;
-       register WORD w1;
-
-       /*
-        *  Copy symbol name
-        */
-       s = sym->sname;
-
-       for(i=0; i<8 && *s; i++)
-               *buf++ = *s++;
+       chptr = buf;
+       D_long(strindx);                // st_name
+       D_long(sym->svalue);    // st_value
+       D_long(0);                              // st_size
+       uint8_t st_info = 0;
 
 
-       while (i++ < 8)
-               *buf++ = '\0';
-
-       /*
-        *  Construct and deposit flag word
-        *
-        *      o  all symbols are AL_DEFINED
-        *      o  install T/D/B/A base
-        *    o  install 'equated'
-        *    o  commons (COMMON) are AL_EXTERN, but not BSS
-        *      o  exports (DEFINED) are AL_GLOBAL
-        *      o  imports (~DEFINED) are AL_EXTERN
-        *
-        */
-       w1 = sym->sattr;
-       w = AL_DEFINED | tdb_tab[w1 & TDB];
-
-       if (w1 & EQUATED)               /* equated */
-               w |= AL_EQUATED;
+       register WORD w1 = sym->sattr;
 
        if (w1 & COMMON)
        {
 
        if (w1 & COMMON)
        {
-               w |= AL_EXTERN | AL_GLOBAL;     /* common symbol */
-               w &= ~AL_BSS;           /* they're not BSS in Alcyon object files */
+               //w |= AL_EXTERN | AL_GLOBAL;   // common symbol
+               //w &= ~AL_BSS;         // they're not BSS in Alcyon object files
        }
        else if (w1 & DEFINED)
        {
        }
        else if (w1 & DEFINED)
        {
-               if (globflag)           /* export the symbol */
-                       w |= AL_GLOBAL;
+               if (globflag)           // Export the symbol
+                       st_info |= 16;   //STB_GLOBAL (1<<4)
        }
        }
-       else w |= AL_EXTERN;            /* imported symbol */
+       else if (w1 & (GLOBAL | REFERENCED))
+               st_info |= 16;
 
 
-       *buf++ = w >> 8;
-       *buf++ = (char)w;
+       D_byte(st_info);
+       D_byte(0);                              // st_other
 
 
-       z = sym->svalue;
+       uint16_t st_shndx = 0xFFF1;     // Assume absolute (equated) number
 
 
-       if (prg_flag)                   /* relocate value in .PRG segment */
-       {
-               w1 &= DATA | BSS;
+       if (w1 & TEXT)
+               st_shndx = elfHdrNum[ES_TEXT];
+       else if (w1 & DATA)
+               st_shndx = elfHdrNum[ES_DATA];
+       else if (w1 & BSS)
+               st_shndx = elfHdrNum[ES_BSS];
+       else if (globflag)
+               st_shndx = 0;           // Global, not absolute
 
 
-               if (w1)
-                       z += sect[TEXT].sloc;
+       D_word(st_shndx);
 
 
-               if (w1 & BSS)
-                       z += sect[DATA].sloc;
-       }
+       strcpy(strtable + strindx, sym->sname);
+       strindx += strlen(sym->sname) + 1;      // Incr string index incl null terminate
+       symsize += 0x10;                                        // Increment symbol table size
+
+       return buf + 0x10;
+}
 
 
-       *buf++ = z >> 24;               /* deposit symbol value */
-       *buf++ = z >> 16;
-       *buf++ = z >> 8;
-       *buf++ = z;
 
 
-       return buf;
+//
+// Helper function for ELF output
+//
+int DepositELFSectionHeader(uint8_t * ptr, uint32_t name, uint32_t type, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint32_t link, uint32_t info, uint32_t addralign, uint32_t entsize)
+{
+       chptr = ptr;
+       D_long(name);
+       D_long(type);
+       D_long(flags);
+       D_long(addr);
+       D_long(offset);
+       D_long(size);
+       D_long(link);
+       D_long(info);
+       D_long(addralign);
+       D_long(entsize);
+       return 40;
+}
+
+
+//
+// Deposit an entry in the Section Header string table
+//
+uint32_t DepositELFSHSTEntry(uint8_t ** pTable, const uint8_t * s)
+{
+#ifdef DEBUG_ELF
+printf("DepositELFSHSTEntry: s = \"%s\"\n", s);
+#endif
+       uint32_t strSize = strlen(s);
+       strcpy(*pTable, s);
+       *pTable += strSize + 1;
+       return strSize + 1;
+}
+
+
+//
+// Deposit a symbol table entry in the ELF Symbol Table
+//
+uint32_t DepositELFSymbol(uint8_t * ptr, uint32_t name, uint32_t addr, uint32_t size, uint8_t info, uint8_t other, uint16_t shndx)
+{
+       chptr = ptr;
+       D_long(name);
+       D_long(addr);
+       D_long(size);
+       *chptr++ = info;
+       *chptr++ = other;
+       D_word(shndx);
+       return 16;
 }
 
 
 }
 
 
@@ -214,8 +282,8 @@ int WriteObject(int fd)
        LONG tds;                               // TEXT & DATA segment size
        int i;                                  // Temporary int
        CHUNK * cp;                             // Chunk (for gather)
        LONG tds;                               // TEXT & DATA segment size
        int i;                                  // Temporary int
        CHUNK * cp;                             // Chunk (for gather)
-       char * buf;                             // Scratch area
-       char * p;                               // Temporary ptr
+       uint8_t * buf;                  // Scratch area
+       uint8_t * p;                    // Temporary ptr
        LONG ssize;                             // Size of symbols
        LONG trsize, drsize;    // Size of relocations
        long unused;                    // For supressing 'write' warnings
        LONG ssize;                             // Size of symbols
        LONG trsize, drsize;    // Size of relocations
        long unused;                    // For supressing 'write' warnings
@@ -230,7 +298,7 @@ int WriteObject(int fd)
        // Write requested object file...
        if ((obj_format == BSD) || ((obj_format == ALCYON) && (prg_flag == 0)))
     {
        // Write requested object file...
        if ((obj_format == BSD) || ((obj_format == ALCYON) && (prg_flag == 0)))
     {
-               // Force BSD format from here onwards
+               // Force BSD format (if it was ALCYON format)
                obj_format = BSD;
 
                if (verb_flag)
                obj_format = BSD;
 
                if (verb_flag)
@@ -238,7 +306,7 @@ int WriteObject(int fd)
                        printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                }
 
                        printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                }
 
-               ssize = ((LONG)sy_assign(NULL, NULL));          // Assign index numbers to the symbols
+               ssize = sy_assign(NULL, NULL);                          // Assign index numbers to the symbols
                tds = sect[TEXT].sloc + sect[DATA].sloc;        // Get size of TEXT and DATA segment
                buf = malloc(0x600000);                                         // Allocate 6mb object file image memory
 
                tds = sect[TEXT].sloc + sect[DATA].sloc;        // Get size of TEXT and DATA segment
                buf = malloc(0x600000);                                         // Allocate 6mb object file image memory
 
@@ -248,9 +316,9 @@ int WriteObject(int fd)
                        return ERROR;
                }
 
                        return ERROR;
                }
 
-               memset(buf, 0, 0x600000);               // Reset allocated memory
+               memset(buf, 0, 0x600000);               // Clear allocated memory
                objImage = buf;                                 // Set global object image pointer
                objImage = buf;                                 // Set global object image pointer
-               strtable = malloc(0x200000);    // Allocate 2mb scratch buffer 
+               strtable = malloc(0x200000);    // Allocate 2MB string table buffer
 
                if (strtable == NULL)
                {
 
                if (strtable == NULL)
                {
@@ -258,23 +326,23 @@ int WriteObject(int fd)
                        return ERROR;
                }
 
                        return ERROR;
                }
 
-               memset(strtable, 0, 0x200000);  // Reset allocated memory
+               memset(strtable, 0, 0x200000);  // Clear allocated memory
 
                // Build object file header
 
                // Build object file header
-               chptr = buf;                                    // Base of header
+               chptr = buf;                                    // Base of header (for D_foo macros)
                D_long(0x00000107);                             // Magic number
                D_long(0x00000107);                             // Magic number
-               D_long(sect[TEXT].sloc);                // TEXT size 
-               D_long(sect[DATA].sloc);                // DATA size 
-               D_long(sect[BSS].sloc);                 // BSS size 
+               D_long(sect[TEXT].sloc);                // TEXT size
+               D_long(sect[DATA].sloc);                // DATA size
+               D_long(sect[BSS].sloc);                 // BSS size
                D_long(0x00000000);                             // Symbol size
                D_long(0x00000000);                             // First entry (0L)
                D_long(0x00000000);                             // TEXT relocation size
                D_long(0x00000000);                             // Symbol size
                D_long(0x00000000);                             // First entry (0L)
                D_long(0x00000000);                             // TEXT relocation size
-               D_long(0x00000000);                             // BSD relocation size
+               D_long(0x00000000);                             // DATA relocation size
 
                // Construct TEXT and DATA segments (without relocation changes)
                p = buf + BSDHDRSIZE;
 
 
                // Construct TEXT and DATA segments (without relocation changes)
                p = buf + BSDHDRSIZE;
 
-               for(i=TEXT; i<=DATA; ++i)
+               for(i=TEXT; i<=DATA; i++)
                {
                        for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
                        {
                {
                        for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
                        {
@@ -284,40 +352,46 @@ int WriteObject(int fd)
                }
 
                // Do relocation tables (and make changes to segment data)
                }
 
                // Do relocation tables (and make changes to segment data)
-               p = buf + (BSDHDRSIZE + tds);   // Move obj image ptr to reloc info
-               trsize = bsdmarkimg(p, tds, sect[TEXT].sloc, TEXT);// Do TEXT relocation table
-               chptr = buf + 24;                               // Point to relocation hdr entry
+               p = buf + BSDHDRSIZE + tds;             // Move obj image ptr to reloc info
+               trsize = MarkBSDImage(p, tds, sect[TEXT].sloc, TEXT);// Do TEXT relocation table
+               chptr = buf + 0x18;                             // Point to relocation hdr entry
                D_long(trsize);                                 // Write the relocation table size
                D_long(trsize);                                 // Write the relocation table size
-               p = buf + (BSDHDRSIZE + tds + trsize);  // Move obj image ptr to reloc info
-               drsize = bsdmarkimg(p, tds, sect[TEXT].sloc, DATA);// Do DATA relocation table
-               chptr = buf + 28;                               // Point to relocation hdr entry
+
+               // Move obj image ptr to reloc info
+               p = buf + BSDHDRSIZE + tds + trsize;
+               drsize = MarkBSDImage(p, tds, sect[TEXT].sloc, DATA);// Do DATA relocation table
+               chptr = buf + 0x1C;                             // Point to relocation hdr entry
                D_long(drsize);                                 // Write the relocation table size
 
                D_long(drsize);                                 // Write the relocation table size
 
-               p = buf + (BSDHDRSIZE + tds + trsize + drsize);// Point to start of symbol table
-               sy_assign(p, constr_bsdsymtab); // Build symbol and string tables
-               chptr = buf + 16;                               // Point to sym table size hdr entry
+               // Point to start of symbol table
+               p = buf + BSDHDRSIZE + tds + trsize + drsize;
+               sy_assign(p, AddBSDSymEntry);   // Build symbol and string tables
+               chptr = buf + 0x10;                             // Point to sym table size hdr entry
                D_long(symsize);                                // Write the symbol table size
 
                // Point to string table
                D_long(symsize);                                // Write the symbol table size
 
                // Point to string table
-               p = buf + (BSDHDRSIZE + tds + trsize + drsize + symsize);    
-
+               p = buf + BSDHDRSIZE + tds + trsize + drsize + symsize;
                memcpy(p, strtable, strindx);   // Copy string table to object image
                memcpy(p, strtable, strindx);   // Copy string table to object image
-
-               if (buf)
-                       free(strtable);                         // Free allocated memory
-
                chptr = p;                                              // Point to string table size long
                D_long(strindx);                                // Write string table size
 
                // Write the BSD object file from the object image buffer
                unused = write(fd, buf, BSDHDRSIZE + tds + trsize + drsize + symsize + strindx + 4);
 
                chptr = p;                                              // Point to string table size long
                D_long(strindx);                                // Write string table size
 
                // Write the BSD object file from the object image buffer
                unused = write(fd, buf, BSDHDRSIZE + tds + trsize + drsize + symsize + strindx + 4);
 
+               if (verb_flag)
+               {
+                       printf("TextRel size: %d bytes\n", trsize);
+                       printf("DataRel size: %d bytes\n", drsize);
+               }
+
                if (buf)
                if (buf)
+               {
+                       free(strtable);                         // Free allocated memory
                        free(buf);                                      // Free allocated memory
                        free(buf);                                      // Free allocated memory
-
-    }
-    else if (obj_format==ALCYON)
-    {
+               }
+       }
+       else if (obj_format == ALCYON)
+       {
                if (verb_flag)
                {
                        if (prg_flag)
                if (verb_flag)
                {
                        if (prg_flag)
@@ -330,79 +404,353 @@ int WriteObject(int fd)
                                printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                        }
                }
                                printf("Total       : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc);
                        }
                }
-               /*
-                *  Compute size of symbol table;
-                *   assign numbers to the symbols...
-                */
+
+               // Compute size of symbol table; assign numbers to the symbols...
                ssize = 0;
 
                ssize = 0;
 
+               // As we grabbed BSD *and* Alcyon in prg_flag == 0 mode, this is *always*
+               // false... :-P
                if (prg_flag != 1)
                if (prg_flag != 1)
-                       ssize = ((LONG)sy_assign(NULL, NULL)) * 14;
+                       ssize = sy_assign(NULL, NULL) * 14;
 
 
-               /*
-                *  Alloc memory for header+text+data, symbol and
-                *   relocation information construction.
-                */
+               // Alloc memory for header + text + data, symbol and relocation
+               // information construction.
                t = tds = sect[TEXT].sloc + sect[DATA].sloc;
 
                if (t < ssize)
                        t = ssize;
 
                t = tds = sect[TEXT].sloc + sect[DATA].sloc;
 
                if (t < ssize)
                        t = ssize;
 
-               buf = (char *)((int)malloc(t + HDRSIZE) + HDRSIZE);
-
-               /*
-                *  Build object file header
-                *   just before the text+data image
-                */
-               chptr = buf - HDRSIZE;  /* -> base of header */
-               D_word(0x601a);                 /* 00 - magic number */
-               t = sect[TEXT].sloc;    /* 02 - TEXT size */
-               D_long(t);
-               t = sect[DATA].sloc;    /* 06 - DATA size */
-               D_long(t);
-               t = sect[BSS].sloc;             /* 0a - BSS size */
-               D_long(t);
-               D_long(ssize);                  /* 0e - symbol table size */
-               D_long(0);                              /* 12 - stack size (unused) */
-               D_long(PRGFLAGS);               /* 16 - PRGFLAGS */
-               D_word(0);                              /* 1a - relocation information exists */
-
-               /*
-                *  Construct text and data segments;
-                *  fixup relocatable longs in .PRG mode;
-                *  finally write the header+text+data
-                */
+               // Is there any reason to do this this way???
+               buf = malloc(t + HDRSIZE);
+               buf += HDRSIZE;
+
+               // Build object file header just before the text+data image
+               chptr = buf - HDRSIZE;          // -> base of header
+               D_word(0x601A);                         // 00 - magic number
+               D_long(sect[TEXT].sloc);        // 02 - TEXT size
+               D_long(sect[DATA].sloc);        // 06 - DATA size
+               D_long(sect[BSS].sloc);         // 0A - BSS size
+               D_long(ssize);                          // 0E - symbol table size
+               D_long(0);                                      // 12 - stack size (unused)
+               D_long(PRGFLAGS);                       // 16 - PRGFLAGS
+               D_word(0);                                      // 1A - relocation information exists
+
+               // Construct text and data segments; fixup relocatable longs in .PRG
+               // mode; finally write the header + text + data
                p = buf;
 
                for(i=TEXT; i<=DATA; i++)
                {
                p = buf;
 
                for(i=TEXT; i<=DATA; i++)
                {
-                       for (cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
+                       for(cp=sect[i].sfcode; cp!=NULL; cp=cp->chnext)
                        {
                                memcpy(p, cp->chptr, cp->ch_size);
                                p += cp->ch_size;
                        }
                }
 
                        {
                                memcpy(p, cp->chptr, cp->ch_size);
                                p += cp->ch_size;
                        }
                }
 
+               // Do a first pass on the Alcyon image, if in PRG mode
                if (prg_flag)
                if (prg_flag)
-                       markimg(buf, tds, sect[TEXT].sloc, 0);
+                       MarkImage(buf, tds, sect[TEXT].sloc, 0);
 
 
-               write(fd, buf - HDRSIZE, tds + HDRSIZE);
+               unused = write(fd, buf - HDRSIZE, tds + HDRSIZE);
 
 
-               /*
-                *  Construct and write symbol table
-                */
+               // Construct and write symbol table
                if (prg_flag != 1)
                {
                if (prg_flag != 1)
                {
-                       sy_assign(buf, constr_symtab);
-                       write(fd, buf, ssize);
+                       sy_assign(buf, AddSymEntry);
+                       unused = write(fd, buf, ssize);
+               }
+
+               // Construct and write relocation information; the size of it changes if
+               // we're writing a RELMODed executable.
+               tds = MarkImage(buf, tds, sect[TEXT].sloc, 1);
+               unused = write(fd, buf, tds);
+       }
+       else if (obj_format == ELF)
+       {
+               // Allocate 6MB object file image memory
+               buf = malloc(0x600000);
+
+               if (buf == NULL)
+               {
+                       error("cannot allocate object file memory (in BSD mode)");
+                       return ERROR;
+               }
+
+               memset(buf, 0, 0x600000);
+               objImage = buf;                                 // Set global object image pointer
+               strtable = malloc(0x200000);    // Allocate 2MB string table buffer
+
+               if (strtable == NULL)
+               {
+                       error("cannot allocate string table memory (in BSD mode)");
+                       return ERROR;
+               }
+
+               memset(strtable, 0, 0x200000);
+
+               // This is pretty much a first pass at this shite, so there's room for
+               // improvement. :-P
+               uint8_t headers[4 * 10 * 10];   // (DWORD * 10) = 1 hdr, 10 entries
+               int headerSize = 0;
+               uint8_t shstrtab[128];                  // The section header string table proper
+               uint32_t shstTab[9];                    // Index into shstrtab for strings
+               uint8_t * shstPtr = shstrtab;   // Temp pointer
+               uint32_t shstSize = 0;
+               int numEntries = 4;                             // There are always at *least* 4 sections
+               int shstIndex = 1;                              // The section where the shstrtab lives
+               int elfSize = 0;                                // Size of the ELF object
+               // Clear the header numbers
+               memset(elfHdrNum, 0, 9 * sizeof(int));
+
+               //
+               // First step is to see what sections need to be made; we also
+               // construct the section header string table here at the same time.
+               //
+               shstTab[ES_NULL] = shstSize;
+               shstSize += DepositELFSHSTEntry(&shstPtr, "");
+               shstTab[ES_SHSTRTAB] = shstSize;
+               shstSize += DepositELFSHSTEntry(&shstPtr, ".shstrtab");
+               shstTab[ES_SYMTAB] = shstSize;
+               shstSize += DepositELFSHSTEntry(&shstPtr, ".symtab");
+               shstTab[ES_STRTAB] = shstSize;
+               shstSize += DepositELFSHSTEntry(&shstPtr, ".strtab");
+
+               if (sect[TEXT].sloc > 0)
+               {
+                       elfHdrNum[ES_TEXT] = shstIndex;
+                       shstTab[ES_TEXT] = shstSize;
+                       shstSize += DepositELFSHSTEntry(&shstPtr, "TEXT");
+                       shstIndex++;
+                       numEntries++;
+               }
+
+               if (sect[DATA].sloc > 0)
+               {
+                       elfHdrNum[ES_DATA] = shstIndex;
+                       shstTab[ES_DATA] = shstSize;
+                       shstSize += DepositELFSHSTEntry(&shstPtr, "DATA");
+                       shstIndex++;
+                       numEntries++;
+               }
+
+               if (sect[BSS].sloc > 0)
+               {
+                       elfHdrNum[ES_BSS] = shstIndex;
+                       shstTab[ES_BSS] = shstSize;
+                       shstSize += DepositELFSHSTEntry(&shstPtr, "BSS");
+                       shstIndex++;
+                       numEntries++;
+               }
+
+               if (sect[TEXT].relocs > 0)
+               {
+                       elfHdrNum[ES_RELATEXT] = shstIndex;
+                       shstTab[ES_RELATEXT] = shstSize;
+                       shstSize += DepositELFSHSTEntry(&shstPtr, ".relaTEXT");
+                       shstIndex++;
+                       numEntries++;
+               }
+
+               if (sect[DATA].relocs > 0)
+               {
+                       elfHdrNum[ES_RELADATA] = shstIndex;
+                       shstTab[ES_RELADATA] = shstSize;
+                       shstSize += DepositELFSHSTEntry(&shstPtr, ".relaDATA");
+                       shstIndex++;
+                       numEntries++;
                }
 
                }
 
-               /*
-                *  Construct and write relocation information;
-                *   the size of it changes if we're writing a RELMODed executable.
-                */
-               tds = markimg(buf, tds, sect[TEXT].sloc, 1);
-               write(fd, buf, tds);
+               elfHdrNum[ES_SHSTRTAB] = shstIndex + 0;
+               elfHdrNum[ES_SYMTAB]   = shstIndex + 1;
+               elfHdrNum[ES_STRTAB]   = shstIndex + 2;
+
+#ifdef DEBUG_ELF
+printf("ELF shstrtab size: %i bytes. Entries:\n", shstSize);
+for(int j=0; j<i; j++)
+       printf("\"%s\"\n", shstrtab + shstTab[j]);
+#endif
+
+               // Construct ELF header
+               // If you want to make any sense out of this you'd better take a look
+               // at Executable and Linkable Format on Wikipedia.
+               chptr = buf;
+               D_long(0x7F454C46); // 00 - "<7F>ELF" Magic Number
+               D_byte(0x01); // 04 - 32 vs 64 (1 = 32, 2 = 64)
+               D_byte(0x02); // 05 - Endianness (1 = LE, 2 = BE)
+               D_byte(0x01); // 06 - Original version of ELF (set to 1)
+               D_byte(0x00); // 07 - Target OS ABI (0 = System V)
+               D_byte(0x00); // 08 - ABI Extra (unneeded)
+               D_byte(0x00); // 09 - Pad bytes
+               D_word(0x00);
+               D_long(0x00);
+               D_word(0x01); // 10 - ELF Type (1 = relocatable)
+               D_word(0x04); // 12 - Architecture (EM_68K = 4, Motorola M68K family)
+               D_long(0x01); // 14 - Version (1 = original ELF)
+               D_long(0x00); // 18 - Entry point virtual address (unneeded)
+               D_long(0x00); // 1C - Program header table offset (unneeded)
+               D_long(0x00); // 20 - Section header table offset (to be determined)
+
+               if (0)
+               {
+                       // Specifically for 68000 CPU
+                       D_long(0x01000000) // 24 - Processor-specific flags - EF_M68K_M68000
+               }
+               else
+               {
+                       // CPUs other than 68000 (68020...)
+                       D_long(0); // 24 - Processor-specific flags (ISA dependent)
+               }
+
+               D_word(0x0034); // 28 - ELF header size in bytes
+               D_word(0); // 2A - Program header table entry size
+               D_word(0); // 2C - Program header table entry count
+               D_word(0x0028); // 2E - Section header entry size - 40 bytes for ELF32
+               D_word(numEntries); // 30 - Section header table entry count
+               D_word(shstIndex); // 32 - Section header string table index
+
+               elfSize += 0x34;
+
+               // Deposit section header 0 (NULL)
+               headerSize += DepositELFSectionHeader(headers + headerSize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+               int textLoc = elfSize;
+
+               // Construct TEXT section, if any
+               if (sect[TEXT].sloc > 0)
+               {
+                       headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_TEXT], 1, 6, 0, elfSize, sect[TEXT].sloc, 0, 0, 2, 0);
+
+                       for(CHUNK * cp=sect[TEXT].sfcode; cp!=NULL; cp=cp->chnext)
+                       {
+                               memcpy(buf + elfSize, cp->chptr, cp->ch_size);
+                               elfSize += cp->ch_size;
+                       }
+
+                       // Pad for next section (LONG boundary)
+                       elfSize = (elfSize + 3) & ~3;
+               }
+
+               int dataLoc = elfSize;
+
+               // Construct DATA section, if any
+               if (sect[DATA].sloc > 0)
+               {
+                       headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_DATA], 1, 3, 0, elfSize, sect[DATA].sloc, 0, 0, 1, 0);
+
+                       for(CHUNK * cp=sect[DATA].sfcode; cp!=NULL; cp=cp->chnext)
+                       {
+                               memcpy(buf + elfSize, cp->chptr, cp->ch_size);
+                               elfSize += cp->ch_size;
+                       }
+
+                       // Pad for next section (LONG boundary)
+                       elfSize = (elfSize + 3) & ~3;
+               }
+
+               // Construct BSS section, if any
+               if (sect[BSS].sloc > 0)
+               {
+                       headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_BSS], 8, 3, 0, elfSize, sect[BSS].sloc, 0, 0, 2, 0);
+               }
+
+               int textrelLoc = headerSize;
+
+               // Add headers for relocated sections, if any...
+               if (sect[TEXT].relocs > 0)
+                       headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_RELATEXT], 4, 0x00, 0, 0, 0, elfHdrNum[ES_SYMTAB], elfHdrNum[ES_TEXT], 4, 0x0C);
+
+               int datarelLoc = headerSize;
+
+               if (sect[DATA].relocs > 0)
+                       headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_RELADATA], 4, 0x40, 0, 0, 0, elfHdrNum[ES_SYMTAB], elfHdrNum[ES_DATA], 4, 0x0C);
+
+               // Add shstrtab
+               headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_SHSTRTAB], 3, 0, 0, elfSize, shstSize, 0, 0, 1, 0);
+               memcpy(buf + elfSize, shstrtab, shstSize);
+               elfSize += shstSize;
+               // Pad for next section (LONG boundary)
+               elfSize = (elfSize + 3) & ~3;
+
+               // Add section headers
+               int headerLoc = elfSize;
+               chptr = buf + 0x20;             // Set section header offset in ELF header
+               D_long(headerLoc);
+               elfSize += (4 * 10) * numEntries;
+
+               // Add symbol table & string table
+               int symtabLoc = elfSize;
+               strindx = 0;    // Make sure we start at the beginning...
+               elfSize += DepositELFSymbol(buf + elfSize, 0, 0, 0, 0, 0, 0);
+               *strtable = 0;
+               strindx++;
+               extraSyms = 1;
+
+               if (sect[TEXT].sloc > 0)
+               {
+                       elfSize += DepositELFSymbol(buf + elfSize, 0, 0, 0, 3, 0, elfHdrNum[ES_TEXT]);
+                       extraSyms++;
+               }
+
+               if (sect[DATA].sloc > 0)
+               {
+                       elfSize += DepositELFSymbol(buf + elfSize, 0, 0, 0, 3, 0, elfHdrNum[ES_DATA]);
+                       extraSyms++;
+               }
+
+               if (sect[BSS].sloc > 0)
+               {
+                       elfSize += DepositELFSymbol(buf + elfSize, 0, 0, 0, 3, 0, elfHdrNum[ES_BSS]);
+                       extraSyms++;
+               }
+
+               int numSymbols = sy_assign_ELF(buf + elfSize, AddELFSymEntry);
+               elfSize += numSymbols * 0x10;
+
+               // String table
+               int strtabLoc = elfSize;
+               memcpy(buf + elfSize, strtable, strindx);
+               elfSize += strindx;
+               // Pad for next section (LONG boundary)
+               elfSize = (elfSize + 3) & ~3;
+
+               headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_SYMTAB], 2, 0, 0, symtabLoc, (numSymbols + extraSyms) * 0x10, shstIndex + 2, firstglobal + extraSyms, 4, 0x10);
+               headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_STRTAB], 3, 0, 0, strtabLoc, strindx, 0, 0, 1, 0);
+
+               // Add relocation tables, if any (no need to align after these, they're
+               // already on DWORD boundaries)
+               if (sect[TEXT].relocs > 0)
+               {
+                       uint32_t textrelSize = CreateELFRelocationRecord(buf + elfSize, buf + textLoc, TEXT);
+                       // Deposit offset & size, now that we know them
+                       chptr = headers + textrelLoc + 0x10;
+                       D_long(elfSize);
+                       D_long(textrelSize);
+                       elfSize += textrelSize;
+               }
+
+               if (sect[DATA].relocs > 0)
+               {
+                       uint32_t datarelSize = CreateELFRelocationRecord(buf + elfSize, buf + dataLoc, DATA);
+                       // Deposit offset & size, now that we know them
+                       chptr = headers + datarelLoc + 0x10;
+                       D_long(elfSize);
+                       D_long(datarelSize);
+                       elfSize += datarelSize;
+               }
+
+               // Copy headers into the object
+               memcpy(buf + headerLoc, headers, headerSize);
+
+               // Finally, write out the object
+               unused = write(fd, buf, elfSize);
+
+               // Free allocated memory
+               if (buf)
+               {
+                       free(buf);
+                       free(strtable);
+               }
        }
 
        return 0;
        }
 
        return 0;
index 26a1960e7395a63851c45ab2872a6a229f7b378b..f3e79d23603ed147afbf9cd4fb2af1490e8f1b4b 100644 (file)
--- a/object.h
+++ b/object.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // OBJECT.H - Writing Object Files
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // OBJECT.H - Writing Object Files
-// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -9,11 +9,34 @@
 #ifndef __OBJECT_H__
 #define __OBJECT_H__
 
 #ifndef __OBJECT_H__
 #define __OBJECT_H__
 
-// Size of BSD header
-#define BSDHDRSIZE   0x20
+#include <rmac.h>
 
 
-// Globals, externals, etc.
-extern char * objImage;
+#define BSDHDRSIZE  0x20       // Size of BSD header
+#define HDRSIZE     0x1C       // Size of Alcyon header
+