]> Shamusworld >> Repos - rmac/blobdiff - riscasm.c
Fixes for last commit; version is now 1.10.0.
[rmac] / riscasm.c
index 78bae9c290a3f506088050a3644de1546e4fe142..a76cb2e19a1438310e38939571546a29cc1569cb 100644 (file)
--- a/riscasm.c
+++ b/riscasm.c
@@ -1,29 +1,30 @@
 //
-// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
+// RMAC - Reboot's Macro Assembler for all Atari computers
 // RISCA.C - GPU/DSP Assembler
-// Copyright (C) 199x Landon Dyer, 2011 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
 //
 
 #include "riscasm.h"
+#include "amode.h"
+#include "direct.h"
 #include "error.h"
-#include "sect.h"
-#include "token.h"
 #include "expr.h"
-#include "direct.h"
 #include "mark.h"
-#include "amode.h"
+#include "procln.h"
+#include "sect.h"
+#include "token.h"
 
 #define DEF_MR                         // Declare keyword values
 #include "risckw.h"                    // Incl. generated risc keywords
 
-#define DEF_KW                         // Declare keyword values 
+#define DEF_KW                         // Declare keyword values
 #include "kwtab.h"                     // Incl. generated keyword tables & defs
 
 
 unsigned altbankok = 0;                // Ok to use alternate register bank
-unsigned orgactive = 0;                // RISC org directive active
+unsigned orgactive = 0;                // RISC/6502 org directive active
 unsigned orgaddr = 0;          // Org'd address
 unsigned orgwarning = 0;       // Has an ORG warning been issued
 int lastOpcode = -1;           // Last RISC opcode assembled
@@ -32,7 +33,7 @@ uint8_t riscImmTokenSeen;     // The '#' (immediate) token was seen
 const char reg_err[] = "missing register R0...R31";
 
 // Jaguar jump condition names
-const char condname[MAXINTERNCC][5] = { 
+const char condname[MAXINTERNCC][5] = {
        "NZ", "Z", "NC", "NCNZ", "NCZ", "C", "CNZ", "CZ", "NN", "NNNZ", "NNZ",
        "N", "N_NZ", "N_Z", "T", "A", "NE", "EQ", "CC", "HS", "HI", "CS", "LO",
        "PL", "MI", "F"
@@ -126,9 +127,27 @@ void strtoupper(char * s)
 //
 static inline int MalformedOpcode(int signal)
 {
-       char buf[16];
-       sprintf(buf, "%02X", signal);
-       return errors("Malformed opcode [internal $%s]", buf);
+       return error("Malformed opcode [internal $%02X]", signal);
+}
+
+
+//
+// Function to return "Illegal Indexed Register" error
+// Anyone trying to index something other than R14 or R15
+//
+static inline int IllegalIndexedRegister(int reg)
+{
+       return error("Attempted index reference with non-indexable register (r%d)", reg - KW_R0);
+}
+
+
+//
+// Function to return "Illegal Indexed Register" error for EQUR scenarios
+// Trying to use register value within EQUR that isn't 14 or 15
+//
+static inline int IllegalIndexedRegisterEqur(SYM * sy)
+{
+       return error("Attempted index reference with non-indexable register within EQUR (%s = r%d)", sy->sname, sy->svalue);
 }
 
 
@@ -155,13 +174,13 @@ void BuildRISCIntructionWord(unsigned short opcode, int reg1, int reg2)
 //
 int GetRegister(WORD rattr)
 {
-       VALUE eval;                                     // Expression value
+       uint64_t eval;                          // Expression value
        WORD eattr;                                     // Expression attributes
        SYM * esym;                                     // External symbol involved in expr.
        TOKEN r_expr[EXPRSIZE];         // Expression token list
 
        // Evaluate what's in the global "tok" buffer
-       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+       if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
                return ERROR;
 
        if ((challoc - ch_size) < 4)
@@ -169,13 +188,13 @@ int GetRegister(WORD rattr)
 
        if (!(eattr & DEFINED))
        {
-               AddFixup((WORD)(FU_WORD | rattr), sloc, r_expr);      
+               AddFixup((WORD)(FU_WORD | rattr), sloc, (TOKENPTR)r_expr);
                return 0;
        }
 
        // If we got a register in range (0-31), return it
        if ((eval >= 0) && (eval <= 31))
-               return eval;
+               return (int)eval;
 
        // Otherwise, it's out of range & we flag an error
        return error(reg_err);
@@ -198,7 +217,7 @@ int GenerateRISCCode(int state)
        WORD attrflg;
        int indexed;                            // Indexed register flag
 
-       VALUE eval;                                     // Expression value
+       uint64_t eval;                          // Expression value
        WORD eattr;                                     // Expression attributes
        SYM * esym;                                     // External symbol involved in expr.
        TOKEN r_expr[EXPRSIZE];         // Expression token list
@@ -230,17 +249,17 @@ int GenerateRISCCode(int state)
                reg2 = GetRegister(FU_REGTWO);
                at_eol();
                BuildRISCIntructionWord(parm, parm >> 6, reg2);
-               break;   
+               break;
 
        // Two operand instructions (Rs,Rd)
        // ADD, ADDC, AND, CMP, DIV, IMACN, IMULT, IMULTN, MOVEFA, MOVETA, MULT,
        // MMULT, MTOI, NORMI, OR, ROR, SH, SHA, SUB, SUBC, XOR
-       case RI_TWO:                      
+       case RI_TWO:
                if (parm == 37)
                        altbankok = 1;                      // MOVEFA
 
                reg1 = GetRegister(FU_REGONE);
-               CHECK_COMMA;         
+               CHECK_COMMA;
 
                if (parm == 36)
                        altbankok = 1;                      // MOVETA
@@ -279,13 +298,13 @@ int GenerateRISCCode(int state)
                if (parm & SUB32)
                        attrflg |= FU_SUB32;
 
-               if (*tok != '#')
+               if (*tok.u32 != '#')
                        return MalformedOpcode(0x01);
 
-               tok++;
+               tok.u32++;
                riscImmTokenSeen = 1;
 
-               if (expr(r_expr, &eval, &eattr, &esym) != OK)
+               if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
                        return MalformedOpcode(0x02);
 
                if ((challoc - ch_size) < 4)
@@ -293,7 +312,7 @@ int GenerateRISCCode(int state)
 
                if (!(eattr & DEFINED))
                {
-                       AddFixup((WORD)(FU_WORD | attrflg), sloc, r_expr);
+                       AddFixup((WORD)(FU_WORD | attrflg), sloc, (TOKENPTR)r_expr);
                        reg1 = 0;
                }
                else
@@ -301,12 +320,12 @@ int GenerateRISCCode(int state)
                        if ((int)eval < reg1 || (int)eval > reg2)
                                return error("constant out of range");
 
-                       if (parm & SUB32) 
-                               reg1 = 32 - eval; 
+                       if (parm & SUB32)
+                               reg1 = 32 - (int)eval;
                        else if (type == RI_NUM_32)
-                               reg1 = (reg1 == 32 ? 0 : eval);
+                               reg1 = (reg1 == 32 ? 0 : (int)eval);
                        else
-                               reg1 = eval;
+                               reg1 = (int)eval;
                }
 
                CHECK_COMMA;
@@ -317,22 +336,22 @@ int GenerateRISCCode(int state)
 
        // Move Immediate--n,Rn--n in Second Word
        case RI_MOVEI:
-               if (*tok != '#')
+               if (*tok.u32 != '#')
                        return MalformedOpcode(0x03);
 
-               tok++;
+               tok.u32++;
                riscImmTokenSeen = 1;
 
                // Check for equated register after # and return error if so
-               if (*tok == SYMBOL)
+               if (*tok.u32 == SYMBOL)
                {
-                       sy = lookup(string[tok[1]], LABEL, 0);
+                       sy = lookup(string[tok.u32[1]], LABEL, 0);
 
                        if (sy && (sy->sattre & EQUATEDREG))
                                return error("equated register in 1st operand of MOVEI instruction");
                }
 
-               if (expr(r_expr, &eval, &eattr, &esym) != OK)
+               if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
                        return MalformedOpcode(0x04);
 
                if (lastOpcode == RI_JUMP || lastOpcode == RI_JR)
@@ -352,19 +371,20 @@ int GenerateRISCCode(int state)
 
                if (!(eattr & DEFINED))
                {
-                       AddFixup(FU_LONG | FU_MOVEI, sloc + 2, r_expr);
+                       AddFixup(FU_LONG | FU_MOVEI, sloc + 2, (TOKENPTR)r_expr);
                        eval = 0;
                }
                else
                {
                        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();
@@ -374,11 +394,11 @@ int GenerateRISCCode(int state)
 
        // PC,Rd or Rs,Rd
        case RI_MOVE:
-               if (*tok == KW_PC)
+               if (*tok.u32 == KW_PC)
                {
                        parm = 51;
                        reg1 = 0;
-                       tok++;
+                       tok.u32++;
                }
                else
                {
@@ -393,22 +413,28 @@ int GenerateRISCCode(int state)
                break;
 
        // (Rn),Rn = 41 / (R14/R15+n),Rn = 43/44 / (R14/R15+Rn),Rn = 58/59
-       case RI_LOAD:          
+       case RI_LOAD:
                indexed = 0;
                parm = 41;
 
-               if (*tok != '(')
+               if (*tok.u32 != '(')
                        return MalformedOpcode(0x05);
 
-               tok++;
+               tok.u32++;
 
-               if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok + 1) != ')')) 
-                       indexed = (*tok - KW_R0);
+        if ((*(tok.u32 + 1) == '+') || (*(tok.u32 + 1) == '-')) {
+            // Trying to make indexed call
+            if ((*tok.u32 == KW_R14 || *tok.u32 == KW_R15)) {
+                indexed = (*tok.u32 - KW_R0);
+            } else {
+                return IllegalIndexedRegister(*tok.u32);
+            }
+        }
 
-               if (*tok == SYMBOL)
+               if (*tok.u32 == SYMBOL)
                {
-//                     sy = lookup((char *)tok[1], LABEL, 0);
-                       sy = lookup(string[tok[1]], LABEL, 0);
+//                     sy = lookup((char *)tok.u32[1], LABEL, 0);
+                       sy = lookup(string[tok.u32[1]], LABEL, 0);
 
                        if (!sy)
                        {
@@ -418,11 +444,13 @@ int GenerateRISCCode(int state)
 
                        if (sy->sattre & EQUATEDREG)
                        {
-                               if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15)
-                                       && (*(tok + 2) != ')'))
-                               {
-                                       indexed = (sy->svalue & 0x1F);
-                                       tok++;
+                               if ((*(tok.u32 + 2) == '+') || (*(tok.u32 + 2) == '-')) {
+                                   if ((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) {
+                                       indexed = (sy->svalue & 0x1F);
+                        tok.u32++;
+                                   } else {
+                                       return IllegalIndexedRegisterEqur(sy);
+                                   }
                                }
                        }
                }
@@ -435,20 +463,20 @@ int GenerateRISCCode(int state)
                {
                        reg1 = indexed;
                        indexed = 0;
-                       tok++;
+                       tok.u32++;
 
-                       if (*tok == '+')
+                       if (*tok.u32 == '+')
                        {
                                parm = (WORD)(reg1 - 14 + 58);
-                               tok++;
+                               tok.u32++;
 
-                               if (*tok >= KW_R0 && *tok <= KW_R31)
+                               if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31)
                                        indexed = 1;
 
-                               if (*tok == SYMBOL)
+                               if (*tok.u32 == SYMBOL)
                                {
-//                                     sy = lookup((char *)tok[1], LABEL, 0);
-                                       sy = lookup(string[tok[1]], LABEL, 0);
+//                                     sy = lookup((char *)tok.u32[1], LABEL, 0);
+                                       sy = lookup(string[tok.u32[1]], LABEL, 0);
 
                                        if (!sy)
                                        {
@@ -466,7 +494,7 @@ int GenerateRISCCode(int state)
                                }
                                else
                                {
-                                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                                       if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
                                                return MalformedOpcode(0x06);
 
                                        if ((challoc - ch_size) < 4)
@@ -475,7 +503,7 @@ int GenerateRISCCode(int state)
                                        if (!(eattr & DEFINED))
                                                return error("constant expected after '+'");
 
-                                       reg1 = eval;
+                                       reg1 = (int)eval;
 
                                        if (reg1 == 0)
                                        {
@@ -501,10 +529,10 @@ int GenerateRISCCode(int state)
                        }
                }
 
-               if (*tok != ')')
+               if (*tok.u32 != ')')
                        return MalformedOpcode(0x07);
 
-               tok++;
+               tok.u32++;
                CHECK_COMMA;
                reg2 = GetRegister(FU_REGTWO);
                at_eol();
@@ -512,23 +540,23 @@ int GenerateRISCCode(int state)
                break;
 
        // Rn,(Rn) = 47 / Rn,(R14/R15+n) = 49/50 / Rn,(R14/R15+Rn) = 60/61
-       case RI_STORE:    
+       case RI_STORE:
                parm = 47;
                reg1 = GetRegister(FU_REGONE);
                CHECK_COMMA;
 
-               if (*tok != '(')
+               if (*tok.u32 != '(')
                        return MalformedOpcode(0x08);
 
-               tok++;
+               tok.u32++;
                indexed = 0;
 
-               if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok + 1) != ')')) 
-                       indexed = (*tok - KW_R0);
+               if ((*tok.u32 == KW_R14 || *tok.u32 == KW_R15) && (*(tok.u32 + 1) != ')'))
+                       indexed = (*tok.u32 - KW_R0);
 
-               if (*tok == SYMBOL)
+               if (*tok.u32 == SYMBOL)
                {
-                       sy = lookup(string[tok[1]], LABEL, 0);
+                       sy = lookup(string[tok.u32[1]], LABEL, 0);
 
                        if (!sy)
                        {
@@ -536,13 +564,13 @@ int GenerateRISCCode(int state)
                                return ERROR;
                        }
 
-                       if (sy->sattre & EQUATEDREG) 
+                       if (sy->sattre & EQUATEDREG)
                        {
                                if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15)
-                                       && (*(tok + 2) != ')'))
+                                       && (*(tok.u32 + 2) != ')'))
                                {
                                        indexed = (sy->svalue & 0x1F);
-                                       tok++;
+                                       tok.u32++;
                                }
                        }
                }
@@ -555,19 +583,19 @@ int GenerateRISCCode(int state)
                {
                        reg2 = indexed;
                        indexed = 0;
-                       tok++;
+                       tok.u32++;
 
-                       if (*tok == '+')
+                       if (*tok.u32 == '+')
                        {
                                parm = (WORD)(reg2 - 14 + 60);
-                               tok++;
+                               tok.u32++;
 
-                               if (*tok >= KW_R0 && *tok <= KW_R31)
+                               if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31)
                                        indexed = 1;
 
-                               if (*tok == SYMBOL)
+                               if (*tok.u32 == SYMBOL)
                                {
-                                       sy = lookup(string[tok[1]], LABEL, 0);
+                                       sy = lookup(string[tok.u32[1]], LABEL, 0);
 
                                        if (!sy)
                                        {
@@ -585,7 +613,7 @@ int GenerateRISCCode(int state)
                                }
                                else
                                {
-                                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                                       if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
                                                return MalformedOpcode(0x09);
 
                                        if ((challoc - ch_size) < 4)
@@ -593,12 +621,12 @@ int GenerateRISCCode(int state)
 
                                        if (!(eattr & DEFINED))
                                        {
-                                               AddFixup(FU_WORD | FU_REGTWO, sloc, r_expr);
+                                               AddFixup(FU_WORD | FU_REGTWO, sloc, (TOKENPTR)r_expr);
                                                reg2 = 0;
                                        }
                                        else
                                        {
-                                               reg2 = eval;
+                                               reg2 = (int)eval;
 
                                                if (reg2 == 0)
                                                {
@@ -625,26 +653,26 @@ int GenerateRISCCode(int state)
                        }
                }
 
-               if (*tok != ')')
+               if (*tok.u32 != ')')
                        return MalformedOpcode(0x0A);
 
-               tok++;
+               tok.u32++;
                at_eol();
                BuildRISCIntructionWord(parm, reg2, reg1);
                break;
 
        // LOADB/LOADP/LOADW (Rn),Rn
-       case RI_LOADN:                    
-               if (*tok != '(')
+       case RI_LOADN:
+               if (*tok.u32 != '(')
                        return MalformedOpcode(0x0B);
 
-               tok++;
+               tok.u32++;
                reg1 = GetRegister(FU_REGONE);
 
-               if (*tok != ')')
+               if (*tok.u32 != ')')
                        return MalformedOpcode(0x0C);
 
-               tok++;
+               tok.u32++;
                CHECK_COMMA;
                reg2 = GetRegister(FU_REGTWO);
                at_eol();
@@ -652,20 +680,20 @@ int GenerateRISCCode(int state)
                break;
 
        // STOREB/STOREP/STOREW Rn,(Rn)
-       case RI_STOREN:                   
+       case RI_STOREN:
                reg1 = GetRegister(FU_REGONE);
                CHECK_COMMA;
 
-               if (*tok != '(')
+               if (*tok.u32 != '(')
                        return MalformedOpcode(0x0D);
 
-               tok++;
+               tok.u32++;
                reg2 = GetRegister(FU_REGTWO);
 
-               if (*tok != ')')
+               if (*tok.u32 != ')')
                        return MalformedOpcode(0x0E);
 
-               tok++;
+               tok.u32++;
                at_eol();
                BuildRISCIntructionWord(parm, reg2, reg1);
                break;
@@ -679,7 +707,7 @@ int GenerateRISCCode(int state)
                // the JR or JUMP should default to 0, Jump Always
                commaFound = 0;
 
-               for(t=tok; *t!=EOL; t++)
+               for(t=tok.u32; *t!=EOL; t++)
                {
                        if (*t == ',')
                        {
@@ -690,19 +718,20 @@ int GenerateRISCCode(int state)
 
                if (commaFound)
                {
-                       if (*tok == CONST)
+                       if (*tok.u32 == CONST)
                        {
                                // CC using a constant number
-                               tok++;
-                               val = *tok;
-                               tok++;
+                               tok.u32++;
+                               uint64_t *tok64 = (uint64_t *)tok.u32;
+                               val = (int)*tok64++;
+                               tok.u32 = (uint32_t *)tok64;
                                CHECK_COMMA;
                        }
-                       else if (*tok == SYMBOL)
+                       else if (*tok.u32 == SYMBOL)
                        {
                                val = 99;
-//                             strcpy(scratch, (char *)tok[1]);
-                               strcpy(scratch, string[tok[1]]);
+//                             strcpy(scratch, (char *)tok.u32[1]);
+                               strcpy(scratch, string[tok.u32[1]]);
                                strtoupper(scratch);
 
                                for(i=0; i<MAXINTERNCC; i++)
@@ -718,21 +747,19 @@ int GenerateRISCCode(int state)
                                // Standard CC was not found, look for an equated one
                                if (val == 99)
                                {
-//                                     ccsym = lookup((char *)tok[1], LABEL, 0);
-                                       ccsym = lookup(string[tok[1]], LABEL, 0);
+//                                     ccsym = lookup((char *)tok.u32[1], LABEL, 0);
+                                       ccsym = lookup(string[tok.u32[1]], LABEL, 0);
 
                                        if (ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC))
-                                       {
                                                val = ccsym->svalue;
-                                       }
                                        else
                                                return error("unknown condition code");
                                }
 
-                               tok += 2;
+                               tok.u32 += 2;
                                CHECK_COMMA;
                        }
-                       else if (*tok == '(')
+                       else if (*tok.u32 == '(')
                        {
                                // Set CC to "Jump Always"
                                val = 0;
@@ -753,7 +780,7 @@ int GenerateRISCCode(int state)
                if (type == RI_JR)
                {
                        // JR cc,n
-                       if (expr(r_expr, &eval, &eattr, &esym) != OK)
+                       if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
                                return MalformedOpcode(0x0F);
 
                        if ((challoc - ch_size) < 4)
@@ -761,7 +788,7 @@ int GenerateRISCCode(int state)
 
                        if (!(eattr & DEFINED))
                        {
-                               AddFixup(FU_WORD | FU_JR, sloc, r_expr);
+                               AddFixup(FU_WORD | FU_JR, sloc, (TOKENPTR)r_expr);
                                reg2 = 0;
                        }
                        else
@@ -769,7 +796,7 @@ int GenerateRISCCode(int state)
                                reg2 = ((int)(eval - ((orgactive ? orgaddr : sloc) + 2))) / 2;
 
                                if ((reg2 < -16) || (reg2 > 15))
-                                       error("PC relative overflow");
+                                       error("PC relative overflow (outside of -16 to 15)");
                        }
 
                        BuildRISCIntructionWord(parm, reg2, reg1);
@@ -777,16 +804,16 @@ int GenerateRISCCode(int state)
                else
                {
                        // JUMP cc, (Rn)
-                       if (*tok != '(')
+                       if (*tok.u32 != '(')
                                return MalformedOpcode(0x10);
 
-                       tok++;
+                       tok.u32++;
                        reg2 = GetRegister(FU_REGTWO);
 
-                       if (*tok != ')')
+                       if (*tok.u32 != ')')
                                return MalformedOpcode(0x11);
 
-                       tok++;
+                       tok.u32++;
                        at_eol();
                        BuildRISCIntructionWord(parm, reg2, reg1);
                }