Fix for bug #29.
authorShamus Hammons <jlhamm@acm.org>
Fri, 14 Nov 2014 04:26:00 +0000 (22:26 -0600)
committerShamus Hammons <jlhamm@acm.org>
Fri, 14 Nov 2014 04:26:00 +0000 (22:26 -0600)
Whoever put this stuff together made a HUGE mistake in its alignment
pseudo-ops. Basically, before this fix, alignment directives in a RISC
section had absolutely NO guarantees of efficacy. This is what happens
when you bodge things together without extensive testing! Note that if
you had some RISC code that you had to wave a dead chicken at to get it
to work, it will probably not work any longer as the assembler will now
do what you tell it to. ;-)

This is a big enough change that it merits a minor version bump; we're
now at 1.3.0. :-)

direct.c
makefile
sect.h
version.h

index efec94a2f438fd63d3a3931f14567cfea8efa690..77fda019a62dd459a106f98959aac8be486a769b 100644 (file)
--- a/direct.c
+++ b/direct.c
@@ -108,7 +108,8 @@ int d_org(void)
        }
 
        orgaddr = address;
-       orgactive = 1;  
+       orgactive = 1;
+//printf("ORG: address = $%08X...\n", orgaddr);
 
        return 0;
 }
@@ -312,7 +313,6 @@ int d_incbin(void)
 
        if (*tok != STRING)
        {
-//             error(syntax_error);
                error("syntax error; string missing");
                return ERROR;
        }
@@ -339,7 +339,6 @@ int d_incbin(void)
                return ERROR;
        }
 
-//#define D_byte(b)    {*chptr++=(char)b; ++sloc; ++ch_size; if(orgactive) ++orgaddr;}
        memcpy(chptr, fileBuffer, size);
        chptr += size;
        sloc += size;
@@ -373,12 +372,38 @@ int d_regbank1(void)
 }
 
 
+//
+// Helper function, to cut down on mistakes & typing
+//
+static inline void SkipBytes(unsigned bytesToSkip)
+{
+       if (!bytesToSkip)
+               return;
+
+       if ((scattr & SBSS) == 0)
+       {
+               chcheck(bytesToSkip);
+               D_ZEROFILL(bytesToSkip);
+       }
+       else
+       {
+               sloc += bytesToSkip;
+
+               if (orgactive)
+                       orgaddr += bytesToSkip;
+       }
+}
+
+
 //
 // Adjust Location to an EVEN Value
 //
 int d_even(void)
 {
-       if (sloc & 1)
+       unsigned skip = (rgpu || rdsp ? orgaddr : sloc) & 0x01;
+       
+//     if (sloc & 1)
+       if (skip)
        {
                if ((scattr & SBSS) == 0)
                {
@@ -387,7 +412,10 @@ int d_even(void)
                }
                else
                {
-                       ++sloc;
+                       sloc++;
+
+                       if (orgactive)
+                               orgaddr++;
                }
        }
 
@@ -400,30 +428,9 @@ int d_even(void)
 //
 int d_long(void)
 {
-       unsigned i;
-       unsigned val = 4;
-                       
-       i = sloc & ~(val - 1);
-
-       if (i != sloc)
-               val = val - (sloc - i); 
-       else
-               val = 0;
-
-       if (val)
-       {
-               if ((scattr & SBSS) == 0)
-               {
-                       chcheck(val);
-
-                       for(i=0; i<val; i++) 
-                               D_byte(0);
-               }
-               else
-               {
-                       sloc += val;
-               }
-       }
+       unsigned lower2Bits = (rgpu || rdsp ? orgaddr : sloc) & 0x03;
+       unsigned bytesToSkip = (0x04 - lower2Bits) & 0x03;
+       SkipBytes(bytesToSkip);
 
        return 0;
 }
@@ -432,32 +439,20 @@ int d_long(void)
 //
 // Adjust Location to an PHRASE Value
 //
+// N.B.: We have to handle the GPU/DSP cases separately because you can embed
+//       RISC code in the middle of a regular 68K section. Also note that all
+//       of the alignment pseudo-ops will have to be fixed this way.
+//
+// This *must* behave differently when in a RISC section, as following sloc
+// (instead of orgaddr) will fuck things up royally. Note that we do it this
+// way because you can embed RISC code in a 68K section, and have the origin
+// pointing to a different alignment in the RISC section than the 68K section.
+//
 int d_phrase(void)
 {
-       unsigned i;
-       unsigned val = 8;
-                       
-       i = sloc & ~(val - 1);
-
-       if (i != sloc)
-               val = val - (sloc - i); 
-       else
-               val = 0;
-
-       if (val)
-       {
-               if ((scattr & SBSS) == 0)
-               {
-                       chcheck(val);
-
-                       for(i=0; i<val; i++) 
-                               D_byte(0);
-               }
-               else
-               {
-                       sloc += val;
-               }
-       }
+       unsigned lower3Bits = (rgpu || rdsp ? orgaddr : sloc) & 0x07;
+       unsigned bytesToSkip = (0x08 - lower3Bits) & 0x07;
+       SkipBytes(bytesToSkip);
 
        return 0;
 }
@@ -468,30 +463,9 @@ int d_phrase(void)
 //
 int d_dphrase(void)
 {
-       unsigned i;
-       unsigned val = 16;
-                       
-       i = sloc & ~(val - 1);
-
-       if (i != sloc)
-               val = val - (sloc - i); 
-       else
-               val = 0;
-
-       if (val)
-       {
-               if ((scattr & SBSS) == 0)
-               {
-                       chcheck(val);
-
-                       for(i=0; i<val; i++) 
-                               D_byte(0);
-               }
-               else
-               {
-                       sloc += val;
-               }
-       }
+       unsigned lower4Bits = (rgpu || rdsp ? orgaddr : sloc) & 0x0F;
+       unsigned bytesToSkip = (0x10 - lower4Bits) & 0x0F;
+       SkipBytes(bytesToSkip);
 
        return 0;
 }
@@ -502,31 +476,9 @@ int d_dphrase(void)
 //
 int d_qphrase(void)
 {
-       unsigned i;
-       unsigned val = 32;
-                       
-       i = sloc & ~(val - 1);
-
-       if (i != sloc)
-               val = val - (sloc - i); 
-       else
-               val = 0;
-
-       if (val)
-       {
-               if ((scattr & SBSS) == 0)
-               {
-                       SaveSection();
-                       chcheck(val);
-
-                       for(i=0; i<val; i++) 
-                               D_byte(0);
-               }
-               else
-               {
-                       sloc += val;
-               }
-       }
+       unsigned lower5Bits = (rgpu || rdsp ? orgaddr : sloc) & 0x1F;
+       unsigned bytesToSkip = (0x20 - lower5Bits) & 0x1F;
+       SkipBytes(bytesToSkip);
 
        return 0;
 }
@@ -540,14 +492,16 @@ int d_qphrase(void)
 // which is OK since multiple labels are only allowed in AS68 kludge mode, and
 // the C compiler is VERY paranoid and uses ".even" whenever it can
 //
+// N.B.: This probably needs the same fixes as above...
+//
 void auto_even(void)
 {
        if (scattr & SBSS)
-               ++sloc;                                               // Bump BSS section
+               sloc++;                           // Bump BSS section
        else
-               D_byte(0)                                             // Deposit 0.b in non-BSS
+               D_byte(0);                        // Deposit 0.b in non-BSS
 
-       if (lab_sym != NULL)                                      // Bump label if we have to
+       if (lab_sym != NULL)                  // Bump label if we have to
                ++lab_sym->svalue;
 }
 
@@ -1238,9 +1192,11 @@ int d_gpu(void)
        // If previous section was dsp or 68000 then we need to reset ORG'd Addresses
        if (!rgpu)
        {
+//printf("Resetting ORG...\n");
                orgactive = 0;
                orgwarning = 0;
        }
+//else printf("NOT resetting ORG!\n");
 
        rgpu = 1;                       // Set GPU assembly
        rdsp = 0;                       // Unset DSP assembly
index 8b46eed9cd6273ac53d3533d1ad275dfe0c5fbad..def563cb1c9ccb50318c1a5136316fbb5f6a2026 100644 (file)
--- a/makefile
+++ b/makefile
@@ -20,6 +20,9 @@ OBJS = amode.o debug.o direct.o eagen.o error.o expr.o listing.o mach.o macro.o
 #
 
 all : mntab.h 68ktab.h kwtab.h risckw.h rmac
+       @echo
+       @echo "Don't forget to bump the version number before commiting!"
+       @echo
 
 #
 # Generated Sources for State Machines and Keyword, Directive and Mnemonic Definitions
diff --git a/sect.h b/sect.h
index 8759eda1dcbd9c41a996f1a5be7fae3847d1c08b..f7c3aafd8a3fde6c5c4a876230a3afb3ec01422a 100644 (file)
--- a/sect.h
+++ b/sect.h
@@ -25,6 +25,9 @@
 //#define D_rlong(lw)  {*chptr++=(char)(lw>>16);*chptr++=(char)(lw>>24);\
 //                                             *chptr++=(char)lw;*chptr++=(char)(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
 
index 75e1c569e74a497e94e24941c05b2ca1a637cfb9..b49b4ae014ce396abaf738b92a38d1d2090a0a4e 100644 (file)
--- a/version.h
+++ b/version.h
@@ -12,7 +12,7 @@
 // Release Information
 
 #define MAJOR   1                      // Major version number
-#define MINOR   2                      // Minor version number
-#define PATCH   15                     // Patch release number
+#define MINOR   3                      // Minor version number
+#define PATCH                        // Patch release number
 
 #endif // __VERSION_H__