Various cleanups to fix compiler warnings.
[rmac] / amode.c
1 //
2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // AMODE.C - Addressing Modes
4 // Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source Utilised with the Kind Permission of Landon Dyer
7 //
8
9 #include "amode.h"
10 #include "error.h"
11 #include "token.h"
12 #include "expr.h"
13 #include "rmac.h"
14
15 #define DEF_KW
16 #include "kwtab.h"
17 #define DEF_MN
18 #include "mntab.h"
19
20 // Address-mode information
21 int nmodes;                                                 // Number of addr'ing modes found
22 int am0;                                                    // Addressing mode
23 int a0reg;                                                  // Register
24 TOKEN a0expr[EXPRSIZE];                                     // Expression
25 VALUE a0exval;                                              // Expression's value
26 WORD a0exattr;                                              // Expression's attribute
27 int a0ixreg;                                                // Index register
28 int a0ixsiz;                                                // Index register size (and scale)
29 TOKEN a0oexpr[EXPRSIZE];                                    // Outer displacement expression
30 VALUE a0oexval;                                             // Outer displacement value
31 WORD a0oexattr;                                             // Outer displacement attribute
32 SYM *a0esym;                                                // External symbol involved in expr
33
34 int am1;                                                    // Addressing mode
35 int a1reg;                                                  // Register
36 TOKEN a1expr[EXPRSIZE];                                     // Expression
37 VALUE a1exval;                                              // Expression's value
38 WORD a1exattr;                                              // Expression's attribute
39 int a1ixreg;                                                // Index register
40 int a1ixsiz;                                                // Index register size (and scale)
41 TOKEN a1oexpr[EXPRSIZE];                                    // Outer displacement expression
42 VALUE a1oexval;                                             // Outer displacement value
43 WORD a1oexattr;                                             // Outer displacement attribute
44 SYM *a1esym;                                                // External symbol involved in expr
45
46 //
47 // --- Parse Addressing Mode -----------------------------------------------------------------------
48 //
49
50 int amode(int acount) {
51    // Initialize global return values
52         nmodes = a0reg = a1reg = 0;
53         am0 = am1 = AM_NONE;
54         a0expr[0] = a0oexpr[0] = a1expr[0] = a1oexpr[0] = ENDEXPR;
55         a0exattr = a0oexattr = a1exattr = a1oexattr = 0;
56         a0esym = a1esym = (SYM *)NULL;
57
58    // If at EOL, then no addr modes at all
59    if(*tok == EOL)
60       return(0);
61
62    // Parse first addressing mode
63    #define AnOK      a0ok
64    #define AMn       am0
65    #define AnREG     a0reg
66    #define AnIXREG   a0ixreg
67    #define AnIXSIZ   a0ixsiz
68    #define AnEXPR    a0expr
69    #define AnEXVAL   a0exval
70    #define AnEXATTR  a0exattr
71    #define AnOEXPR   a0oexpr
72    #define AnOEXVAL  a0oexval
73    #define AnOEXATTR a0oexattr
74    #define AnESYM    a0esym
75    #define AMn_IX0   am0_ix0
76    #define AMn_IXN   am0_ixn
77    #include "parmode.h"
78
79    // If caller wants only one mode, return just one (ignore comma); 
80    // If there is no second addressing mode (no comma), then return just one anyway.
81    nmodes = 1;
82    if(acount == 0 || *tok != ',')
83       return(1);
84    ++tok;                                                   // Eat comma
85
86    // Parse second addressing mode
87    #define AnOK      a1ok
88    #define AMn       am1
89    #define AnREG     a1reg
90    #define AnIXREG   a1ixreg
91    #define AnIXSIZ   a1ixsiz
92    #define AnEXPR    a1expr
93    #define AnEXVAL   a1exval
94    #define AnEXATTR  a1exattr
95    #define AnOEXPR   a1oexpr
96    #define AnOEXVAL  a1oexval
97    #define AnOEXATTR a1oexattr
98    #define AnESYM    a1esym
99    #define AMn_IX0   am1_ix0
100    #define AMn_IXN   am1_ixn
101    #include "parmode.h"
102
103    nmodes = 2;
104    return(2);
105
106    // Error messages:
107    badmode:
108
109    return(error("addressing mode syntax"));
110
111    unmode:
112
113    return(error("unimplemented addressing mode"));
114 }
115
116 //
117 // --- Parse Register List -------------------------------------------------------------------------
118 //
119
120 int reglist(WORD *a_rmask) {
121    static WORD msktab[] = {
122       0x0001, 0x0002, 0x0004, 0x0008,
123       0x0010, 0x0020, 0x0040, 0x0080,
124       0x0100, 0x0200, 0x0400, 0x0800,
125       0x1000, 0x2000, 0x4000, 0x8000
126    };
127    WORD rmask;
128    int r, cnt;
129
130    rmask = 0;
131    for(;;) {
132       if(*tok >= KW_D0 && *tok <= KW_A7)
133          r = *tok++ & 15;
134       else break;
135
136       if(*tok == '-') {
137          ++tok;
138          if(*tok >= KW_D0 && *tok <= KW_A7)
139             cnt = *tok++ & 15;
140          else 
141             return(error("register list syntax"));
142
143          if(cnt < r)
144             return(error("register list order"));
145          cnt -= r;
146       } else 
147          cnt = 0;
148
149       while(cnt-- >= 0)
150          rmask |= msktab[r++];
151       if(*tok != '/')
152          break;
153       ++tok;
154    }
155
156    *a_rmask = rmask;
157
158    return(OK);
159 }
160
161