]> Shamusworld >> Repos - rmac/blobdiff - 6502.c
Fixes for last commit; version is now 1.10.0.
[rmac] / 6502.c
diff --git a/6502.c b/6502.c
index afc0ba1aa5839ce577b3321604ed1cfff7d1acc4..711435e1bac68f7205fc5b50390f3e4b3e8c5397 100644 (file)
--- a/6502.c
+++ b/6502.c
@@ -1,5 +1,9 @@
 //
-// 6502 Assembler
+// RMAC - Reboot's Macro Assembler for all Atari computers
+// 6502.C - 6502 Assembler
+// 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
 //
 //    Init6502 initialization
 //    d_6502    handle ".6502" directive
@@ -25,6 +29,7 @@ static uint16_t orgmap[1024][2];              // Mark all 6502 org changes
 // Exported vars
 const char in_6502mode[] = "directive illegal in .6502 section";
 uint16_t * currentorg = &orgmap[0][0]; // Current org range
+char strtoa8[128];     // ASCII to Atari 800 internal conversion table
 
 //
 // 6502 addressing modes;
@@ -145,6 +150,22 @@ static int abs2zp[] =
        -1                      // ZPY
 };
 
+static char a8internal[] =
+{
+    ' ', 0,   '!', 1,   '"', 2,   '#', 3,   '$',  4,   '%', 5,   '&', 6,   '\'', 7,
+    '(', 8,   ')', 9,   '*', 10,  '+', 11,  ',',  12,  '-', 13,  '.', 14,  '/',  15,
+    '0', 16,  '1', 17,  '2', 18,  '3', 19,  '4',  20,  '5', 21,  '6', 22,  '7',  23,
+    '8', 24,  '9', 25,  ':', 26,  ';', 27,  '<',  28,  '=', 29,  '>', 30,  '?',  31,
+    '@', 32,  'A', 33,  'B', 34,  'C', 35,  'D',  36,  'E', 37,  'F', 38,  'G',  39,
+    'H', 40,  'I', 41,  'J', 42,  'K', 43,  'L',  44,  'M', 45,  'N', 46,  'O',  47,
+    'P', 48,  'Q', 49,  'R', 50,  'S', 51,  'T',  52,  'U', 53,  'V', 54,  'W',  55,
+    'X', 56,  'Y', 57,  'Z', 58,  '[', 59,  '\\', 60,  ']', 61,  '^', 62,  '_',  63,
+    'a', 97,  'b', 98,  'c', 99,  'd', 100, 'e',  101, 'f', 102, 'g', 103, 'h',  104,
+    'i', 105, 'j', 106, 'k', 107, 'l', 108, 'm',  109, 'n', 110, 'o', 111, 'p',  112,
+    'q', 113, 'r', 114, 's', 115, 't', 116, 'u',  117, 'v', 118, 'w', 119, 'x',  120,
+    'y', 121, 'z', 122
+};
+
 
 //
 // Initialize 6502 assembler
@@ -186,6 +207,24 @@ void Init6502()
 
        // Set up first org section (set to zero)
        orgmap[0][0] = 0;
+
+       SwitchSection(M6502);   // Switch to 6502 section
+
+       // Initialise string conversion table(s)
+       char * p = a8internal;
+       memset(strtoa8, 31, 128);   // 31=fallback value ("?")
+
+       for(; p<a8internal+sizeof(a8internal); p+=2)
+               strtoa8[p[0]] = p[1];
+
+       if (challoc == 0)
+       {
+               // Allocate and clear 64K of space for the 6502 section
+               chcheck(UPSEG_SIZE);
+               memset(sect[M6502].scode->chptr, 0, UPSEG_SIZE);
+       }
+
+       SwitchSection(TEXT);    // Go back to TEXT
 }
 
 
@@ -197,13 +236,6 @@ int d_6502()
        SaveSection();                  // Save curent section
        SwitchSection(M6502);   // Switch to 6502 section
 
-       if (challoc == 0)
-       {
-               // Allocate and clear 64K of space for the 6502 section
-               chcheck(UPSEG_SIZE);
-               memset(sect[M6502].scode->chptr, 0, UPSEG_SIZE);
-       }
-
        return 0;
 }
 
@@ -215,7 +247,7 @@ void m6502cg(int op)
 {
        register int amode;             // (Parsed) addressing mode
        register int i;
-       VALUE eval;                             // Expression value
+       uint64_t eval;                  // Expression value
        WORD eattr;                             // Expression attributes
        int zpreq;                              // 1, optimize instr to zero-page form
        register char * p;              // (Temp) string usage
@@ -226,27 +258,29 @@ void m6502cg(int op)
        //
        zpreq = 0;
 
-       switch ((int)*tok)
+       switch (tok.u32[0])
        {
        case EOL:
                amode = A65_IMPL;
                break;
 
        case '#':
-               tok++;
+               tok.u32++;
 
-               if (*tok == '>')
+               if (*tok.u32 == '>')
                {
-                       tok++;
+                       tok.u32++;
+
                        if (expr(exprbuf, &eval, &eattr, NULL) < 0)
                                return;
 
                        amode = A65_IMMEDH;
                        break;
                }
-               else if (*tok == '<')
+               else if (*tok.u32 == '<')
                {
-                       tok++;
+                       tok.u32++;
+
                        if (expr(exprbuf, &eval, &eattr, NULL) < 0)
                                return;
 
@@ -261,41 +295,43 @@ void m6502cg(int op)
                break;
 
        case '(':
-               tok++;
+               tok.u32++;
 
                if (expr(exprbuf, &eval, &eattr, NULL) < 0)
                        return;
 
-               if (*tok == ')')
+               if (*tok.u32 == ')')
                {
                        // (foo) or (foo),y
-                       if (*++tok == ',')
+                       if (*++tok.u32 == ',')
                        {
                                // (foo),y
-                               tok++;
-                               p = string[tok[1]];
+                               tok.u32++;
+                               p = string[tok.u32[1]];
 
-                               if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') // Sleazo tolower()
+                               // Sleazo tolower() ---------------------vvvvvvvvvvv
+                               if (*tok.u32 != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y')
                                        goto badmode;
 
-                               tok += 2;
+                               tok.u32 += 2;
                                amode = A65_INDY;
                        }
                        else
                                amode = A65_IND;
                }
-               else if (*tok == ',')
+               else if (*tok.u32 == ',')
                {
                        // (foo,x)
-                       tok++;
-                       p = string[tok[1]];
+                       tok.u32++;
+                       p = string[tok.u32[1]];
 
-                       if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') // Sleazo tolower()
+                       // Sleazo tolower() ---------------------vvvvvvvvvvv
+                       if (*tok.u32 != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x')
                                goto badmode;
 
-                       tok += 2;
+                       tok.u32 += 2;
 
-                       if (*tok++ != ')')
+                       if (*tok.u32++ != ')')
                                goto badmode;
 
                        amode = A65_INDX;
@@ -306,17 +342,17 @@ void m6502cg(int op)
                break;
 
        case '@':
-               tok++;
+               tok.u32++;
 
                if (expr(exprbuf, &eval, &eattr, NULL) < 0)
                        return;
 
-               if (*tok == '(')
+               if (*tok.u32 == '(')
                {
-                       tok++;
-                       p = string[tok[1]];
+                       tok.u32++;
+                       p = string[tok.u32[1]];
 
-                       if (*tok != SYMBOL || p[1] != EOS || tok[2] != ')' || tok[3] != EOL)
+                       if (*tok.u32 != SYMBOL || p[1] != EOS || tok.u32[2] != ')' || tok.u32[3] != EOL)
                                goto badmode;
 
                        i = (*p | 0x20);        // Sleazo tolower()
@@ -328,10 +364,10 @@ void m6502cg(int op)
                        else
                                goto badmode;
 
-                       tok += 3;               // Past SYMBOL <string> ')' EOL
+                       tok.u32 += 3;   // Past SYMBOL <string> ')' EOL
                        zpreq = 1;              // Request zeropage optimization
                }
-               else if (*tok == EOL)
+               else if (*tok.u32 == EOL)
                        amode = A65_IND;
                else
                        goto badmode;
@@ -344,7 +380,7 @@ void m6502cg(int op)
                //   x,foo
                //   y,foo
                //
-               p = string[tok[1]];
+               p = string[tok.u32[1]];
                // ggn: the following code is effectively disabled as it would make
                //      single letter labels not work correctly (would not identify the
                //      label properly). And from what I understand it's something to
@@ -380,17 +416,17 @@ not_coinop:
 
                zpreq = 1;
 
-               if (*tok == EOL)
+               if (*tok.u32 == EOL)
                        amode = A65_ABS;
-               else if (*tok == ',')
+               else if (*tok.u32 == ',')
                {
-                       tok++;
-                       p = string[tok[1]];
+                       tok.u32++;
+                       p = string[tok.u32[1]];
 
-                       if (*tok != SYMBOL || p[1] != EOS)
+                       if (*tok.u32 != SYMBOL || p[1] != EOS)
                                goto badmode;
 
-                       tok += 2;
+                       tok.u32 += 2;
 
                        //
                        // Check for X or Y index register;
@@ -547,7 +583,7 @@ badmode:
        if (sloc > 0x10000L)
                fatal("6502 code pointer > 64K");
 
-       if (*tok != EOL)
+       if (*tok.u32 != EOL)
                error(extra_stuff);
 }
 
@@ -556,10 +592,6 @@ badmode:
 // Generate 6502 object output file.
 //
 // ggn: converted into a com/exe/xex output format
-//      Notes: 1. The $FFFF is only mandatory for the first segment, but let's
-//                dump it everywhere for now
-//             2. It's still dumping pages instead of more fine grained stuff.
-//                Should look into this - a8 people don't like waste so much ;)
 void m6502obj(int ofd)
 {
        uint16_t exeheader[3];