]> Shamusworld >> Repos - rmac/commitdiff
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
-// 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
 //
index e03e65d6fa0d2ed53a9ee57dcc4569912cdd3d10..a127bd8f874fb7c054a7b5ecc383ec28529ef3ff 100644 (file)
   <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>
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
-// 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
 //
@@ -78,7 +78,7 @@ int amode(int acount)
        #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;
 
@@ -146,7 +146,7 @@ int reglist(WORD * a_rmask)
 
                        if (*tok >= KW_D0 && *tok <= KW_A7)
                                cnt = *tok++ & 15;
-                       else 
+                       else
                                return error("register list syntax");
 
                        if (cnt < r)
@@ -154,7 +154,7 @@ int reglist(WORD * a_rmask)
 
                        cnt -= r;
                }
-               else 
+               else
                        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
-// 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
 //
@@ -39,7 +39,7 @@
 #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)
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
-// 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
 //
@@ -43,8 +43,7 @@ TOKEN * printexpr(TOKEN * tp)
                        switch ((int)*tp++)
                        {
                        case SYMBOL:
-//                             printf("`%s' ", ((SYM *)*tp)->sname);
-                               printf("`%s' ", symbolPtr[*tp]->sname);
+                               printf("'%s' ", symbolPtr[*tp]->sname);
                                tp++;
                                break;
                        case CONST:
@@ -61,7 +60,6 @@ TOKEN * printexpr(TOKEN * tp)
                }
        }
 
-//     printf(";\n");
        return tp + 1;
 }
 
@@ -88,28 +86,24 @@ int chdump(CHUNK * ch, int format)
 int fudump(CHUNK * ch)
 {
        PTR p;
-       char * ep;
-       WORD attr, esiz;
-       WORD line, file;
-       LONG loc;
 
        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)
                {
-                       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)
                        {
-                               esiz = *p.wp++;
+                               uint16_t esiz = *p.wp++;
                                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;
-               
+
                for(;;)
                {
                        w = *p.wp++;
@@ -192,7 +186,7 @@ int mudump(void)
 // 0 - bytes
 // 1 - words
 // 2 - longwords
-// 
+//
 // 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("  ");
 
-                               while(j < i)
+                               while (j < i)
                                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);
-                       ++i;
+                       i++;
                        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];
 
-               while(k--)
+               while (k--)
                        putchar(' ');
 
                printf("  ");
 
-               while(j < i)
+               while (j < i)
                        visprt(start[j++]);
 
                putchar('\n');
@@ -291,34 +285,34 @@ int dumptok(TOKEN * tk)
                case STRING:                                       // STRING <address>
                        printf("STRING='%s'", string[*tk++]);
                        break;
-               case SYMBOL:                                       // SYMBOL <address> 
+               case SYMBOL:                                       // SYMBOL <address>
                        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;
-               case DEQUALS:                                      // == 
+               case DEQUALS:                                      // ==
                        printf("DEQUALS");
                        break;
-               case DCOLON:                                       // :: 
+               case DCOLON:                                       // ::
                        printf("DCOLON");
                        break;
-               case GE:                                           // >= 
+               case GE:                                           // >=
                        printf("GE");
                        break;
-               case LE:                                           // <= 
+               case LE:                                           // <=
                        printf("LE");
                        break;
-               case NE:                                           // <> or != 
+               case NE:                                           // <> or !=
                        printf("NE");
                        break;
-               case SHR:                                          // >> 
+               case SHR:                                          // >>
                        printf("SHR");
                        break;
-               case SHL:                                          // << 
+               case SHL:                                          // <<
                        printf("SHL");
                        break;
                default:
@@ -338,9 +332,7 @@ int dumptok(TOKEN * tk)
 //
 int dump_everything(void)
 {
-       int i;
-
-       for(i=1; i<NSECTS; i++)
+       for(int i=1; i<NSECTS; i++)
        {
                if (sect[i].scattr & SUSED)
                {
@@ -357,7 +349,7 @@ int dump_everything(void)
 
        printf("\nMarks:\n");
        mudump();                                                               // Dump marks
-//     printf("Total memory allocated=$%X\n", amemtot);
 
        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
-// 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
 //
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
-// 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
 //
@@ -77,8 +77,8 @@ int (*dirtab[])() = {
        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
@@ -141,7 +141,7 @@ int d_org(void)
 {
        VALUE address;
 
-       if (!rgpu && !rdsp) 
+       if (!rgpu && !rdsp)
                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);
 
-                       if (list_fd) 
+                       if (list_fd)
                                unused = write(list_fd, prntstr, (LONG)strlen(prntstr));
 
                        tok += 2;
@@ -222,9 +222,9 @@ int d_print(void)
                        {
                                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)
@@ -234,7 +234,7 @@ int d_print(void)
 
                                printf("%s", prntstr);
 
-                               if (list_fd) 
+                               if (list_fd)
                                        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)
@@ -420,7 +420,7 @@ allright:
 }
 
 
-// 
+//
 // 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;
-       
+
        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)
@@ -642,7 +642,7 @@ int d_include(void)
        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
        {
@@ -650,7 +650,7 @@ int d_include(void)
                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:
@@ -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
-       // 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 > 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);
@@ -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);
        }
-       else 
+       else
                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 (siz != SIZB && (sloc & 1))                            // Automatic .even 
+       if ((siz != SIZB) && (sloc & 1))        // Automatic .even
                auto_even();
 
        if (abs_expr(&eval) != OK)
@@ -865,7 +866,7 @@ int d_ds(WORD siz)
                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
        {
@@ -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;
-       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");
@@ -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");
 
-       for(;; ++tok)
+       for(;; tok++)
        {
                // 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);
 
-                       for(p=string[tok[1]]; *p!=EOS; ++p)
+                       for(p=string[tok[1]]; *p!=EOS; p++)
                                D_byte(*p);
 
                        tok += 2;
                        goto comma;
                }
 
-               if (*tok == 'I')
+               int movei = 0; // MOVEI flag for dc.i
+
+               if (*tok == DOTI)
                {
                        movei = 1;
                        tok++;
@@ -929,11 +928,13 @@ int d_dc(WORD siz)
                }
 
                // dc.x <expression>
-               if (expr(exprbuf, &eval, &eattr, NULL) != OK)
+               SYM * esym = 0;
+
+               if (expr(exprbuf, &eval, &eattr, &esym) != OK)
                        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);
@@ -948,15 +949,15 @@ int d_dc(WORD siz)
                        }
                        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 (tdb)
+                                       return error("non-absolute byte value");
+
                                D_byte(eval);
                        }
 
@@ -970,13 +971,13 @@ int d_dc(WORD siz)
                        }
                        else
                        {
-                               if (tdb)
-                                       rmark(cursect, sloc, tdb, MWORD, NULL);
-
                                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);
                        }
 
@@ -994,16 +995,16 @@ int d_dc(WORD siz)
                        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;
                }
-               
+
 comma:
                if (*tok != ',')
                        break;
@@ -1046,9 +1047,9 @@ int d_dcb(WORD siz)
 
 //
 // Generalized initialization directive
-// 
+//
 // .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
@@ -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;
-               default: 
+               default:
                        siz = def_siz;
-                       --tok;
+                       tok--;
                        break;
                }
 
@@ -1105,7 +1106,7 @@ int d_init(WORD def_siz)
                case EOL:
                        return 0;
                case ',':
-                       ++tok;
+                       tok++;
                        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)
-                                       rmark(cursect, sloc, tdb, MWORD, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                                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)
-                                       rmark(cursect, sloc, tdb, MLONG, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
                                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
-       orgactive = 0;                               
+       orgactive = 0;
        orgwarning = 0;
        SaveSection();
        SwitchSection(TEXT);
@@ -1325,12 +1326,12 @@ int d_dsp(void)
 
 //
 // .cargs [#offset], symbol[.size], ...
-// 
+//
 // Lists of registers may also be mentioned; they just take up space. Good for
 // "documentation" purposes:
-// 
+//
 // .cargs a6, .arg1, .arg2, .arg3...
-// 
+//
 // Symbols thus created are ABS and EQUATED.
 //
 int d_cargs(void)
@@ -1438,12 +1439,12 @@ int d_cargs(void)
 
 //
 // .cstruct [#offset], symbol[.size], ...
-// 
+//
 // Lists of registers may also be mentioned; they just take up space. Good for
 // "documentation" purposes:
-// 
+//
 // .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.
@@ -1576,7 +1577,6 @@ int undmac1(char * p)
        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;
 
@@ -1626,7 +1626,7 @@ int d_opt(void)
                        if (ParseOptimization(tmpstr) != OK)
                        {
                                char temperr[256];
-                               sprintf(temperr, "unknown optimisation flag '%s'", tmpstr);
+                               sprintf(temperr, "unknown optimization flag '%s'", tmpstr);
                                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
-// 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
 //
@@ -43,7 +43,7 @@ int ExitMacro(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 *);
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
-// 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
 //
@@ -21,6 +21,7 @@
 #define aNexpr    a0expr
 #define aNixreg   a0ixreg
 #define aNixsiz   a0ixsiz
+#define AnESYM    a0esym
 #include "eagen0.c"
 
 #define eaNgen    ea1gen
@@ -30,4 +31,5 @@
 #define aNexpr    a1expr
 #define aNixreg   a1ixreg
 #define aNixsiz   a1ixsiz
+#define AnESYM    a1esym
 #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")
-// 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)
 {
-       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)
        {
@@ -35,18 +31,16 @@ int eaNgen(WORD siz)
                // expr(An)
                if (w)
                {
-                       // Just deposit it 
+                       // Just deposit it
                        if (tdb)
-                               rmark(cursect, sloc, tdb, MWORD, NULL);
+                               MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                        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
@@ -56,9 +50,8 @@ int eaNgen(WORD siz)
                                }
                                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
@@ -79,8 +72,8 @@ int eaNgen(WORD siz)
                }
                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);
                }
 
@@ -88,7 +81,7 @@ int eaNgen(WORD siz)
        case PCDISP:
                if (w)
                {
-                       // Just deposit it 
+                       // Just deposit it
                        if ((aNexattr & TDB) == cursect)
                                v -= (VALUE)sloc;
                        else if ((aNexattr & TDB) != ABS)
@@ -101,8 +94,8 @@ int eaNgen(WORD siz)
                }
                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);
                }
 
@@ -113,21 +106,21 @@ int eaNgen(WORD siz)
 
                if (aNexattr & DEFINED)
                {
-                       // Deposit a byte... 
+                       // Deposit a byte...
                        if (tdb)
-                               // Can't mark bytes 
+                               // Can't mark bytes
                                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
-                       AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
+                       AddFixup(FU_BYTE | FU_SEXT, sloc + 1, aNexpr);
                        D_word(w);
                }
 
@@ -138,8 +131,8 @@ int eaNgen(WORD siz)
 
                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);
@@ -152,8 +145,8 @@ int eaNgen(WORD siz)
                }
                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);
                }
 
@@ -174,7 +167,7 @@ int eaNgen(WORD siz)
                        }
                        else
                        {
-                               AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
+                               AddFixup(FU_BYTE | FU_SEXT, sloc + 1, aNexpr);
                                D_word(0);
                        }
 
@@ -183,17 +176,17 @@ int eaNgen(WORD siz)
                case SIZN:
                        if (w)
                        {
-                               if (tdb)
-                                       rmark(cursect, sloc, tdb, MWORD, NULL);
-
                                if (v + 0x10000 >= 0x20000)
                                        return error(range_error);
 
+                               if (tdb)
+                                       MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
+
                                D_word(v);
                        }
                        else
                        {
-                               AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+                               AddFixup(FU_WORD | FU_SEXT, sloc, aNexpr);
                                D_word(0);
                        }
 
@@ -202,7 +195,7 @@ int eaNgen(WORD siz)
                        if (w)
                        {
                                if (tdb)
-                                       rmark(cursect, sloc, tdb, MLONG, NULL);
+                                       MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
                                D_long(v);
                        }
@@ -220,10 +213,10 @@ int eaNgen(WORD siz)
 
                break;
        case ABSW:
-               if (w)
+               if (w) // Defined
                {
                        if (tdb)
-                               rmark(cursect, sloc, tdb, MWORD, NULL);
+                               MarkRelocatable(cursect, sloc, tdb, MWORD, NULL);
 
                        if (v + 0x8000 >= 0x10000)
                                return error(range_error);
@@ -232,16 +225,16 @@ int eaNgen(WORD siz)
                }
                else
                {
-                       AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+                       AddFixup(FU_WORD | FU_SEXT, sloc, aNexpr);
                        D_word(0);
                }
 
                break;
        case ABSL:
-               if (w)
+               if (w) // Defined
                {
                        if (tdb)
-                               rmark(cursect, sloc, tdb, MLONG, NULL);
+                               MarkRelocatable(cursect, sloc, tdb, MLONG, NULL);
 
                        D_long(v);
                }
@@ -260,7 +253,7 @@ int eaNgen(WORD siz)
        case PCMPRE:
                return error("unsupported 68020 addressing mode");
        default:
-               // Bad addressing mode in ea gen 
+               // Bad addressing mode in ea gen
                interror(3);
        }
 
@@ -275,4 +268,5 @@ int eaNgen(WORD siz)
 #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
-// 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
 //
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
-// 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
 //
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
-// 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
 //
@@ -17,7 +17,7 @@
 #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
@@ -29,22 +29,22 @@ static WORD evattr[EVSTACKSIZE];    // Evaluator attribute stack
 // Token-class initialization list
 char itokcl[] = {
        0,                                                              // END
-       CONST, SYMBOL, 0,                               // ID 
+       CONST, SYMBOL, 0,                               // ID
        '(', '[', '{', 0,                               // OPAR
-       ')', ']', '}', 0,                               // CPAR 
+       ')', ']', '}', 0,                               // CPAR
        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
-       '*', '/', '%', 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";
@@ -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)
-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++;
-               else 
+               else
                        tokenClass[(int)(*p)] = (char)i;
        }
 
@@ -105,7 +105,7 @@ int expr0(void)
 
        if (expr1() != OK)
                return ERROR;
-       
+
        while (tokenClass[*tok] >= MULT)
        {
                t = *tok++;
@@ -211,7 +211,7 @@ getsym:
                        break;
                }
        }
-       else 
+       else
                return expr2();
 
        return OK;
@@ -244,7 +244,7 @@ int expr2(void)
                // 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)
@@ -395,7 +395,7 @@ if (symbol)
                        // 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)
@@ -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?
 */
-                       if (symbol->sattre & EQUATEDREG) 
+                       if (symbol->sattre & EQUATEDREG)
                                *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++];
-                       sy->sattr |= REFERENCED;                // Set "referenced" bit 
+                       sy->sattr |= REFERENCED;                // Set "referenced" bit
 
                        if (!(sy->sattr & DEFINED))
                        {
@@ -508,7 +508,7 @@ int evexpr(TOKEN * tk, VALUE * a_value, WORD * a_attr, SYM ** a_esym)
                        }
                        else
                        {
-                               *++sval = 0;                            // 0 for undefined symbols 
+                               *++sval = 0;                            // 0 for undefined symbols
                        }
 
                        *++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:
-                       // 
+                       //
                        //                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
-                       --sattr;                                                // Pop attrib 
+                       --sattr;                                                // Pop attrib
 //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
-                       --sattr;                                                // Pop attrib 
+                       --sattr;                                                // Pop attrib
 //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");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        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");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        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");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        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");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        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");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        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");
-                       --sattr;
-                       --sval;
+                       sattr--;
+                       sval--;
 
                        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 '*':
-                               --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 '/':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
 
                                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 '%':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
 
                                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;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval <<= sval[1];
                                break;
                        case SHR:
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval >>= sval[1];
                                break;
                        case '&':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval &= sval[1];
                                break;
                        case '^':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *sval ^= sval[1];
                                break;
                        case '|':
-                               --sval;
-                               --sattr;                                        // Pop attrib 
+                               sval--;
+                               sattr--;                                        // Pop attrib
                                *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
-// 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
 //
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
-// 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
 //
@@ -421,3 +421,4 @@ void panic(char * s)
        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
-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
-LONG lsloc;                                                    // `sloc' at start of line 
+LONG lsloc;                                                    // `sloc' 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 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
@@ -80,7 +80,7 @@ VALUE dos_date(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)
@@ -176,7 +176,7 @@ void list_setup(void)
        }
 
        list_fname = NULL;
-       
+
        if ((list_fd = open(fnbuf, _OPEN_FLAGS, _PERM_MODE)) < 0)
                cantcreat(fnbuf);
 }
@@ -348,13 +348,13 @@ nochunk:
                                strcpy(buf, "xx");
                                p++;            // Advance anyway
                        }
-                       else 
+                       else
                                sprintf(buf, "%02x", *p++ & 0xff);
 
                        strncpy(lnimage + col, buf, 2);
                }
 
-               // Flush partial line 
+               // Flush partial line
                if (col > DATA_COL)
                {
                        uc_ln(lnimage);
@@ -441,7 +441,7 @@ int d_subttl(void)
 
        tok += 2;
 
-       // Always eject on pages 2+ 
+       // Always eject on pages 2+
        if (ejectok && (subflag || pageno > 1))
                eject();
 
@@ -459,7 +459,7 @@ int d_title(void)
 {
        if (*tok != STRING)
                return error("missing string");
-       
+
 //     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
-// 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
 //
@@ -31,6 +31,7 @@ extern LONG lsloc;
 
 // Prototypes
 void InitListing(void);
+int eject(void);
 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
-// 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
 //
@@ -19,7 +19,7 @@
 #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);
@@ -59,8 +59,8 @@ extern int ea1gen(WORD);
 
 // 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
 };
@@ -72,18 +72,18 @@ WORD reg_9[8] = {
 
 // SIZB==>00, SIZW==>01, SIZL==>10, SIZN==>01 << 6
 WORD siz_6[] = {
-       (WORD)-1,                                        // n/a 
+       (WORD)-1,                                        // n/a
        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,
-   0x1000,                                           // Byte 
-   0x3000, (WORD)-1,                                 // Word 
+   0x1000,                                           // Byte
+   0x3000, (WORD)-1,                                 // Word
    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
-// 
+//
 // 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.
-// 
+//
 // 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 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)
        {
-               // OR-in register number 
+               // OR-in register number
                if (flg & 8)
-                       inst |= reg_9[a1reg];           // ea1reg in bits 9..11 
+                       inst |= reg_9[a1reg];           // ea1reg in bits 9..11
                else
-                       inst |= reg_9[a0reg];           // ea0reg in bits 9..11 
+                       inst |= reg_9[a0reg];           // ea0reg in bits 9..11
        }
 
        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);
 
-               ea1gen(siz);                                    // Generate ea1 
+               ea1gen(siz);                                    // Generate ea1
        }
        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);
        }
@@ -202,7 +202,7 @@ int m_abcd(WORD inst, WORD siz)
 {
        if (inst & 1)
        {
-               // Install size bits 
+               // Install size bits
                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);
-       ea0gen(siz);    // Generate EA 
+       ea0gen(siz);    // Generate EA
 
        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.
-// 
+//
 int m_reg(WORD inst, WORD siz)
 {
        if (inst & 1)
-               // Install size bits 
+               // Install size bits
                inst |= siz_6[siz];
 
        if (inst & 2)
-               // Install other register (9..11) 
+               // Install other register (9..11)
                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;
@@ -318,11 +318,11 @@ int m_bitop(WORD inst, WORD siz)
 {
        // 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);
        }
-       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
@@ -331,7 +331,7 @@ int m_bitop(WORD inst, WORD siz)
        if (am0 == IMMED)
        {
                D_word(inst);
-               ea0gen(SIZB);                           // Immediate bit number 
+               ea0gen(SIZB);                           // Immediate bit number
        }
        else
        {
@@ -339,7 +339,7 @@ int m_bitop(WORD inst, WORD siz)
                D_word(inst);
        }
 
-       // ea to bit-munch 
+       // ea to bit-munch
        ea1gen(SIZB);
 
        return 0;
@@ -386,14 +386,14 @@ int m_exg(WORD inst, WORD siz)
        siz = siz;
 
        if (am0 == DREG && am1 == DREG)
-               m = 0x0040;                                           // Dn,Dn 
+               m = 0x0040;                                           // Dn,Dn
        else if (am0 == AREG && am1 == AREG)
-               m = 0x0048;                                           // An,An 
+               m = 0x0048;                                           // An,An
        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;
                }
@@ -425,7 +425,7 @@ int m_link(WORD inst, WORD siz)
 //
 // 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)
@@ -467,9 +467,9 @@ int m_usp(WORD inst, WORD siz)
        siz = siz;
 
        if (am0 == AM_USP)
-               inst |= a1reg;          // USP, An 
+               inst |= a1reg;          // USP, An
        else
-               inst |= a0reg;          // An, USP 
+               inst |= a0reg;          // An, USP
 
        D_word(inst);
 
@@ -484,11 +484,11 @@ int m_moveq(WORD inst, WORD siz)
 {
        siz = siz;
 
-       // Arrange for future fixup 
+       // Arrange for future fixup
        if (!(a0exattr & DEFINED))
        {
                AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
-               a0exval = 0; 
+               a0exval = 0;
        }
        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)
-               else 
+               else
                        ea1gen(siz);
        }
        else
@@ -525,7 +525,7 @@ int m_movep(WORD inst, WORD siz)
 
                if (am0 == AIND)
                        D_word(0)
-               else 
+               else
                        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)
                        {
-                               // Fits in .B 
+                               // Fits in .B
                                inst |= v & 0xFF;
                                D_word(inst);
                                if (sbra_flag)
@@ -564,7 +564,7 @@ int m_br(WORD inst, WORD siz)
                        }
                        else
                        {
-                               // Fits in .W 
+                               // Fits in .W
                                if (v + 0x8000 > 0x10000)
                                        return error(range_error);
 
@@ -598,14 +598,14 @@ int m_br(WORD inst, WORD siz)
 
        if (siz == SIZB)
        {
-               // .B 
+               // .B
                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);
@@ -624,7 +624,7 @@ int m_addq(WORD inst, WORD siz)
 
        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;
@@ -660,7 +660,7 @@ int m_trap(WORD inst, WORD siz)
                inst |= a0exval;
                D_word(inst);
        }
-       else 
+       else
                return error(undef_error);
 
        return 0;
@@ -685,7 +685,7 @@ int m_movem(WORD inst, WORD siz)
 
        if (*tok == '#')
        {
-               // Handle #<expr>, ea 
+               // Handle #<expr>, ea
                tok++;
 
                if (abs_expr(&eval) != OK)
@@ -700,7 +700,7 @@ int m_movem(WORD inst, WORD siz)
 
        if (*tok >= KW_D0 && *tok <= KW_A7)
        {
-               // <rlist>, ea 
+               // <rlist>, ea
                if (reglist(&rmask) < 0)
                        return 0;
 
@@ -728,7 +728,7 @@ immed1:
        }
        else
        {
-               // ea, <rlist> 
+               // ea, <rlist>
                if (amode(0) < 0)
                        return 0;
 
@@ -742,7 +742,7 @@ immed1:
 
                if (*tok == '#')
                {
-                       // ea, #<expr> 
+                       // ea, #<expr>
                        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
-// 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
 //
@@ -12,7 +12,7 @@
 #include "rmac.h"
 #include "amode.h"
 
-// Globals, Externals etc
+// Exported variables
 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__
+
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
-// 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 "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 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;
-               return 1;                                                       // Keep looking 
+               return 1;                                                       // Keep looking
 #else
                if (curmac->lineList == NULL)
                {
@@ -239,11 +237,11 @@ int defr1(char * ln, int kwno)
 
        switch (kwno)
        {
-       case 0:                                                                         // .endr 
+       case 0:                                                                         // .endr
                if (--rptlevel == 0)
                return(0);
                goto addln;
-       case 1:                                                                         // .rept 
+       case 1:                                                                         // .rept
                rptlevel++;
        default:
 //MORE stupidity here...
@@ -256,7 +254,7 @@ WARNING(!!! Casting (char *) as LONG !!!)
                *p = 0;
 
                strcpy((char *)(p + 1), ln);
-               
+
                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)
-// 
+//
 // `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.
-// 
+//
 // `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)
-               lnsave++;                                                               // Tell tokenizer to keep lines 
+               lnsave++;                                                               // Tell tokenizer to keep lines
 
        for(;;)
        {
@@ -359,7 +357,7 @@ int lncatch(int (* lnfunc)(), char * dirlist)
 
                if (p != NULL)
                {
-                       if (*p == '.')                                          // ignore leading '.'s 
+                       if (*p == '.')                                          // ignore leading '.'s
                                p++;
 
                        k = kwmatch(p, dirlist);
@@ -438,7 +436,7 @@ int InvokeMacro(SYM * mac, WORD siz)
 //     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;
@@ -447,7 +445,6 @@ int InvokeMacro(SYM * mac, WORD siz)
        TOKEN * dest;
        int stringNum = 0;
        int argumentNum = 0;
-//     int i;
 
        for(dry_run=1; ; dry_run--)
        {
@@ -457,7 +454,7 @@ int InvokeMacro(SYM * mac, WORD siz)
                                nargs++;
                        else
                        {
-#if 0                          
+#if 0
                                *argptr++ = p;
 #else
                                argPtrs[argp++] = p;
@@ -569,7 +566,7 @@ streams, we can alleviate this problem.]
 //                     argp += nargs;
 #endif
                }
-               else 
+               else
                        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
-// 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
 //
index cd52ffe9bc983b00ec0018d1be59cb0a7567b3ae..8eef37062297f6be65a12b0155d7e0ade3b5e80e 100644 (file)
--- a/makefile
+++ b/makefile
@@ -8,7 +8,7 @@ rm = /bin/rm -f
 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 
 
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 "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
-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
-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
 
@@ -36,6 +42,7 @@ void InitMark(void)
        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
-               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
-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)
-               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;
 
        //
-       //  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)
        {
@@ -86,18 +100,19 @@ if (symbol)
 
                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;
+       mcused += sizeof(uint16_t) + sizeof(uint32_t);
 
        if (flags & MCHFROM)
        {
-               curfrom = from;
-               *markptr.wp++ = from;
-               mcused += sizeof(WORD);
+               curfrom = section;
+               *markptr.wp++ = section;
+               mcused += sizeof(uint16_t);
        }
 
        if (flags & MSYMBOL)
@@ -106,6 +121,11 @@ if (symbol)
                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;
@@ -115,29 +135,28 @@ if (symbol)
 //
 // 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.
-//     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->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)
        {
-               // 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;
        }
 
-       if (!firstmch)
-               firstmch = p;
-
-       curmch = p;                                             // Setup global vars 
+       // Setup global vars
+       curmch = p;
        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)
-               //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;
 
-                       /*
-                        *  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++;
 
-                       if (w & MSYMBOL)        /* maybe includes a symbol */
+                       if (w & MSYMBOL)        // maybe includes a symbol
                                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;
 
-                       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;
@@ -220,15 +214,13 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
 
                        if (symbol)
                        {
-                               /*
-                                *  Deposit external reference
-                                */
+                               // Deposit external reference
                                if (okflag)
                                {
                                        if (w & MPCREL)
-                                               w = 6;          /* pc-relative fixup */
+                                               w = 6;          // PC-relative fixup
                                        else
-                                               w = 4;          /* absolute fixup */
+                                               w = 4;          // Absolute fixup
 
                                        w |= symbol->senv << 3;
                                        *wp++ = w >> 8;
@@ -237,27 +229,19 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                        }
                        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)))
                                {
-                                       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
@@ -266,11 +250,7 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                                        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
@@ -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)
        {
-               firstp = 1;
-               wp = mp;
-               dp = mp;
+               int firstp = 1;
+               wp = dp = mp;
 
                for(loc=0; loc<siz;)
                {
@@ -295,44 +272,40 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
                        {
                                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
                                {
-                                       for(diff=loc-lastloc; diff>254; diff-= 254)
+                                       uint32_t diff;
+
+                                       for(diff=loc-lastloc; diff>254; diff-=254)
                                                *dp++ = 1;
 
-                                       *dp++ = (char)diff;
+                                       *dp++ = (uint8_t)diff;
                                }
 
-                               wp += 4;
                                lastloc = loc;
                                loc += 4;
+                               wp += 4;
                        }
-                       else 
+                       else
                        {
                                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;
-               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;
        }
@@ -344,211 +317,230 @@ LONG markimg(register char * mp, LONG siz, LONG tsize, int okflag)
 //
 // 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
-printf("bsdmarkimg():\n");
+printf("MarkBSDImage():\n");
 #endif
-       // Initialise relocation size
-       rsize = 0;
+       // Initialize relocation table point (for D_foo macros)
        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)
-                               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)
                        {
-                               // Maybe change "from" section
                                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++;
 
-                       if (obj_format == BSD)
-                       {
-                               raddr = loc;                    // Set relocation address
+                       if (!validsegment)
+                               continue;
 
-                               if (validsegment)
 #ifdef DEBUG_IMAGE_MARKING
-{
 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
-                               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
-                                               D_long(rflag);                          // Write relocation flags
-                                               rsize += 8;                                     // Increment relocation size
-                                       }
-                               }
                        }
                        else
                        {
-                               if (obj_format == BSD)
-                               {
 #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
-                                               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
-       
-                                                       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
-                                               }
-                                       }
                                }
                        }
+
+                       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
-{
 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
-// 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
 //
 #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);
-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__
 
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
-// 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"
-#include "sect.h"
-#include "symbol.h"
-#include "mark.h"
 #include "error.h"
-#include "riscasm.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
 //
-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
 
-       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)
-       {                                       
+       {
                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 = 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
 
-       if (w1 & BSS) 
+       if (w1 & BSS)
                z += sect[DATA].sloc;                   // If BSS add DATA segment size
 
        D_long(z);                                                      // Deposit symbol value
-
        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
@@ -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)
        {
-               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)
        {
-               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)
-       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
@@ -230,7 +298,7 @@ int WriteObject(int fd)
        // 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)
@@ -238,7 +306,7 @@ int WriteObject(int fd)
                        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
 
@@ -248,9 +316,9 @@ int WriteObject(int fd)
                        return ERROR;
                }
 
-               memset(buf, 0, 0x600000);               // Reset allocated memory
+               memset(buf, 0, 0x600000);               // Clear allocated memory
                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)
                {
@@ -258,23 +326,23 @@ int WriteObject(int fd)
                        return ERROR;
                }
 
-               memset(strtable, 0, 0x200000);  // Reset allocated memory
+               memset(strtable, 0, 0x200000);  // Clear allocated memory
 
                // 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(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);                             // BSD relocation size
+               D_long(0x00000000);                             // DATA relocation size
 
                // 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)
                        {
@@ -284,40 +352,46 @@ int WriteObject(int fd)
                }
 
                // 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
-               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
 
-               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
-               p = buf + (BSDHDRSIZE + tds + trsize + drsize + symsize);    
-
+               p = buf + BSDHDRSIZE + tds + trsize + drsize + symsize;
                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);
 
+               if (verb_flag)
+               {
+                       printf("TextRel size: %d bytes\n", trsize);
+                       printf("DataRel size: %d bytes\n", drsize);
+               }
+
                if (buf)
+               {
+                       free(strtable);                         // Free allocated memory
                        free(buf);                                      // Free allocated memory
-
-    }
-    else if (obj_format==ALCYON)
-    {
+               }
+       }
+       else if (obj_format == ALCYON)
+       {
                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);
                        }
                }
-               /*
-                *  Compute size of symbol table;
-                *   assign numbers to the symbols...
-                */
+
+               // Compute size of symbol table; assign numbers to the symbols...
                ssize = 0;
 
+               // As we grabbed BSD *and* Alcyon in prg_flag == 0 mode, this is *always*
+               // false... :-P
                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;
 
-               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++)
                {
-                       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;
                        }
                }
 
+               // Do a first pass on the Alcyon image, if in PRG mode
                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)
                {
-                       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;
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
-// 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
 //
@@ -9,11 +9,34 @@
 #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
+
+//
+// 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
+
+enum ELFSectionNames
+{
+       ES_NULL, ES_TEXT, ES_DATA, ES_BSS, ES_RELATEXT, ES_RELADATA, ES_SHSTRTAB,
+       ES_SYMTAB, ES_STRTAB
+};
+
+// Exported variables.
+extern uint8_t * objImage;
+extern int elfHdrNum[];
+extern uint32_t extraSyms;
 
 // Exported functions
 int WriteObject(int);
index c003523f322f9aa49c6e0f3858b1c37b833ffe55..5518343c04878f487f01e701a3bdb0cf774905ff 100644 (file)
--- a/parmode.h
+++ b/parmode.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // PARMODE.C - Addressing Modes Parser Include
-// 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
 //
@@ -75,7 +75,7 @@
                        goto AMn_IX0;            // Handle ",Xn[.siz][*scale])"
                }
                else if (*tok == KW_PC)
-               {                            // (PC,Xn[.siz][*scale]) 
+               {                            // (PC,Xn[.siz][*scale])
                        tok++;
                        AMn = PCINDEXED;
 
@@ -98,7 +98,7 @@
                        AnIXREG = *tok++ & 15;
 
                        switch ((int)*tok)
-                       {                        // Index reg size: <empty> | .W | .L 
+                       {                        // Index reg size: <empty> | .W | .L
                        case DOTW:
                                tok++;
                        default:
                        }
 
                        if (*tok == '*')
-                       {                        // scale: *1, *2, *4, *8 
+                       {                        // scale: *1, *2, *4, *8
                                tok++;
 
                                if (*tok++ != CONST || *tok > 8)
                                }
                        }
 
-                       if (*tok++ != ')')         // final ")" 
+                       if (*tok++ != ')')         // final ")"
                                goto badmode;
 
                        goto AnOK;
                }
                else if (*tok == '[')
-               {                              // ([... 
+               {                              // ([...
                        goto unmode;
                }
                else
-               {                              // (expr... 
+               {                              // (expr...
                        if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
                                return ERROR;
 
                                }
                                else if (*tok == ')')
                                {
-                                       AMn = PCDISP;             // expr(PC) 
+                                       AMn = PCDISP;             // expr(PC)
                                        tok++;
                                        goto AnOK;
                                }
 CHK_FOR_DISPn:
                if (*tok == DOTW)
                {
-                       // expr.W 
+                       // expr.W
                        tok++;
                        AMn = ABSW;
 
index 2cd1bdc3d513b6b7476d33cea3c59b0e09f8b357..dd8980622be2eb42d4f4ebd7e3dd75ab3572c9f7 100644 (file)
--- a/procln.c
+++ b/procln.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // PROCLN.C - Line Processing
-// 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
 //
@@ -18,7 +18,7 @@
 #include "symbol.h"
 #include "riscasm.h"
 
-#define DEF_KW                                 // Declare keyword values 
+#define DEF_KW                                 // Declare keyword values
 #include "kwtab.h"                             // Incl generated keyword tables & defs
 
 #define DEF_MN                                 // Incl 68k keyword definitions
@@ -34,8 +34,8 @@ IFENT * ifent;                                        // Current ifent
 static IFENT ifent0;                   // Root ifent
 static IFENT * f_ifent;                        // Freelist of ifents
 static int disabled;                   // Assembly conditionally disabled
-int just_bss;                                  // 1, ds.b in microprocessor mode 
-VALUE pcloc;                                   // Value of "PC" at beginning of line 
+int just_bss;                                  // 1, ds.b in microprocessor mode
+VALUE pcloc;                                   // Value of "PC" at beginning of line
 SYM * lab_sym;                                 // Label on line (or NULL)
 
 const char extra_stuff[] = "extra (unexpected) text found after addressing mode";
@@ -76,15 +76,15 @@ LONG amsktab[0112] = {
        0L,                                                                                             // 076
        0L,                                                                                             // 077
        M_ABASE,                                                                                // 0100
-       M_MEMPOST,                                                                              // 0101 
-       M_MEMPRE,                                                                               // 0102 
+       M_MEMPOST,                                                                              // 0101
+       M_MEMPRE,                                                                               // 0102
        M_PCBASE,                                                                               // 0103
        M_PCMPOST,                                                                              // 0104
        M_PCMPRE,                                                                               // 0105
        M_AM_USP,                                                                               // 0106
-       M_AM_SR,                                                                                // 0107 
+       M_AM_SR,                                                                                // 0107
        M_AM_CCR,                                                                               // 0110
-       M_AM_NONE                                                                               // 0111 
+       M_AM_NONE                                                                               // 0111
 };                                                                                                     // 0112 length
 
 
@@ -251,7 +251,7 @@ as68label:
        // Check for ".b" ".w" ".l" after directive, macro or mnemonic.
        siz = SIZN;
 
-       if (*tok == DOTW) 
+       if (*tok == DOTW)
                siz = SIZW, tok++;
        else if (*tok == DOTL)
                siz = SIZL, tok++;
@@ -368,8 +368,8 @@ normal:
                {
                        if ((equtyp == EQUREG) && (sy->sattre & UNDEF_EQUR))
                        {
-//REALLY?                              sy->sattre |= ~UNDEF_EQUR; 
-                               sy->sattre &= ~UNDEF_EQUR; 
+//REALLY?                              sy->sattre |= ~UNDEF_EQUR;
+                               sy->sattre &= ~UNDEF_EQUR;
                                sy->svalue = 0;
                        }
                        else if ((equtyp == CCDEF) && (sy->sattre & UNDEF_CC))
@@ -602,7 +602,7 @@ When checking to see if it's already been equated, issue a warning.
        // Invoke macro or complain about bad mnemonic
        if (state < 0)
        {
-               if ((sy = lookup(opname, MACRO, 0)) != NULL) 
+               if ((sy = lookup(opname, MACRO, 0)) != NULL)
                        InvokeMacro(sy, siz);
                else
                        errors("unknown op '%s'", opname);
@@ -727,7 +727,7 @@ int HandleLabel(char * label, int labelType)
 }
 
 
-// 
+//
 // .if, Start conditional assembly
 //
 int d_if(void)
@@ -762,7 +762,7 @@ int d_if(void)
 }
 
 
-// 
+//
 // .else, Do alternate case for .if
 //
 int d_else(void)
index 4a64dbd7912f9d872ac3630599b09b5284f2700e..c645722702ba6350b0163f6512489cd557ca1987 100644 (file)
--- a/procln.h
+++ b/procln.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // PROCLN.H - Line Processing
-// 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
 //
index 9d95bfc9920676f1c06c5e334c1dd1affe5d570f..2c291ffe9daad4b687f938dc35509312c044771b 100644 (file)
--- a/riscasm.c
+++ b/riscasm.c
@@ -385,12 +385,13 @@ int GenerateRISCCode(int state)
                {
                        if (eattr & TDB)
 //{
-//printf("RISCASM: Doing rmark for RI_MOVEI (tdb=$%X)...\n", eattr & TDB);
-                               rmark(cursect, sloc + 2, (eattr & TDB), (MLONG | MMOVEI), NULL);
+//printf("RISCASM: Doing MarkRelocatable for RI_MOVEI (tdb=$%X)...\n", eattr & TDB);
+                               MarkRelocatable(cursect, sloc + 2, (eattr & TDB), (MLONG | MMOVEI), NULL);
 //}
                }
 
-               val = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
+//             val = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
+               val = WORDSWAP32(eval);
                CHECK_COMMA;
                reg2 = GetRegister(FU_REGTWO);
                at_eol();
index a91f703fb7ce5f369cfc4bfc27c6f7137731e8b7..96623e62d67352fb7c38b4b049966f2f31083f8d 100644 (file)
--- a/riscasm.h
+++ b/riscasm.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // RISCA.H - GPU/DSP Assembler
-// 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
 //
diff --git a/rmac.c b/rmac.c
index 5745d5274e82a1b35a2d66a846c4aae5337b96e8..5842792087b00ada698fb54eaf5ecdccfed04b9d 100644 (file)
--- a/rmac.c
+++ b/rmac.c
@@ -39,11 +39,11 @@ int rgpu, rdsp;                                     // Assembling Jaguar GPU or DSP code
 int list_fd;                                   // File to write listing to
 int regbank;                                   // RISC register bank
 int segpadsize;                                        // Segment padding size
-int endian;                                            // Host processor endianess
+int endian;                                            // Host processor endianess (0 = LE, 1 = BE)
 char * objfname;                               // Object filename pointer
 char * firstfname;                             // First source filename
 char * cmdlnexec;                              // Executable name, pointer to ARGV[0]
-char * searchpath;                             // Search path for include files 
+char * searchpath;                             // Search path for include files
 char defname[] = "noname.o";   // Default output filename
 int optim_flags[OPT_COUNT];    // Specific optimisations on/off matrix
 
@@ -128,6 +128,7 @@ void DisplayHelp(void)
                "  -f[format]        Output object file format\n"
                "                    a: ALCYON (use this for ST)\n"
                "                    b: BSD (use this for Jaguar)\n"
+               "                    e: ELF\n"
                "  -i[path]          Directory to search for include files\n"
                "  -l[filename]      Create an output listing file\n"
                "  -n                Don't do things behind your back in RISC assembler\n"
@@ -209,7 +210,7 @@ int ParseOptimization(char * optstring)
 }
 
 
-// 
+//
 // Process command line arguments and do an assembly
 //
 int Process(int argc, char ** argv)
@@ -304,10 +305,14 @@ int Process(int argc, char ** argv)
                                case 'A':
                                        obj_format = ALCYON;
                                        break;
-                               case 'b':                       // -fb = BSD (Jaguar Recommended)
+                               case 'b':                       // -fb = BSD (Jaguar Recommended: 3 out 4 jaguars recommend it!)
                                case 'B':
                                        obj_format = BSD;
                                        break;
+                               case 'e':                       // -fe = ELF
+                               case 'E':
+                                       obj_format = ELF;
+                                       break;
                                default:
                                        printf("-f: unknown object format specified\n");
                                        errcnt++;
@@ -585,9 +590,9 @@ int main(int argc, char ** argv)
        // Set legacy optimisation flags to on
        // and everything else to off
        memset(optim_flags, 0, OPT_COUNT * sizeof(int));
-       optim_flags[OPT_ABS_SHORT] = 
+       optim_flags[OPT_ABS_SHORT] =
                optim_flags[OPT_MOVEL_MOVEQ] =
-               optim_flags[OPT_BSR_BCC_S] = 1;  
+               optim_flags[OPT_BSR_BCC_S] = 1;
 
        cmdlnexec = argv[0];                    // Obtain executable name
 
diff --git a/rmac.h b/rmac.h
index 4a4e8b92b97c7b6ed6bd205ec6e773fdfeae753d..f81b9a94290a11daf4f652d97ac05a3df413b510 100644 (file)
--- a/rmac.h
+++ b/rmac.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // RMAC.H - Main Application Code
-// Copyright (C) 199x Landon Dyer, 2011 Reboot & Friends
+// Copyright (C) 199x Landon Dyer, 2017 Reboot & Friends
 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
 // Source utilised with the kind permission of Landon Dyer
 //
@@ -26,7 +26,7 @@
        #define PLATFORM        "Win32"
        #define _OPEN_FLAGS     _O_TRUNC|_O_CREAT|_O_BINARY|_O_RDWR
        #define _OPEN_INC       _O_RDONLY|_O_BINARY
-       #define _PERM_MODE      _S_IREAD|_S_IWRITE 
+       #define _PERM_MODE      _S_IREAD|_S_IWRITE
        #ifdef _MSC_VER
                #if _MSC_VER > 1000
                        #pragma warning(disable:4996)
@@ -36,6 +36,7 @@
        #define STRINGIZE_HELPER(x) #x
        #define STRINGIZE(x) STRINGIZE_HELPER(x)
        #define WARNING(desc) __pragma(message(__FILE__ "(" STRINGIZE(__LINE__) ") : Warning: " #desc))
+       #define inline __inline
 
        // usage:
        // WARNING(FIXME: Code removed because...)
        // for the fireworks!
        #define DO_PRAGMA(x) _Pragma (#x)
        #define WARNING(desc) DO_PRAGMA(message (#desc))
-       #define inline __inline
 
        #endif
 
-#else 
+#else
+
        #ifdef __GCCUNIX__
+       #ifdef __MINGW32__
+       #define off64_t long
+       #define off_t long
+       #endif
+
        #include <sys/fcntl.h>
        #include <unistd.h>
-       // Release platform - mac OS-X or linux
+       // Release platform - mac OS-X or Linux
        #define PLATFORM        "OSX/Linux"
        #define _OPEN_FLAGS     O_TRUNC|O_CREAT|O_RDWR
        #define _OPEN_INC       O_RDONLY
@@ -65,7 +71,7 @@
        #define DO_PRAGMA(x) _Pragma (#x)
        #define WARNING(desc) DO_PRAGMA(message (#desc))
 #else
-       // Release platform - not specified 
+       // Release platform - not specified
        #include <sys/fcntl.h>
        #define PLATFORM        "Unknown"
        #define _OPEN_FLAGS     O_TRUNC|O_CREAT|O_RDWR
        #endif
 #endif
 
+//
+// Endian related, for safe handling of endian-sensitive data
+// USAGE: GETBExx() is *always* an rvalue, a = pointer to a uint8_t,
+//        r = offset from 0. SETBExx(), v = value to write into 'a'
+//
+#define GETBE16(a, r) \
+       (((uint16_t)(a)[(r + 0)] << 8) | ((uint16_t)(a)[(r + 1)]))
+
+#define GETBE32(a, r) \
+       (((uint32_t)(a)[(r + 0)] << 24) | ((uint32_t)(a)[(r + 1)] << 16) \
+       | ((uint32_t)(a)[(r + 2)] << 8) | ((uint32_t)(a)[(r + 3)]))
+
+#define GETBE64(a, r) \
+       (((uint64_t)(a)[(r + 0)] << 56) | ((uint64_t)(a)[(r + 1)] << 48) \
+       | ((uint64_t)(a)[(r + 2)] << 40) | ((uint64_t)(a)[(r + 3)] << 32) \
+       | ((uint64_t)(a)[(r + 4)] << 24) | ((uint64_t)(a)[(r + 5)] << 16) \
+       | ((uint64_t)(a)[(r + 6)] << 8) | ((uint64_t)(a)[(r + 7)]))
+
+#define SETBE16(a, r, v) \
+       { (a)[(r + 0)] = (uint8_t)((v) >> 8); \
+       (a)[(r + 1)] = (uint8_t)((v) & 0xFF); }
+
+#define SETBE32(a, r, v) \
+       { (a)[(r + 0)] = (uint8_t)((v) >> 24); \
+       (a)[(r + 1)] = (uint8_t)(((v) >> 16) & 0xFF); \
+       (a)[(r + 2)] = (uint8_t)(((v) >> 8) & 0xFF); \
+       (a)[(r + 3)] = (uint8_t)((v) & 0xFF); }
+
+#define SETBE64(a, r, v) \
+       { (a)[(r + 0)] = (uint8_t)((v) >> 56); \
+       (a)[(r + 1)] = (uint8_t)(((v) >> 48) & 0xFF); \
+       (a)[(r + 2)] = (uint8_t)(((v) >> 40) & 0xFF); \
+       (a)[(r + 3)] = (uint8_t)(((v) >> 32) & 0xFF); \
+       (a)[(r + 4)] = (uint8_t)(((v) >> 24) & 0xFF); \
+       (a)[(r + 5)] = (uint8_t)(((v) >> 16) & 0xFF); \
+       (a)[(r + 6)] = (uint8_t)(((v) >> 8) & 0xFF); \
+       (a)[(r + 7)] = (uint8_t)((v) & 0xFF); }
+
+// Byteswap crap
+#define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
+#define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
+#define WORDSWAP32(x) ((((x) & 0x0000FFFF) << 16) | (((x) & 0xFFFF0000) >> 16))
+
 //
 // Non-target specific stuff
 //
 
 #define ERROR        (-1)                      // Generic error return
 #define EOS          '\0'                      // End of string
-#define SPACE        ' '                       // ASCII space 
+#define SPACE        ' '                       // ASCII space
 #define SLASHCHAR    '/'
 #define SLASHSTRING  "/"
 #define VALUE        LONG                      // Assembler value
 #define ALCYON       0                         // Alcyon/DRI C object format
 #define MWC          1                         // Mark Williams object format
 #define BSD          2                         // BSD object format
+#define ELF          3                         // ELF object format
 
 // Pointer type that can point to (almost) anything
 #define PTR union _ptr
 PTR
 {
-   char * cp;                                          // Char
-   WORD * wp;                                          // WORD
-   LONG * lp;                                          // LONG
-   LONG lw;                                                    // LONG
+   uint8_t * cp;                                       // Char
+   uint16_t * wp;                                      // WORD
+   uint32_t * lp;                                      // LONG
+   uint32_t lw;                                                // LONG
    SYM ** sy;                                          // SYM
    TOKEN * tk;                                         // TOKEN
 };
@@ -168,10 +218,10 @@ PTR
 //#define M6502        0x0008          // 6502/microprocessor (absolute)
 #define TDB          (TEXT|DATA|BSS)   // Mask for text+data+bss
 
-// Sizes 
-#define SIZB         0x0001                    // .b 
-#define SIZW         0x0002                    // .w 
-#define SIZL         0x0004                    // .l 
+// Sizes
+#define SIZB         0x0001                    // .b
+#define SIZW         0x0002                    // .w
+#define SIZL         0x0004                    // .l
 #define SIZN         0x0008                    // no .(size) specifier
 
 // RISC register bank definitions (used in extended symbol attributes also)
@@ -188,10 +238,10 @@ PTR
 // Optimisation defines
 enum
 {
-       OPT_ABS_SHORT       = 0,
-       OPT_MOVEL_MOVEQ     = 1,
-       OPT_BSR_BCC_S       = 2,
-       OPT_INDIRECT_DISP   = 3,
+       OPT_ABS_SHORT     = 0,
+       OPT_MOVEL_MOVEQ   = 1,
+       OPT_BSR_BCC_S     = 2,
+       OPT_INDIRECT_DISP = 3,
        OPT_COUNT   // Dummy, used to count number of optimisation switches
 };
 
@@ -211,6 +261,7 @@ extern int lsym_flag;
 extern int sbra_flag;
 extern int obj_format;
 extern int legacy_flag;
+extern int prg_flag;   // 1 = write ".PRG" relocatable executable
 extern LONG PRGFLAGS;
 extern int optim_flags[OPT_COUNT];
 
diff --git a/sect.c b/sect.c
index 619c1632b00879c72eda8bd132fa55a9c9e0a3f4..b58d441709681244e395a0bb2683d607cf4e00f1 100644 (file)
--- a/sect.c
+++ b/sect.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // SECT.C - Code Generation, Fixups and Section Management
-// 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
 //
 
 
 // Function prototypes
-void MakeSection(int, WORD);
+void MakeSection(int, uint16_t);
 void SwitchSection(int);
 
 // Section descriptors
-SECT sect[NSECTS];             // All sections... 
+SECT sect[NSECTS];             // All sections...
 int cursect;                   // Current section number
 
 // These are copied from the section descriptor, the current code chunk
 // descriptor and the current fixup chunk descriptor when a switch is made into
 // a section.  They are copied back to the descriptors when the section is left.
-WORD scattr;                   // Section attributes 
-LONG sloc;                             // Current loc in section 
+uint16_t scattr;               // Section attributes
+uint32_t sloc;                 // Current loc in section
 
-CHUNK * scode;                 // Current (last) code chunk 
-LONG challoc;                  // # bytes alloc'd to code chunk 
-LONG ch_size;                  // # bytes used in code chunk 
-char * chptr;                  // Deposit point in code chunk buffer 
-char * chptr_opcode;   // Backup of chptr, updated before entering code generators
+CHUNK * scode;                 // Current (last) code chunk
+uint32_t challoc;              // # bytes alloc'd to code chunk
+uint32_t ch_size;              // # bytes used in code chunk
+uint8_t * chptr;               // Deposit point in code chunk buffer
+uint8_t * chptr_opcode;        // Backup of chptr, updated before entering code generators
 
 CHUNK * sfix;                  // Current (last) fixup chunk
-LONG fchalloc;                 // # bytes alloc'd to fixup chunk
-LONG fchsize;                  // # bytes used in fixup chunk
+uint32_t fchalloc;             // # bytes alloc'd to fixup chunk
+uint32_t fchsize;              // # bytes used in fixup chunk
 PTR fchptr;                            // Deposit point in fixup chunk buffer
 
 // Return a size (SIZB, SIZW, SIZL) or 0, depending on what kind of fixup is
 // associated with a location.
-static char fusiztab[] = {
+static uint8_t fusiztab[] = {
    0,  // FU_QUICK
    1,  // FU_BYTE
    2,  // FU_WORD
@@ -57,7 +57,7 @@ static char fusiztab[] = {
 };
 
 // Offset to REAL fixup location
-static char fusizoffs[] = {
+static uint8_t fusizoffs[] = {
    0,  // FU_QUICK
    0,  // FU_BYTE
    0,  // FU_WORD
@@ -95,7 +95,7 @@ void InitSection(void)
 //
 // Make a new (clean) section
 //
-void MakeSection(int sno, WORD attr)
+void MakeSection(int sno, uint16_t attr)
 {
        SECT * p = &sect[sno];
        p->scattr = attr;
@@ -131,7 +131,7 @@ void SwitchSection(int sno)
        else
                challoc = ch_size = 0;
 
-       // Copy fixup chunk vars 
+       // Copy fixup chunk vars
        if ((cp = sfix) != NULL)
        {
                fchalloc = cp->challoc;
@@ -165,13 +165,9 @@ void SaveSection(void)
 // Test to see if a location has a fixup sic'd on it.  This is used by the
 // listing generator to print 'xx's instead of '00's for forward references
 //
-int fixtest(int sno, LONG loc)
+int fixtest(int sno, uint32_t loc)
 {
-       CHUNK * ch;
        PTR fup;
-       char * fuend;
-       WORD w;
-       LONG xloc;
 
        // Force update to sect[] variables
        StopMark();
@@ -179,15 +175,15 @@ int fixtest(int sno, LONG loc)
        // Hairy, ugly linear search for a mark on our location; the speed doesn't
        // matter, since this is only done when generating a listing, which is
        // SLOW.
-       for(ch=sect[sno].sffix; ch!=NULL; ch=ch->chnext)
+       for(CHUNK * ch=sect[sno].sffix; ch!=NULL; ch=ch->chnext)
        {
-               fup.cp = (char *)ch->chptr;
-               fuend = fup.cp + ch->ch_size;
+               fup.cp = (uint8_t *)ch->chptr;
+               uint8_t * fuend = fup.cp + ch->ch_size;
 
                while (fup.cp < fuend)
                {
-                       w = *fup.wp++;
-                       xloc = *fup.lp++ + (int)fusizoffs[w & FUMASK];
+                       uint16_t w = *fup.wp++;
+                       uint32_t xloc = *fup.lp++ + (int)fusizoffs[w & FUMASK];
                        fup.wp += 2;
 
                        if (xloc == loc)
@@ -207,14 +203,14 @@ int fixtest(int sno, LONG loc)
 }
 
 
-// 
+//
 // Check that there are at least 'amt' bytes left in the current chunk. If
 // there are not, allocate another chunk of at least 'amt' bytes (and probably
 // more).
-// 
+//
 // If 'amt' is zero, ensure there are at least CH_THRESHOLD bytes, likewise.
 //
-int chcheck(LONG amt)
+int chcheck(uint32_t amt)
 {
        DEBUG { printf("chcheck(%u)\n", amt); }
        // If in BSS section, no allocation required
@@ -225,7 +221,7 @@ int chcheck(LONG amt)
                amt = CH_THRESHOLD;
 
        DEBUG { printf("    challoc=%i, ch_size=%i, diff=%i\n", challoc, ch_size, challoc-ch_size); }
-       if ((int)(challoc - ch_size) >= (int)amt) 
+       if ((int)(challoc - ch_size) >= (int)amt)
                return 0;
 
        if (amt < CH_CODE_SIZE)
@@ -246,7 +242,7 @@ int chcheck(LONG amt)
        {
                cp->chprev = scode;
                scode->chnext = cp;
-               scode->ch_size = ch_size;                       // Save old chunk's globals 
+               scode->ch_size = ch_size;                       // Save old chunk's globals
        }
 
        // Setup chunk and global vars
@@ -254,7 +250,7 @@ int chcheck(LONG amt)
        cp->chnext = NULL;
        challoc = cp->challoc = amt;
        ch_size = cp->ch_size = 0;
-       chptr = cp->chptr = ((char *)cp) + sizeof(CHUNK);
+       chptr = cp->chptr = ((uint8_t *)cp) + sizeof(CHUNK);
        scode = p->scode = cp;
 
        return 0;
@@ -263,14 +259,14 @@ int chcheck(LONG amt)
 
 // This is really wrong. We need to make some proper structures here so we
 // don't have to count sizes of objects, that's what the compiler's for! :-P
-#define FIXUP_BASE_SIZE (sizeof(WORD) + sizeof(LONG) + sizeof(WORD) + sizeof(WORD))
+#define FIXUP_BASE_SIZE (sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t))
 //
 // Arrange for a fixup on a location
 //
-int AddFixup(WORD attr, LONG loc, TOKEN * fexpr)
+int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr)
 {
-       LONG i;
-       LONG len = 0;
+       uint32_t i;
+       uint32_t len = 0;
        CHUNK * cp;
        SECT * p;
        // Shamus: Expression lengths are voodoo ATM (variable "i"). Need to fix
@@ -284,14 +280,14 @@ WARNING(!!! AddFixup() is filled with VOODOO !!!)
        if (*fexpr == SYMBOL && fexpr[2] == ENDEXPR)
        {
                // Just a single symbol
-               // SCPCD : correct bit mask for attr (else other FU_xxx will match) 
+               // SCPCD : correct bit mask for attr (else other FU_xxx will match)
                // NYAN !
                if ((attr & FUMASKRISC) == FU_JR)
                {
 //printf("AddFixup: ((attr & FUMASKRISC) == FU_JR)\n");
 //                     i = 18;
-//                     i = FIXUP_BASE_SIZE + (sizeof(LONG) * 2);
-                       i = FIXUP_BASE_SIZE + sizeof(SYM *) + sizeof(LONG);
+//                     i = FIXUP_BASE_SIZE + (sizeof(uint32_t) * 2);
+                       i = FIXUP_BASE_SIZE + sizeof(SYM *) + sizeof(uint32_t);
                }
                else
                {
@@ -311,9 +307,9 @@ WARNING(!!! AddFixup() is filled with VOODOO !!!)
                                len++;
                }
 
-               len++;                                                          // Add 1 for ENDEXPR 
+               len++;                                                          // Add 1 for ENDEXPR
 //             i = (len << 2) + 12;
-               i = FIXUP_BASE_SIZE + sizeof(WORD) + (len * sizeof(TOKEN));
+               i = FIXUP_BASE_SIZE + sizeof(uint16_t) + (len * sizeof(TOKEN));
        }
 
        // Alloc another fixup chunk for this one to fit in if necessary
@@ -340,7 +336,7 @@ WARNING(!!! AddFixup() is filled with VOODOO !!!)
                cp->chnext = NULL;
                fchalloc = cp->challoc = CH_FIXUP_SIZE;
                fchsize = cp->ch_size = 0;
-               fchptr.cp = cp->chptr = ((char *)cp) + sizeof(CHUNK);
+               fchptr.cp = cp->chptr = ((uint8_t *)cp) + sizeof(CHUNK);
                sfix = p->sfix = cp;
        }
 
@@ -349,20 +345,19 @@ WARNING(!!! AddFixup() is filled with VOODOO !!!)
        *fchptr.wp++ = attr;
        *fchptr.lp++ = loc;
        *fchptr.wp++ = cfileno;
-       *fchptr.wp++ = (WORD)curlineno;
+       *fchptr.wp++ = (uint16_t)curlineno;
 
        // Store postfix expression or pointer to a single symbol, or nothing for a
        // mark.
        if (attr & FU_EXPR)
        {
-               *fchptr.wp++ = (WORD)len;
+               *fchptr.wp++ = (uint16_t)len;
 
                while (len--)
-                       *fchptr.lp++ = (LONG)*fexpr++;
+                       *fchptr.lp++ = (uint32_t)*fexpr++;
        }
        else
        {
-//             *fchptr.lp++ = (LONG)fexpr[1];
                *fchptr.sy++ = symbolPtr[fexpr[1]];
 //printf("AddFixup: adding symbol (%s) [%08X]\n", symbolPtr[fexpr[1]]->sname, symbolPtr[fexpr[1]]->sattr);
        }
@@ -387,24 +382,20 @@ WARNING(!!! AddFixup() is filled with VOODOO !!!)
 int ResolveFixups(int sno)
 {
        PTR fup;                                // Current fixup
-       WORD * fuend;                   // End of last fixup (in this chunk)
-       WORD w;                                 // Fixup word (type+modes+flags)
-       char * locp;                    // Location to fix (in cached chunk) 
-       LONG loc;                               // Location to fixup
-       VALUE eval;                             // Expression value 
-       WORD eattr;                             // Expression attrib
+       uint16_t * fuend;               // End of last fixup (in this chunk)
+       uint16_t w;                             // Fixup word (type+modes+flags)
+       uint8_t * locp;                 // Location to fix (in cached chunk)
+       uint32_t loc;                   // Location to fixup
+       VALUE eval;                             // Expression value
+       uint16_t eattr;                 // Expression attrib
        SYM * esym;                             // External symbol involved in expr
        SYM * sy;                               // (Temp) pointer to a symbol
-       WORD i;                                 // (Temp) word
-       WORD tdb;                               // eattr & TDB
-       LONG oaddr;
+       uint16_t i;                             // (Temp) word
+       uint16_t tdb;                   // eattr & TDB
+       uint32_t oaddr;
        int reg2;
-       WORD flags;
-       unsigned page_jump = 0;
-       unsigned address = 0;
-       //unsigned j;
-       //char buf[EBUFSIZ];
-       
+       uint16_t flags;
+
        SECT * sc = &sect[sno];
        CHUNK * ch = sc->sffix;
 
@@ -421,7 +412,7 @@ int ResolveFixups(int sno)
        do
        {
                fup.cp = ch->chptr;                                     // fup -> start of chunk
-               fuend = (WORD *)(fup.cp + ch->ch_size); // fuend -> end of chunk
+               fuend = (uint16_t *)(fup.cp + ch->ch_size);     // fuend -> end of chunk
 
                while (fup.wp < fuend)
                {
@@ -429,16 +420,18 @@ int ResolveFixups(int sno)
                        loc = *fup.lp++;
                        cfileno = *fup.wp++;
                        curlineno = (int)*fup.wp++;
-DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
+                       DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
+
                        // This is based on global vars cfileno, curfname :-P
-                       // This approach is kinda meh as well. I think we can do better than this.
+                       // This approach is kinda meh as well. I think we can do better
+                       // than this.
                        SetFilenameForErrorReporting();
 
                        esym = NULL;
 
                        // Search for chunk containing location to fix up; compute a
                        // pointer to the location (in the chunk). Often we will find the
-                       // fixup is in the "cached" chunk, so the linear-search is seldom
+                       // Fixup is in the "cached" chunk, so the linear-search is seldom
                        // executed.
                        if (loc < cch->chloc || loc >= (cch->chloc + cch->ch_size))
                        {
@@ -450,7 +443,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
 
                                if (cch == NULL)
                                {
-                                       // Fixup (loc) out of range 
+                                       // Fixup (loc) out of range
                                        interror(7);
                                        // NOTREACHED
                                }
@@ -460,6 +453,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                        eattr = 0;
 
                        // Compute expression/symbol value and attribs
+
                        // Complex expression
                        if (w & FU_EXPR)
                        {
@@ -484,39 +478,31 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                else
                                        eval = 0;
 
+                               // If the symbol is not defined, but global, set esym to sy
                                if ((eattr & (GLOBAL | DEFINED)) == GLOBAL)
                                        esym = sy;
                        }
 
-                       tdb = (WORD)(eattr & TDB);
+                       tdb = (uint16_t)(eattr & TDB);
 
                        // If the expression is undefined and no external symbol is
-                       // involved, then it's an error.
+                       // involved, then that's an error.
                        if (!(eattr & DEFINED) && (esym == NULL))
                        {
                                error(undef_error);
                                continue;
                        }
 
-// It seems that this is completely unnecessary!
-#if 0
-                       if (((w & FUMASKRISC) == FU_MOVEI) && esym)
-//{
-//printf("DoFixups: Setting symbol attre to RISCSYM...\n");
-                               esym->sattre |= RISCSYM;
-//}
-#endif
-
                        // Do the fixup
-                       // 
+                       //
                        // If a PC-relative fixup is undefined, its value is *not*
                        // subtracted from the location (that will happen in the linker
                        // when the external reference is resolved).
-                       // 
+                       //
                        // MWC expects PC-relative things to have the LOC subtracted from
                        // the value, if the value is external (that is, undefined at this
                        // point).
-                       // 
+                       //
                        // PC-relative fixups must be DEFINED and either in the same
                        // section (whereupon the subtraction takes place) or ABS (with no
                        // subtract).
@@ -556,7 +542,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                eval -= 2;
 
                                if (eval + 0x80 >= 0x100)
-                                       goto range;
+                                       goto rangeErr;
 
                                if (eval == 0)
                                {
@@ -564,7 +550,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                        continue;
                                }
 
-                               *++locp = (char)eval;
+                               *++locp = (uint8_t)eval;
                                break;
                        // Fixup one-byte value at locp + 1.
                        case FU_WBYTE:
@@ -585,23 +571,23 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                }
 
                                if ((w & FU_PCREL) && eval + 0x80 >= 0x100)
-                                       goto range;
+                                       goto rangeErr;
 
                                if (w & FU_SEXT)
                                {
                                        if (eval + 0x100 >= 0x200)
-                                               goto range;
+                                               goto rangeErr;
                                }
                                else if (eval >= 0x100)
-                                       goto range;
+                                       goto rangeErr;
 
-                               *locp = (char)eval;
+                               *locp = (uint8_t)eval;
                                break;
-                       // Fixup WORD forward references; 
+                       // Fixup WORD forward references;
                        // the word could be unaligned in the section buffer, so we have to
                        // be careful.
                        case FU_WORD:
-                               if ((w & FUMASKRISC) == FU_JR)// || ((w & 0x0F00) == FU_MJR))
+                               if ((w & FUMASKRISC) == FU_JR)
                                {
                                        oaddr = *fup.lp++;
 
@@ -616,9 +602,9 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                break;
                                        }
 
-                                       *locp = (char)(*locp | ((reg2 >> 3) & 0x03));
+                                       *locp = (uint8_t)(*locp | ((reg2 >> 3) & 0x03));
                                        locp++;
-                                       *locp = (char)(*locp | ((reg2 & 0x07) << 5));
+                                       *locp = (uint8_t)(*locp | ((reg2 & 0x07) << 5));
                                        break;
                                }
 
@@ -630,9 +616,9 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                break;
                                        }
 
-                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
                                        locp++;
-                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
                                        break;
                                }
 
@@ -644,9 +630,9 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                break;
                                        }
 
-                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
                                        locp++;
-                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
                                        break;
                                }
 
@@ -662,9 +648,9 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                eval = (32 - eval);
 
                                        eval = (eval == 32) ? 0 : eval;
-                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
                                        locp++;
-                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
                                        break;
                                }
 
@@ -676,9 +662,9 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                break;
                                        }
 
-                                       *locp = (char)(*locp | ((eval >> 3) & 0x03));
+                                       *locp = (uint8_t)(*locp | ((eval >> 3) & 0x03));
                                        locp++;
-                                       *locp = (char)(*locp | ((eval & 0x07) << 5));
+                                       *locp = (uint8_t)(*locp | ((eval & 0x07) << 5));
                                        break;
                                }
 
@@ -691,28 +677,28 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                        }
 
                                        locp++;
-                                       *locp = (char)(*locp | (eval & 0x1F));
+                                       *locp = (uint8_t)(*locp | (eval & 0x1F));
                                        break;
                                }
 
                                if (!(eattr & DEFINED))
                                {
+                                       flags = MWORD;
+
                                        if (w & FU_PCREL)
-                                               w = MPCREL | MWORD;
-                                       else
-                                               w = MWORD;
+                                               flags |= MPCREL;
 
-                                       rmark(sno, loc, 0, w, esym);
+                                       MarkRelocatable(sno, loc, 0, flags, esym);
                                }
                                else
                                {
                                        if (tdb)
-                                               rmark(sno, loc, tdb, MWORD, NULL);
+                                               MarkRelocatable(sno, loc, tdb, MWORD, NULL);
 
                                        if (w & FU_SEXT)
                                        {
                                                if (eval + 0x10000 >= 0x20000)
-                                                       goto range;
+                                                       goto rangeErr;
                                        }
                                        else
                                        {
@@ -720,50 +706,40 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                                if (w & FU_ISBRA)
                                                {
                                                        if (eval + 0x8000 >= 0x10000)
-                                                       goto range;
+                                                       goto rangeErr;
                                                }
                                                else if (eval >= 0x10000)
-                                                       goto range;
+                                                       goto rangeErr;
                                        }
                                }
 
-                               *locp++ = (char)(eval >> 8);
-                               *locp = (char)eval;
+                               SETBE16(locp, 0, eval);
                                break;
                        // Fixup LONG forward references;
                        // the long could be unaligned in the section buffer, so be careful
                        // (again).
                        case FU_LONG:
+                               flags = MLONG;
+
                                if ((w & FUMASKRISC) == FU_MOVEI)
                                {
                                        // Long constant in MOVEI # is word-swapped, so fix it here
-                                       eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
-                                       flags = (MLONG | MMOVEI);
+                                       eval = WORDSWAP32(eval);
+                                       flags |= MMOVEI;
                                }
-                               else
-                                       flags = MLONG;
 
+                               // If the symbol is undefined, make sure to pass the symbol in
+                               // to the MarkRelocatable() function.
                                if (!(eattr & DEFINED))
-                               {
-//printf("Fixup (long): Symbol undefined. loc = $%X, long = $%X, flags = $%x\n", loc, eval, flags);
-                                       rmark(sno, loc, 0, flags, esym);
-                               }
+                                       MarkRelocatable(sno, loc, 0, flags, esym);
                                else if (tdb)
-                               {
-//printf("Fixup (long): TDB = $%X. loc =$%X, long = $%X, flags = $%x\n", tdb, loc, eval, flags);
-                                       rmark(sno, loc, tdb, flags, NULL);
-                               }
-//else
-//printf("Fixup (long): TDB = $%X. loc =$%X, long = $%X, flags = $%x\n", tdb, loc, eval, flags);
+                                       MarkRelocatable(sno, loc, tdb, flags, NULL);
 
-                               *locp++ = (char)(eval >> 24);
-                               *locp++ = (char)(eval >> 16);
-                               *locp++ = (char)(eval >> 8);
-                               *locp = (char)eval;
+                               SETBE32(locp, 0, eval);
                                break;
 
                        // Fixup a 3-bit "QUICK" reference in bits 9..1
-                       // (range of 1..8) in a word.  Really bits 1..3 in a byte.
+                       // (range of 1..8) in a word. Really bits 1..3 in a byte.
                        case FU_QUICK:
                                if (!(eattr & DEFINED))
                                {
@@ -772,7 +748,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                }
 
                                if (eval < 1 || eval > 8)
-                                       goto range;
+                                       goto rangeErr;
 
                                *locp |= (eval & 7) << 1;
                                break;
@@ -782,9 +758,9 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                eval -= (loc + 1);
 
                                if (eval + 0x80 >= 0x100)
-                                       goto range;
+                                       goto rangeErr;
 
-                               *locp = (char)eval;
+                               *locp = (uint8_t)eval;
                                break;
 
                        default:
@@ -793,7 +769,7 @@ DEBUG { printf("ResolveFixups: cfileno=%u\n", cfileno); }
                                // NOTREACHED
                        }
                        continue;
-range:
+rangeErr:
                        error("expression out of range");
                }
 
@@ -809,9 +785,6 @@ range:
 //
 int ResolveAllFixups(void)
 {
-       //unsigned i;
-       //char buf[EBUFSIZ];
-
        // Make undefined symbols GLOBL
        if (glob_flag)
                ForceUndefinedSymbolsGlobal();
@@ -824,4 +797,3 @@ int ResolveAllFixups(void)
        return 0;
 }
 
-
diff --git a/sect.h b/sect.h
index ceeb5052a8c25823217f42de9eba57346ffb507a..b4c3733cab4c4aac1f560620f880d33d1fafe3c8 100644 (file)
--- a/sect.h
+++ b/sect.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // SECT.H - Code Generation, Fixups and Section Management
-// 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
 //
 // Macros to deposit code in the current section
 // D_rword deposits a "6502" format (low, high) word (01).
 // D_rlong deposits a MWC "canonical byte order" longword (2301).
-#define D_byte(b)      {*chptr++=(char)b; ++sloc; ++ch_size; if(orgactive) ++orgaddr;}
-#define D_word(w)      {chcheck(2);*chptr++=(char)(w>>8); *chptr++=(char)w; \
-                                               sloc+=2; ch_size+=2; if(orgactive) orgaddr += 2;}
-#define D_long(lw)     {*chptr++=(char)(lw>>24); *chptr++=(char)(lw>>16);\
-                                               *chptr++=(char)(lw>>8); *chptr++=(char)lw; \
-                                               sloc+=4; ch_size += 4; if(orgactive) orgaddr += 4;}
-//#define D_rword(w)   {*chptr++=(char)w; *chptr++=(char)(w>>8); \
+#define D_byte(b)      {*chptr++=(uint8_t)(b); sloc++; ch_size++; \
+                                               if(orgactive) orgaddr++;}
+#define D_word(w)      {chcheck(2);*chptr++=(uint8_t)((w)>>8); \
+                                               *chptr++=(uint8_t)(w); \
+                                               sloc += 2; ch_size += 2; if(orgactive) orgaddr += 2;}
+#define D_long(lw)     {*chptr++=(uint8_t)((lw)>>24); \
+                                               *chptr++=(uint8_t)((lw)>>16);\
+                                               *chptr++=(uint8_t)((lw)>>8); \
+                                               *chptr++=(uint8_t)(lw); \
+                                               sloc += 4; ch_size += 4; if(orgactive) orgaddr += 4;}
+//#define D_rword(w)   {*chptr++=(uint8_t)w; *chptr++=(uint8_t)(w>>8); \
 //                                             sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;}
-//#define D_rlong(lw)  {*chptr++=(char)(lw>>16);*chptr++=(char)(lw>>24);\
-//                                             *chptr++=(char)lw;*chptr++=(char)(lw>>8); \
+//#define D_rlong(lw)  {*chptr++=(uint8_t)(lw>>16);*chptr++=(uint8_t)(lw>>24);\
+//                                             *chptr++=(uint8_t)lw;*chptr++=(uint8_t)(lw>>8); \
 //                                             sloc+=4; ch_size += 4;if(orgactive) orgaddr += 4;}
 // Fill n bytes with zeroes
 #define D_ZEROFILL(n)  {memset(chptr, 0, n); chptr+=n; sloc+=n; ch_size+=n;\
                                                if (orgactive) orgaddr+=n;}
 
-#define NSECTS       16                                // Max. number of sections
+#define NSECTS       16                        // Max. number of sections
 
 // Tunable (storage) definitions
-#define CH_THRESHOLD    64                     // Minimum amount of space in code chunk
-#define CH_CODE_SIZE    2048           // Code chunk normal allocation
-#define CH_FIXUP_SIZE   1024           // Fixup chunk normal allocation
+#define CH_THRESHOLD    64             // Minimum amount of space in code chunk
+#define CH_CODE_SIZE    2048   // Code chunk normal allocation
+#define CH_FIXUP_SIZE   1024   // Fixup chunk normal allocation
 
 // Section attributes (.scattr)
-#define SUSED        0x8000                    // Section is used (really, valid)
-#define SBSS         0x4000                    // Section can contain no data
-#define SABS         0x2000                    // Section is absolute
-#define SPIC         0x1000                    // Section is position-independent code
+#define SUSED        0x8000            // Section is used (really, valid)
+#define SBSS         0x4000            // Section can contain no data
+#define SABS         0x2000            // Section is absolute
+#define SPIC         0x1000            // Section is position-independent code
 
 // Fixup record a WORD of these bits, followed by a loc and then a pointer
 // to a symbol or an ENDEXPR-terminated postfix expression.
 // token.L     expression list
 // (etc)
 // ENDEXPR.L   (end of expression)
-#define FUMASK       007                       // Mask for fixup cases:
-#define FU_QUICK     000                       // Fixup 3-bit quick instr field
-#define FU_BYTE      001                       // Fixup byte
-#define FU_WORD      002                       // Fixup word
-#define FU_WBYTE     003                       // Fixup byte (at loc+1)
-#define FU_LONG      004                       // Fixup long
-#define FU_BBRA      005                       // Fixup byte branch
-#define FU_6BRA      007                       // Fixup 6502-format branch offset
-#define FU_SEXT      010                       // Ok to sign extend
-#define FU_PCREL     020                       // Subtract PC first
-#define FU_EXPR      040                       // Expression (not symbol) follows
-
-#define FUMASKRISC     0x0F00                  // Mask for RISC fixup cases
+#define FUMASK       007               // Mask for fixup cases:
+#define FU_QUICK     000               // Fixup 3-bit quick instr field
+#define FU_BYTE      001               // Fixup byte
+#define FU_WORD      002               // Fixup word
+#define FU_WBYTE     003               // Fixup byte (at loc+1)
+#define FU_LONG      004               // Fixup long
+#define FU_BBRA      005               // Fixup byte branch
+#define FU_6BRA      007               // Fixup 6502-format branch offset
+#define FU_SEXT      010               // Ok to sign extend
+#define FU_PCREL     020               // Subtract PC first
+#define FU_EXPR      040               // Expression (not symbol) follows
+
+#define FU_GLOBAL    0x0080            // Mark global symbol
+
+#define FUMASKRISC   0x0F00            // Mask for RISC fixup cases
 #define FU_MOVEI     0x0100
 #define FU_JR        0x0200
 #define FU_REGONE    0x0400
 #define FU_REGTWO    0x0800
 
 #define FU_SUB32     0x1000
-#define FU_ISBRA     0x2000                    // Word forward fixup is a BRA or DBRA
-#define FU_LBRA      0x4000                    // Long branch, for short branch detect
-#define FU_DONE      0x8000                    // Fixup has been done
+#define FU_ISBRA     0x2000            // Word forward fixup is a BRA or DBRA
+#define FU_LBRA      0x4000            // Long branch, for short branch detect
+#define FU_DONE      0x8000            // Fixup has been done
 
 // Chunks are used to hold generated code and fixup records
 #define CHUNK  struct _chunk
 CHUNK {
-   CHUNK * chnext;                                     // Next, previous chunks in section
-   CHUNK * chprev;
-   LONG chloc;                                         // Base addr of this chunk
-   LONG challoc;                                       // # bytes allocated for chunk
-   LONG ch_size;                                       // # bytes chunk actually uses
-   char * chptr;                                       // Data for this chunk
+       CHUNK * chnext;                         // Next, previous chunks in section
+       CHUNK * chprev;
+       uint32_t chloc;                         // Base addr of this chunk
+       uint32_t challoc;                       // # bytes allocated for chunk
+       uint32_t ch_size;                       // # bytes chunk actually uses
+       uint8_t * chptr;                        // Data for this chunk
 };
 
 // Section descriptor
 #define SECT   struct _sect
 SECT {
-   WORD scattr;                                                // Section attributes
-   LONG sloc;                                          // Current loc-in / size-of section 
-   CHUNK * sfcode;                                     // First chunk in section
-   CHUNK * scode;                                      // Last chunk in section
-   CHUNK * sffix;                                      // First fixup chunk
-   CHUNK * sfix;                                       // Last fixup chunk
+       uint16_t scattr;                        // Section attributes
+       uint32_t sloc;                          // Current loc-in / size-of section
+       uint32_t relocs;                        // # of relocations for this section
+       CHUNK * sfcode;                         // First chunk in section
+       CHUNK * scode;                          // Last chunk in section
+       CHUNK * sffix;                          // First fixup chunk
+       CHUNK * sfix;                           // Last fixup chunk
 };
 
-// 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    [symbol]      symbol involved in external reference
-#define MCHUNK struct _mchunk
-MCHUNK {
-   MCHUNK * mcnext;                                    // Next mark chunk
-   PTR mcptr;                                          // Vector of marks
-   LONG mcalloc;                                       // # marks allocted to mark block
-   LONG mcused;                                                // # marks used in block
-};
-
-#define MWORD        0x0000                    // Marked word
-#define MLONG        0x0100                    // Marked long 
-#define MMOVEI       0x0200
-#define MCHFROM      0x8000                    // Mark includes change-to-from
-#define MSYMBOL      0x4000                    // Mark includes symbol number
-#define MCHEND       0x2000                    // Indicates end of mark chunk
-#define MPCREL       0x1000                    // Mark is PC-relative
-
 // Globals, external etc
-extern LONG sloc;
-extern WORD scattr;
-extern char * chptr;
-extern char * chptr_opcode;
-extern LONG ch_size;
+extern uint32_t sloc;
+extern uint16_t scattr;
+extern uint8_t * chptr;
+extern uint8_t * chptr_opcode;
+extern uint32_t ch_size;
 extern int cursect;
 extern SECT sect[];
-extern LONG challoc;
+extern uint32_t challoc;
 extern CHUNK * scode;
 
 // Prototypes
 void InitSection(void);
 void SwitchSection(int);
 void SaveSection(void);
-int fixtest(int, LONG);
-int chcheck(LONG);
-int AddFixup(WORD, LONG, TOKEN *);
+int fixtest(int, uint32_t);
+int chcheck(uint32_t);
+int AddFixup(uint16_t, uint32_t, TOKEN *);
 int ResolveAllFixups(void);
 
 #endif // __SECT_H__
+
index 9ba661fc3fa931609a7f34eb1c95c5aa84d33d6c..f2f513cc3671aa0ca652d7be9f300c40fd8281d4 100644 (file)
--- a/symbol.c
+++ b/symbol.c
@@ -7,29 +7,31 @@
 //
 
 #include "symbol.h"
+#include "error.h"
 #include "listing.h"
+#include "object.h"
 #include "procln.h"
-#include "error.h"
 
 
 // Macros
-#define NBUCKETS 256                                   // Number of hash buckets (power of 2)
-
-static SYM * symbolTable[NBUCKETS];            // User symbol-table header
-int curenv;                                                            // Current enviroment number
-static SYM * sorder;                                   // * -> Symbols, in order of reference
-static SYM * sordtail;                                 // * -> Last symbol in sorder list
-static SYM * sdecl;                                            // * -> Symbols, in order of declaration
-static SYM * sdecltail;                                        // * -> Last symbol in sdecl list
-static uint32_t currentUID;                            // Symbol UID tracking (done by NewSymbol())
-
-// Tags for marking symbol spaces
+#define NBUCKETS 256                           // Number of hash buckets (power of 2)
+
+static SYM * symbolTable[NBUCKETS];    // User symbol-table header
+int curenv;                                                    // Current enviroment number
+static SYM * sorder;                           // * -> Symbols, in order of reference
+static SYM * sordtail;                         // * -> Last symbol in sorder list
+static SYM * sdecl;                                    // * -> Symbols, in order of declaration
+static SYM * sdecltail;                                // * -> Last symbol in sdecl list
+static uint32_t currentUID;                    // Symbol UID tracking (done by NewSymbol())
+uint32_t firstglobal; // Index of the first global symbol in an ELF object.
+
+// Tags for marking symbol spaces:
 // a = absolute
 // t = text
 // d = data
 // ! = "impossible!"
 // b = BSS
-static char tdb_text[8] = {
+static uint8_t tdb_text[8] = {
    'a', 't', 'd', '!', 'b', SPACE, SPACE, SPACE
 };
 
@@ -39,9 +41,7 @@ static char tdb_text[8] = {
 //
 void InitSymbolTable(void)
 {
-       int i;                                                                  // Iterator
-
-       for(i=0; i<NBUCKETS; i++)                               // Initialise symbol hash table
+       for(int i=0; i<NBUCKETS; i++)                   // Initialise symbol hash table
                symbolTable[i] = NULL;
 
        curenv = 1;                                                             // Init local symbol enviroment
@@ -54,13 +54,13 @@ void InitSymbolTable(void)
 
 
 //
-// Hash the print name and enviroment number
+// Hash the ASCII name and enviroment number
 //
-int HashSymbol(char * name, int envno)
+int HashSymbol(uint8_t * name, int envno)
 {
-       int sum, k = 0;                                                 // Hash calculation
+       int sum = envno, k = 0;
 
-       for(sum=envno; *name; name++)
+       for(; *name; name++)
        {
                if (k++ == 1)
                        sum += *name << 2;
@@ -73,9 +73,9 @@ int HashSymbol(char * name, int envno)
 
 
 //
-// Make a new symbol of type `type' in enviroment `envno'
+// Make a new symbol of type 'type' in enviroment 'envno'
 //
-SYM * NewSymbol(char * name, int type, int envno)
+SYM * NewSymbol(uint8_t * name, int type, int envno)
 {
        // Allocate the symbol
        SYM * symbol = malloc(sizeof(SYM));
@@ -88,27 +88,25 @@ SYM * NewSymbol(char * name, int type, int envno)
 
        // Fill-in the symbol
        symbol->sname  = strdup(name);
-       symbol->stype  = (BYTE)type;
-       symbol->senv   = (WORD)envno;
+       symbol->stype  = (uint8_t)type;
+       symbol->senv   = (uint16_t)envno;
+       // We don't set this as DEFINED, as it could be a forward reference!
        symbol->sattr  = 0;
-       // Don't do this, it could be a forward reference!
-//     symbol->sattr  = DEFINED;               // We just defined it...
-       // This is a bad assumption. Not every symbol 1st seen in a RISC section is
-       // a RISC symbol!
-//     symbol->sattre = (rgpu || rdsp ? RISCSYM : 0);
+       // We don't set RISCSYM here as not every symbol first seen in a RISC
+       // section is a RISC symbol!
        symbol->sattre = 0;
        symbol->svalue = 0;
        symbol->sorder = NULL;
        symbol->uid    = currentUID++;
 
-       // Install symbol in symbol table
+       // Install symbol in the symbol table
        int hash = HashSymbol(name, envno);
        symbol->snext = symbolTable[hash];
        symbolTable[hash] = symbol;
 
-       // Append symbol to symbol-order list
+       // Append symbol to the symbol-order list
        if (sorder == NULL)
-               sorder = symbol;                                        // Add first symbol 
+               sorder = symbol;                                        // Add first symbol
        else
                sordtail->sorder = symbol;                      // Or append to tail of list
 
@@ -121,7 +119,7 @@ SYM * NewSymbol(char * name, int type, int envno)
 // Look up the symbol name by its UID and return the pointer to the name.
 // If it's not found, return NULL.
 //
-char * GetSymbolNameByUID(uint32_t uid)
+uint8_t * GetSymbolNameByUID(uint32_t uid)
 {
        //problem is with string lookup, that's why we're writing this
        //so once this is written, we can put the uid in the token stream
@@ -143,10 +141,10 @@ char * GetSymbolNameByUID(uint32_t uid)
 
 
 //
-// Lookup the symbol `name', of the specified type, with the specified
+// Lookup the symbol 'name', of the specified type, with the specified
 // enviroment level
 //
-SYM * lookup(char * name, int type, int envno)
+SYM * lookup(uint8_t * name, int type, int envno)
 {
        SYM * symbol = symbolTable[HashSymbol(name, envno)];
 
@@ -182,7 +180,7 @@ void AddToSymbolDeclarationList(SYM * symbol)
 
        if (sdecl == NULL)
                sdecl = symbol;                         // First on decl-list
-       else 
+       else
                sdecltail->sdecl = symbol;      // Add to end of list
 
        // Fix up list's tail
@@ -200,8 +198,8 @@ void ForceUndefinedSymbolsGlobal(void)
 
        DEBUG printf("~ForceUndefinedSymbolsGlobal()\n");
 
-       // Scan through all symbols;
-       // If a symbol is REFERENCED but not DEFINED, then make it global.
+       // Scan through all symbols; if a symbol is REFERENCED but not DEFINED,
+       // then make it global.
        for(sy=sorder; sy!=NULL; sy=sy->sorder)
        {
                if (sy->stype == LABEL && sy->senv == 0
@@ -211,58 +209,43 @@ void ForceUndefinedSymbolsGlobal(void)
 }
 
 
-//
-// Convert string to uppercase
-//
-int uc_string(char * s)
-{
-       for(; *s; s++)
-       {
-               if (*s >= 'a' && *s <= 'z')
-                       *s -= 32;
-       }
-
-       return 0;
-}
-
-
 //
 // Assign numbers to symbols that are to be exported or imported. The symbol
-// number is put in `.senv'. Return the number of symbols that will be in the
+// number is put in 'senv'. Returns the number of symbols that will be in the
 // symbol table.
 //
-int sy_assign(char * buf, char *(* constr)())
+// N.B.: This is usually called twice; first time with NULL parameters and the
+//       second time with real ones. The first one is typically done to get a
+//       count of the # of symbols in the symbol table, and the second is to
+//       actually create it.
+//
+uint32_t sy_assign(uint8_t * buf, uint8_t *(* construct)())
 {
-       SYM * sy;
-       int scount = 0;
+       uint16_t scount = 0;
 
+       // Done only on first pass...
        if (buf == NULL)
        {
                // Append all symbols not appearing on the .sdecl list to the end of
                // the .sdecl list
-               for(sy=sorder; sy!=NULL; sy=sy->sorder)
+               for(SYM * sy=sorder; sy!=NULL; sy=sy->sorder)
                        AddToSymbolDeclarationList(sy);
        }
 
        // Run through all symbols (now on the .sdecl list) and assign numbers to
        // them. We also pick which symbols should be global or not here.
-       for(sy=sdecl; sy!=NULL; sy=sy->sdecl)
+       for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
        {
-               // Don't want register/CC or undefined on our list
-//these should already be rejected above...
-//             if (sy->sattre & (EQUATEDREG | UNDEF_EQUR | EQUATEDCC | UNDEF_CC)))
-//                     continue;
-
                // Export or import external references, and export COMMON blocks.
                if ((sy->stype == LABEL)
                        && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED)
                        || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED))
                        || (sy->sattr & COMMON))
                {
-                       sy->senv = (WORD)scount++;
+                       sy->senv = scount++;
 
                        if (buf != NULL)
-                               buf = (*constr)(buf, sy, 1);
+                               buf = construct(buf, sy, 1);
                }
                // Export vanilla labels (but don't make them global). An exception is
                // made for equates, which are not exported unless they are referenced.
@@ -270,49 +253,159 @@ int sy_assign(char * buf, char *(* constr)())
                        && (sy->sattr & (DEFINED | REFERENCED)) != 0
                        && (!as68_flag || *sy->sname != 'L'))
                {
-                       sy->senv = (WORD)scount++;
+                       sy->senv = scount++;
 
                        if (buf != NULL)
-                               buf = (*constr)(buf, sy, 0);
+                               buf = construct(buf, sy, 0);
                }
        }
 
+       // For ELF object mode run through all symbols in reference order
+       // and export all global-referenced labels. Not sure if this is
+       // required but it's here nonetheless
+/* why?? when you have sy_assign_ELF ???
+       if (obj_format == ELF)
+       {
+               for(sy=sdecl; sy!=NULL; sy=sy->sorder)
+               {
+                       if ((sy->sattr == (GLOBAL | REFERENCED)) && (buf != NULL))
+                       {
+                               buf = (*construct)(buf, sy, 0);
+                               scount++;
+                       }
+               }
+       }*/
+
        return scount;
 }
 
 
+//
+// Custom version of sy_assign for ELF .o files.
+// The order that the symbols should be dumped is different.
+// (globals must be explicitly at the end of the table)
+//
+// N.B.: It should be possible to merge this with sy_assign, as there's nothing
+//       really ELF specific in here, other than the "globals go at the end of
+//       the queue" thing, which doesn't break the others. :-P
+uint32_t sy_assign_ELF(uint8_t * buf, uint8_t *(* construct)())
+{
+       uint16_t scount = 0;
+
+//     if (construct == (uint8_t *(*)())constr_elfsymtab)
+//     if (buf == NULL)
+       {
+               // Append all symbols not appearing on the .sdecl list to the end of
+               // the .sdecl list
+               for(SYM * sy=sorder; sy!=NULL; sy=sy->sorder)
+                       AddToSymbolDeclarationList(sy);
+       }
+
+       // Run through all symbols (now on the .sdecl list) and assign numbers to
+       // them. We also pick which symbols should be global or not here.
+       for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
+       {
+               // Export or import external references, and export COMMON blocks.
+               //if ((sy->stype == LABEL)
+               //      && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED)
+               //      || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED))
+               //      || (sy->sattr & COMMON))
+               //{
+               //      sy->senv = (WORD)scount++;
+        //
+               //      if (buf != NULL)
+               //              buf = (*construct)(buf, sy, 1);
+               //}
+               // Export vanilla labels (but don't make them global). An exception is
+               // made for equates, which are not exported unless they are referenced.
+               if (sy->stype == LABEL && lsym_flag
+                       && (sy->sattr & (DEFINED | REFERENCED)) != 0
+                       && (*sy->sname != '.')
+                       && (sy->sattr & GLOBAL) == 0)
+               //if (sy->stype == 0)
+               //      if (lsym_flag)
+               //              if ((sy->sattr & (DEFINED | REFERENCED)) != 0)
+               //                      if ((!as68_flag || *sy->sname != 'L'))
+               {
+                       sy->senv = scount++;
+
+                       if (buf != NULL)
+                               buf = construct(buf, sy, 0);
+               }
+       }
+
+       firstglobal = scount;
+
+       // For ELF object mode run through all symbols in reference order
+       // and export all global-referenced labels. Not sure if this is
+       // required but it's here nonetheless
+
+       //for(sy=sdecl; sy!=NULL; sy=sy->sorder)
+       for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
+       {
+               if ((sy->stype == LABEL)
+                       && ((sy->sattr & (GLOBAL | DEFINED)) == (GLOBAL | DEFINED)
+                       || (sy->sattr & (GLOBAL | REFERENCED)) == (GLOBAL | REFERENCED))
+                       || (sy->sattr & COMMON))
+               {
+                       sy->senv = scount++;
+
+                       if (buf != NULL)
+                               buf = construct(buf, sy, 1);
+               }
+               else if ((sy->sattr == (GLOBAL | REFERENCED)) &&  (buf != NULL))
+               {
+                       buf = construct(buf, sy, 0);
+                       scount++;
+               }
+       }
+
+       return scount;
+}
+
+
+//
+// Convert string to uppercase
+//
+void ToUppercase(uint8_t * s)
+{
+       for(; *s; s++)
+       {
+               if (*s >= 'a' && *s <= 'z')
+                       *s -= 0x20;
+       }
+}
+
+
 //
 // Generate symbol table for listing file
 //
 int symtable(void)
 {
+       extern int pagelen;
        int i;
        int j;
        SYM * q = NULL;
        SYM * p;
        SYM * r;
        SYM * k;
-       SYM ** sy;
        SYM * colptr[4];
-       char ln[150];
-       char ln1[150];
+       char ln[200];
+       char ln1[200];
        char ln2[20];
        char c, c1;
        WORD w;
        int ww;
-       int colhei;
-       extern int pagelen;
+       int colhei = pagelen - 5;
 
-       colhei = pagelen - 5;
+       // Allocate storage for list headers and partition all labels. Throw away
+       // macros and macro arguments.
+       SYM ** sy = (SYM **)malloc(128 * sizeof(uint32_t));
 
-       // Allocate storage for list headers and partition all labels.  
-       // Throw away macros and macro arguments.
-       sy = (SYM **)malloc(128 * sizeof(LONG));
-
-       for(i=0; i<128; ++i)
+       for(i=0; i<128; i++)
                sy[i] = NULL;
 
-       for(i=0; i<NBUCKETS; ++i)
+       for(i=0; i<NBUCKETS; i++)
        {
                for(p=symbolTable[i]; p!=NULL; p=k)
                {
@@ -372,11 +465,11 @@ int symtable(void)
 
        while (p != NULL)
        {
-               for(i=0; i<4; ++i)
+               for(i=0; i<4; i++)
                {
                        colptr[i] = p;
 
-                       for(j=0; j<colhei; ++j)
+                       for(j=0; j<colhei; j++)
                        {
                                if (p == NULL)
                                        break;
@@ -385,14 +478,14 @@ int symtable(void)
                        }
                }
 
-               for(i=0; i<colhei; ++i)
+               for(i=0; i<colhei; i++)
                {
                        *ln = EOS;
 
                        if (colptr[0] == NULL)
                                break;
 
-                       for(j=0; j<4; ++j)
+                       for(j=0; j<4; j++)
                        {
                                if ((q = colptr[j]) == NULL)
                                        break;
@@ -410,7 +503,7 @@ int symtable(void)
 
                                if (w & COMMON)
                                        c = 'c';
-                               else if ((w & (DEFINED|GLOBAL)) == GLOBAL)
+                               else if ((w & (DEFINED | GLOBAL)) == GLOBAL)
                                        c = 'x';
                                else if (w & GLOBAL)
                                        c = 'g';
@@ -422,7 +515,7 @@ int symtable(void)
                                else
                                {
                                        sprintf(ln2, "%08X", q->svalue);
-                                       uc_string(ln2);
+                                       ToUppercase(ln2);
                                }
 
                                sprintf(ln1, "  %16s %s %c%c%c", q->sname, ln2, (ww & EQUATEDREG) ? 'e' : SPACE, c1, c);
index bd32a5efc114fc8efd2dfa6f2dfea290831f4411..9c5c26a82e08e15feef7b35a8ef64985c655e537 100644 (file)
--- a/symbol.h
+++ b/symbol.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // SYMBOL.H - Symbol 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
 //
@@ -15,7 +15,7 @@
 struct LineList
 {
        struct LineList * next;
-       char * line;
+       uint8_t * line;
 };
 
 // Symbols
@@ -25,12 +25,12 @@ SYM
        SYM * snext;                                    // * -> Next symbol on hash-chain
        SYM * sorder;                                   // * -> Next sym in order of reference
        SYM * sdecl;                                    // * -> Next sym in order of declaration
-       uint8_t stype;                                  // Symbol type 
+       uint8_t stype;                                  // Symbol type
        uint16_t sattr;                                 // Attribute bits
        uint32_t sattre;                                // Extended attribute bits
        uint16_t senv;                                  // Enviroment number
        uint32_t svalue;                                // Symbol value
-       char * sname;                                   // * -> Symbol's print-name
+       uint8_t * sname;                                // * -> Symbol's print-name
        struct LineList * lineList;             // * -> Macro's linked list of lines
        struct LineList * last;                 // * -> end of macro linked list
        uint32_t uid;                                   // Symbol's unique ID
@@ -38,18 +38,19 @@ SYM
 
 // Globals, externals, etc.
 extern int curenv;
-extern char subttl[];
-extern int eject(void);
+extern uint8_t subttl[];
+extern uint32_t firstglobal;// Index of the fist global symbol in an ELF object.
 
 // Exported functions
-SYM * lookup(char *, int, int);
+SYM * lookup(uint8_t *, int, int);
 void InitSymbolTable(void);
-SYM * NewSymbol(char *, int, int);
+SYM * NewSymbol(uint8_t *, int, int);
 void AddToSymbolDeclarationList(SYM *);
 void ForceUndefinedSymbolsGlobal(void);
 int symtable(void);
-int sy_assign(char *, char *(*)());
-char * GetSymbolNameByUID(uint32_t);
+uint32_t sy_assign(uint8_t *, uint8_t *(*)());
+uint32_t sy_assign_ELF(uint8_t *, uint8_t *(*)());
+uint8_t * GetSymbolNameByUID(uint32_t);
 
 #endif // __SYMBOL_H__
 
diff --git a/token.c b/token.c
index 30f529d018b95084e621a18c99cf272df071e5b7..8726eb4b9ee256ed536f9eff6ae061bb48d27dc0 100644 (file)
--- a/token.c
+++ b/token.c
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // TOKEN.C - Token Handling
-// 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
 //
@@ -13,7 +13,7 @@
 #include "symbol.h"
 
 #define DECL_KW                                // Declare keyword arrays
-#define DEF_KW                         // Declare keyword values 
+#define DEF_KW                         // Declare keyword values
 #include "kwtab.h"                     // Incl generated keyword tables & defs
 
 
@@ -23,7 +23,7 @@ int totlines;                         // Total # of lines
 int mjump_align = 0;           // mjump alignment flag
 char lntag;                                    // Line tag
 char * curfname;                       // Current filename
-char tolowertab[128];          // Uppercase ==> lowercase 
+char tolowertab[128];          // Uppercase ==> lowercase
 int8_t hextab[128];                    // Table of hex values
 char dotxtab[128];                     // Table for ".b", ".s", etc.
 char irbuf[LNSIZ];                     // Text for .rept block line
@@ -54,28 +54,28 @@ static IMACRO * f_imacro;                           // Ptr list of free IMACROs
 static TOKEN tokbuf[TOKBUFSIZE];               // Token buffer (stack-like, all files)
 
 char chrtab[] = {
-       ILLEG, ILLEG, ILLEG, ILLEG,                     // NUL SOH STX ETX 
-       ILLEG, ILLEG, ILLEG, ILLEG,                     // EOT ENQ ACK BEL 
-       ILLEG, WHITE, ILLEG, ILLEG,                     // BS HT LF VT 
-       WHITE, ILLEG, ILLEG, ILLEG,                     // FF CR SO SI 
+       ILLEG, ILLEG, ILLEG, ILLEG,                     // NUL SOH STX ETX
+       ILLEG, ILLEG, ILLEG, ILLEG,                     // EOT ENQ ACK BEL
+       ILLEG, WHITE, ILLEG, ILLEG,                     // BS HT LF VT
+       WHITE, ILLEG, ILLEG, ILLEG,                     // FF CR SO SI
 
-       ILLEG, ILLEG, ILLEG, ILLEG,                     // DLE DC1 DC2 DC3 
-       ILLEG, ILLEG, ILLEG, ILLEG,                     // DC4 NAK SYN ETB 
-       ILLEG, ILLEG, ILLEG, ILLEG,                     // CAN EM SUB ESC 
-       ILLEG, ILLEG, ILLEG, ILLEG,                     // FS GS RS US 
+       ILLEG, ILLEG, ILLEG, ILLEG,                     // DLE DC1 DC2 DC3
+       ILLEG, ILLEG, ILLEG, ILLEG,                     // DC4 NAK SYN ETB
+       ILLEG, ILLEG, ILLEG, ILLEG,                     // CAN EM SUB ESC
+       ILLEG, ILLEG, ILLEG, ILLEG,                     // FS GS RS US
 
        WHITE, MULTX, MULTX, SELF,                      // SP ! " #
        MULTX+CTSYM, MULTX, SELF, MULTX,        // $ % & '
        SELF, SELF, SELF, SELF,                         // ( ) * +
        SELF, SELF, STSYM, SELF,                        // , - . /
 
-       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 0 1 
-       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 2 3 
-       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 4 5 
-       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 6 7 
-       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 8 9 
-       MULTX, MULTX,                                                           // : ; 
-       MULTX, MULTX, MULTX, STSYM+CTSYM,                       // < = > ? 
+       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 0 1
+       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 2 3
+       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 4 5
+       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 6 7
+       DIGIT+HDIGIT+CTSYM, DIGIT+HDIGIT+CTSYM,         // 8 9
+       MULTX, MULTX,                                                           // : ;
+       MULTX, MULTX, MULTX, STSYM+CTSYM,                       // < = > ?
 
        MULTX, STSYM+CTSYM+HDIGIT,                                                                      // @ A
        (char)((BYTE)DOT)+STSYM+CTSYM+HDIGIT, STSYM+CTSYM+HDIGIT,       // B C
@@ -96,10 +96,10 @@ char chrtab[] = {
        STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM,                     // h i j k
        (char)((BYTE)DOT)+STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM,   // l m n o
 
-       STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM,   // p q r s 
-       STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM,   // t u v w 
-       STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF,                            // x y z { 
-       SELF, SELF, SELF, ILLEG                                                                         // | } ~ DEL 
+       STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM,   // p q r s
+       STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, (char)((BYTE)DOT)+STSYM+CTSYM,   // t u v w
+       STSYM+CTSYM, STSYM+CTSYM, STSYM+CTSYM, SELF,                            // x y z {
+       SELF, SELF, SELF, ILLEG                                                                         // | } ~ DEL
 };
 
 // Names of registers
@@ -110,7 +110,7 @@ static char * regname[] = {
 };
 
 static char * riscregname[] = {
-        "r0",  "r1",  "r2",  "r3",  "r4", "r5",   "r6",  "r7", 
+        "r0",  "r1",  "r2",  "r3",  "r4", "r5",   "r6",  "r7",
         "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15",
        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
@@ -155,15 +155,15 @@ void InitTokenizer(void)
                tolowertab[i] |= 0x20;
 
        // These characters are legal immediately after a period
-       dotxtab['b'] = DOTB;                                    // .b .B .s .S 
+       dotxtab['b'] = DOTB;                                    // .b .B .s .S
        dotxtab['B'] = DOTB;
        dotxtab['s'] = DOTB;
        dotxtab['S'] = DOTB;
-       dotxtab['w'] = DOTW;                                    // .w .W 
+       dotxtab['w'] = DOTW;                                    // .w .W
        dotxtab['W'] = DOTW;
-       dotxtab['l'] = DOTL;                                    // .l .L 
+       dotxtab['l'] = DOTL;                                    // .l .L
        dotxtab['L'] = DOTL;
-       dotxtab['i'] = DOTI;                                    // .i .I (???) 
+       dotxtab['i'] = DOTI;                                    // .i .I (???)
        dotxtab['I'] = DOTI;
 }
 
@@ -230,7 +230,7 @@ INOBJ * a_inobj(int typ)
 
                inobj->inobj.ifile = ifile;
                break;
-       case SRC_IMACRO:                                                // Alloc and init an IMACRO 
+       case SRC_IMACRO:                                                // Alloc and init an IMACRO
                if (f_imacro == NULL)
                        imacro = malloc(sizeof(IMACRO));
                else
@@ -288,7 +288,6 @@ int ExpandMacro(char * src, char * dest, int destsiz)
        IMACRO * imacro = cur_inobj->inobj.imacro;
        int macnum = (int)(imacro->im_macro->sattr);
 
-//     destsiz--;
        char * dst = dest;                                              // Next dest slot
        char * edst = dest + destsiz - 1;               // End + 1(?) of dest buffer
 
@@ -316,7 +315,7 @@ int ExpandMacro(char * src, char * dest, int destsiz)
 
                        // Skip comments in case a loose @ or \ is in there
                        // In that case the tokeniser was trying to expand it.
-                       if (*s == '*' || *s == ';' || ((*s == '/') && (*(s + 1) == '/')))
+                       if ((*s == ';') || ((*s == '/') && (*(s + 1) == '/')))
                                goto skipcomments;
 
                        *dst++ = *s++;
@@ -335,11 +334,11 @@ int ExpandMacro(char * src, char * dest, int destsiz)
 
                                *dst++ = *s++;
                                continue;
-                       case '?':                                               // \? <macro>  set `questmark' flag 
+                       case '?':                                               // \? <macro>  set `questmark' flag
                                ++s;
                                questmark = 1;
                                break;
-                       case '#':                                               // \#, number of arguments 
+                       case '#':                                               // \#, number of arguments
                                sprintf(numbuf, "%d", (int)imacro->im_nargs);
                                goto copystr;
                        case '!':                                               // \! size suffix supplied on invocation
@@ -352,7 +351,7 @@ int ExpandMacro(char * src, char * dest, int destsiz)
                                }
 
                                goto copy_d;
-                       case '~':                                               // ==> unique label string Mnnnn... 
+                       case '~':                                               // ==> unique label string Mnnnn...
                                sprintf(numbuf, "M%u", curuniq);
 copystr:
                                d = numbuf;
@@ -627,8 +626,6 @@ overflow:
 //
 char * GetNextMacroLine(void)
 {
-//     unsigned source_addr;
-
        IMACRO * imacro = cur_inobj->inobj.imacro;
 //     LONG * strp = imacro->im_nextln;
        struct LineList * strp = imacro->im_nextln;
@@ -636,7 +633,6 @@ char * GetNextMacroLine(void)
        if (strp == NULL)                                               // End-of-macro
                return NULL;
 
-//     imacro->im_nextln = (LONG *)*strp;
        imacro->im_nextln = strp->next;
 //     ExpandMacro((char *)(strp + 1), imacro->im_lnbuf, LNSIZ);
        ExpandMacro(strp->line, imacro->im_lnbuf, LNSIZ);
@@ -682,17 +678,13 @@ char * GetNextRepeatLine(void)
 //
 int include(int handle, char * fname)
 {
-       IFILE * ifile;
-       INOBJ * inobj;
-       FILEREC * fr;
-
        // Debug mode
        if (debug)
                printf("[include: %s, cfileno=%u]\n", fname, cfileno);
 
        // Alloc and initialize include-descriptors
-       inobj = a_inobj(SRC_IFILE);
-       ifile = inobj->inobj.ifile;
+       INOBJ * inobj = a_inobj(SRC_IFILE);
+       IFILE * ifile = inobj->inobj.ifile;
 
        ifile->ifhandle = handle;                               // Setup file handle
        ifile->ifind = ifile->ifcnt = 0;                // Setup buffer indices
@@ -700,21 +692,20 @@ int include(int handle, char * fname)
        ifile->ifoldfname = curfname;                   // Save old filename
        ifile->ifno = cfileno;                                  // Save old file number
 
-//     cfileno = filecount++;                                  // Compute new file number
        // NB: This *must* be preincrement, we're adding one to the filecount here!
        cfileno = ++filecount;                                  // Compute NEW file number
        curfname = strdup(fname);                               // Set current filename (alloc storage)
        curlineno = 0;                                                  // Start on line zero
 
        // Add another file to the file-record
-       fr = (FILEREC *)malloc(sizeof(FILEREC));
+       FILEREC * fr = (FILEREC *)malloc(sizeof(FILEREC));
        fr->frec_next = NULL;
        fr->frec_name = curfname;
 
        if (last_fr == NULL)
-               filerec = fr;                                           // Add first filerec 
+               filerec = fr;                                           // Add first filerec
        else
-               last_fr->frec_next = fr;                        // Append to list of filerecs 
+               last_fr->frec_next = fr;                        // Append to list of filerecs
 
        last_fr = fr;
        DEBUG printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno);
@@ -768,7 +759,7 @@ if (debug)  printf("[fpop (pre):  curfname=%s]\n", curfname);
                        curfname = ifile->ifoldfname;   // Set current filename
 if (debug)     printf("[fpop (post): curfname=%s]\n", curfname);
 if (debug)     printf("[fpop: (pre)  cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno);
-                       curlineno = ifile->ifoldlineno; // Set current line# 
+                       curlineno = ifile->ifoldlineno; // Set current line#
                        DEBUG printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno);
                        cfileno = ifile->ifno;                  // Restore current file number
 if (debug)     printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno);
@@ -827,7 +818,7 @@ char * GetNextLine(void)
                                if (*p == '\r')
                                {
                                        if (i >= j)
-                                               break;  // Need to read more, then look for '\n' to eat 
+                                               break;  // Need to read more, then look for '\n' to eat
                                        else if (p[1] == '\n')
                                                i++;
                                }
@@ -928,7 +919,7 @@ retry:
                {
 if (debug) printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n");
                        if (fpop() == 0)                                // Pop input level
-                               goto retry;                                     // Try for more lines 
+                               goto retry;                                     // Try for more lines
                        else
                        {
                                ifent->if_prev = (IFENT *) - 1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs
@@ -1019,7 +1010,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                        ln++;
 
                // Handle EOL, comment with ';'
-               if (*ln == EOS || *ln == ';'|| ((*ln == '/') && (*(ln + 1) == '/'))) 
+               if (*ln == EOS || *ln == ';'|| ((*ln == '/') && (*(ln + 1) == '/')))
                        break;
 
                // Handle start of symbol. Symbols are null-terminated in place. The
@@ -1066,7 +1057,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                        if (*ln == '.')
                        {
                                *ln++ = EOS;            // Terminate symbol
-                               stuffnull = 0;          // And never try it again 
+                               stuffnull = 0;          // And never try it again
 
                                // Character following the `.' must have a DOT attribute, and
                                // the chararacter after THAT one must not have a start-symbol
@@ -1171,7 +1162,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                {
                        switch (*ln++)
                        {
-                       case '!':               // ! or != 
+                       case '!':               // ! or !=
                                if (*ln == '=')
                                {
                                        *tk++ = NE;
@@ -1181,8 +1172,8 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                        *tk++ = '!';
 
                                continue;
-                       case '\'':              // 'string' 
-                       case '\"':              // "string" 
+                       case '\'':              // 'string'
+                       case '\"':              // "string"
                                c1 = ln[-1];
                                *tk++ = STRING;
 //#warning
@@ -1325,7 +1316,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                        *tk++ = '$';
 
                                continue;
-                       case '<':               // < or << or <> or <= 
+                       case '<':               // < or << or <> or <=
                                switch (*ln)
                                {
                                case '<':
@@ -1354,7 +1345,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                        *tk++ = ':';
 
                                continue;
-                       case '=':               // = or == 
+                       case '=':               // = or ==
                                if (*ln == '=')
                                {
                                        *tk++ = DEQUALS;
@@ -1364,7 +1355,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                        *tk++ = '=';
 
                                continue;
-                       case '>':               // > or >> or >= 
+                       case '>':               // > or >> or >=
                                switch (*ln)
                                {
                                case '>':
@@ -1379,7 +1370,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                        *tk++ = '>';
                                        continue;
                                }
-                       case '%':               // % or binary constant 
+                       case '%':               // % or binary constant
                                if (*ln < '0' || *ln > '1')
                                {
                                        *tk++ = '%';
@@ -1414,7 +1405,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
                                *tk++ = CONST;
                                *tk++ = v;
                                continue;
-                       case '@':               // @ or octal constant 
+                       case '@':               // @ or octal constant
                                if (*ln < '0' || *ln > '7')
                                {
                                        *tk++ = '@';
@@ -1469,7 +1460,7 @@ if (debug) printf("TokenizeLine: Calling fpop() from SRC_IREPT...\n");
 
                                for(state=0; state>=0;)
                                {
-                                       // Get char, convert to lowercase 
+                                       // Get char, convert to lowercase
                                        j = *p++;
 
                                        if (j >= 'A' && j <= 'Z')
@@ -1559,15 +1550,15 @@ goteol:
 
 //
 // .GOTO <label>       goto directive
-// 
+//
 // The label is searched for starting from the first line of the current,
 // enclosing macro definition. If no enclosing macro exists, an error is
 // generated.
-// 
+//
 // A label is of the form:
-// 
+//
 // :<name><whitespace>
-// 
+//
 // The colon must appear in column 1.  The label is stripped prior to macro
 // expansion, and is NOT subject to macro expansion.  The whitespace may also
 // be EOL.
@@ -1594,7 +1585,6 @@ int d_goto(WORD unused)
        struct LineList * defln = imacro->im_macro->lineList;
 
        // Find the label, starting with the first line.
-//     for(; defln!=NULL; defln=(LONG *)*defln)
        for(; defln!=NULL; defln=defln->next)
        {
 //             if (*(char *)(defln + 1) == ':')
diff --git a/token.h b/token.h
index c44989c09f7ca99651f9287432c23828b8e909e7..1deec2c96d922e8901df746f9c76ece4a6c0fc98 100644 (file)
--- a/token.h
+++ b/token.h
@@ -1,7 +1,7 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // TOKEN.H - Token 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
 //
 #define SET             149                                    // Set
 #define REG             'R'                                    // Reg
 #define DCOLON          'h'                                    // ::
-#define GE              'i'                                    // >= 
-#define LE              'j'                                    // <= 
-#define NE              'k'                                    // <> or != 
-#define SHR             'l'                                    // >> 
-#define SHL             'm'                                    // << 
-#define UNMINUS         'n'                                    // Unary '-' 
-#define DOTB            'B'                                    // .b or .B or .s or .S 
-#define DOTW            'W'                                    // .w or .W 
-#define DOTL            'L'                                    // .l or .L 
-#define DOTI            'I'                                    // .l or .L 
-#define ENDEXPR         'E'                                    // End of expression 
+#define GE              'i'                                    // >=
+#define LE              'j'                                    // <=
+#define NE              'k'                                    // <> or !=
+#define SHR             'l'                                    // >>
+#define SHL             'm'                                    // <<
+#define UNMINUS         'n'                                    // Unary '-'
+#define DOTB            'B'                                    // .b or .B or .s or .S
+#define DOTW            'W'                                    // .w or .W
+#define DOTL            'L'                                    // .l or .L
+#define DOTI            'I'                                    // .l or .L
+#define ENDEXPR         'E'                                    // End of expression
 
 // ^^ operators
 #define CR_DEFINED      'p'                                    // ^^defined - is symbol defined?
@@ -104,7 +104,7 @@ IFILE {
        char * ifoldfname;              // Old file's name
        int ifoldlineno;                // Old line number
        int ifind;                              // Position in file buffer
-       int ifcnt;                              // #chars left in file buffer 
+       int ifcnt;                              // #chars left in file buffer
        int ifhandle;                   // File's descriptor
        WORD ifno;                              // File number
        char ifbuf[LNBUFSIZ];   // Line buffer
@@ -137,7 +137,7 @@ IREPT {
        VALUE ir_count;                 // Repeat count (decrements)
 };
 
-// Globals, externals etc
+// Exported variables
 extern int lnsave;
 extern int curlineno;
 extern char * curfname;
@@ -153,7 +153,7 @@ extern LONG sloc;
 extern int mjump_align;
 extern char * string[];
 
-// Prototypes
+// Exported functions
 int include(int, char *);
 void InitTokenizer(void);
 void SetFilenameForErrorReporting(void);
index b24415fedc2a08c12622c1bd57b5417ad3d03841..a00f607f7e3bc78c9edadd18521dcb85783167f4 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,10 +1,12 @@
 //
 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
 // VERSION.H - Version Information
-// Copyright (C) 199x Landon Dyer, 2011 - 2017 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
 //
+// Contributors: James Hammons, George Nakos, Graeme Hinchliffe, SCPCD
+//
 
 #ifndef __VERSION_H__
 #define __VERSION_H__
@@ -12,7 +14,8 @@
 // Release Information
 
 #define MAJOR   1              // Major version number
-#define MINOR   4              // Minor version number
-#define PATCH   21             // Patch release number
+#define MINOR   5              // Minor version number
+#define PATCH                // Patch release number
 
 #endif // __VERSION_H__
+