Fixed word reversed fixup problem.
[rmac] / parmode.h
1 //
2 // RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System
3 // PARMODE.C - Addressing Modes Parser Include
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 // This file is included (twice) to parse two addressing modes, into slightly
10 // different var names
11 {
12         // Dn
13         // An
14         // # expression
15         if ((*tok >= KW_D0) && (*tok <= KW_D7))
16         {
17                 AMn = DREG;
18                 AnREG = *tok++ & 7;
19         }
20         else if ((*tok >= KW_A0) && (*tok <= KW_A7))
21         {
22                 AMn = AREG;
23                 AnREG = *tok++ & 7;
24         }
25         else if (*tok == '#')
26         {
27                 tok++;
28
29                 if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
30                         return ERROR;
31
32                 AMn = IMMED;
33         }
34         // (An)
35         // (An)+
36         // (An,Xn[.siz][*scale])
37         // (PC,Xn[.siz][*scale])
38         // (d16,An)
39         // (d8,An,Xn[.siz][*scale])
40         // (d16,PC)
41         // (d8,PC,Xn[.siz][*scale])
42         // ([bd,An],Xn,od)
43         // ([bd,An,Xn],od)
44         // ([bd,PC],Xn,od)
45         // ([bd,PC,Xn],od)
46         else if (*tok == '(')
47         {
48                 tok++;
49
50                 if ((*tok >= KW_A0) && (*tok <= KW_A7))
51                 {
52                         AnREG = *tok++ & 7;
53
54                         if (*tok == ')')
55                         {
56                                 tok++;
57
58                                 if (*tok == '+')
59                                 {
60                                         tok++;
61                                         AMn = APOSTINC;
62                                 }
63                                 else
64                                         AMn = AIND;
65
66                                 goto AnOK;
67                         }
68
69                         AMn = AINDEXED;
70                         goto AMn_IX0;                                      // Handle ",Xn[.siz][*scale])"
71                 }
72                 else if (*tok == KW_PC)
73                 {                            // (PC,Xn[.siz][*scale]) 
74                         tok++;
75                         AMn = PCINDEXED;
76
77                         // Common index handler; enter here with `tok' pointing at the comma.
78
79                         AMn_IX0:                                           // Handle indexed with missing expr
80
81                         AnEXVAL = 0;
82                         AnEXATTR = ABS | DEFINED;
83
84                         AMn_IXN:                                           // Handle any indexed (tok -> a comma)
85
86                         if (*tok++ != ',')
87                                 goto badmode;
88
89                         if (*tok < KW_D0 || *tok > KW_A7)
90                                 goto badmode;
91
92                         AnIXREG = *tok++ & 15;
93
94                         switch ((int)*tok)
95                         {                                // Index reg size: <empty> | .W | .L 
96                         case DOTW:
97                                 tok++;
98                         default:
99                                 AnIXSIZ = 0;
100                                 break;
101                         case DOTL:
102                                 AnIXSIZ = 0x0800;
103                                 tok++;
104                                 break;
105                         case DOTB:                                      // .B not allowed here...
106                                 goto badmode;
107                         }
108
109                         if (*tok == '*')
110                         {                                  // scale: *1, *2, *4, *8 
111                                 tok++;
112
113                                 if (*tok++ != CONST || *tok > 8)
114                                         goto badmode;
115
116                                 switch ((int)*tok++)
117                                 {
118                                 case 1:
119                                         break;
120                                 case 2:
121                                         AnIXSIZ |= TIMES2;
122                                         break;
123                                 case 4:
124                                         AnIXSIZ |= TIMES4;
125                                         break;
126                                 case 8:
127                                         AnIXSIZ |= TIMES8;
128                                         break;
129                                 default:
130                                         goto badmode;
131                                 }
132                         }
133
134                         if (*tok++ != ')')                                  // final ")" 
135                                 goto badmode;
136
137                         goto AnOK;
138                 }
139                 else if (*tok == '[')
140                 {                              // ([... 
141                         goto unmode;
142                 }
143                 else
144                 {                                              // (expr... 
145                         if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
146                                 return ERROR;
147
148                         if (*tok++ != ',')
149                                 goto badmode;
150
151                         if ((*tok >= KW_A0) && (*tok <= KW_A7))
152                         {
153                                 AnREG = *tok & 7;
154                                 tok++;
155
156                                 if (*tok == ',')
157                                 {
158                                         AMn = AINDEXED;
159                                         goto AMn_IXN;
160                                 }
161                                 else if (*tok == ')')
162                                 {
163                                         AMn = ADISP;
164                                         tok++;
165                                         goto AnOK;
166                                 }
167                                 else
168                                         goto badmode;
169                         }
170                         else if (*tok == KW_PC)
171                         {
172                                 if (*++tok == ',')
173                                 {                             // expr(PC,Xn...)
174                                         AMn = PCINDEXED;
175                                         goto AMn_IXN;
176                                 }
177                                 else if (*tok == ')')
178                                 {
179                                         AMn = PCDISP;                                // expr(PC) 
180                                         tok++;
181                                         goto AnOK;
182                                 }
183                                 else
184                                         goto badmode;
185                         }
186                         else
187                                 goto badmode;
188                 }
189         }
190         else if (*tok=='-' && tok[1]=='(' && ((tok[2]>=KW_A0) && (tok[2]<=KW_A7)) && tok[3]==')')
191         {
192                 AMn = APREDEC;
193                 AnREG = tok[2] & 7;
194                 tok += 4;
195         }
196         else if (*tok == KW_CCR)
197         {
198                 AMn = AM_CCR;
199                 tok++;
200                 goto AnOK;
201         }
202         else if (*tok == KW_SR)
203         {
204                 AMn = AM_SR;
205                 tok++;
206                 goto AnOK;
207         }
208         else if (*tok == KW_USP)
209         {
210                 AMn = AM_USP;
211                 tok++;
212                 goto AnOK;
213         }
214         // expr
215         // expr.w
216         // expr.l
217         // d16(An)
218         // d8(An,Xn[.siz])
219         // d16(PC)
220         // d8(PC,Xn[.siz])
221         else
222         {
223                 if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
224                         return ERROR;
225
226                 if (*tok == DOTW)
227                 {
228                         // expr.W 
229                         tok++;
230                         AMn = ABSW;
231                         goto AnOK;
232                 }
233                 else if (*tok != '(')
234                 {
235                         // expr[.L]
236                         AMn = ABSL;
237
238                         // Defined, absolute values from $FFFF8000..$00007FFF get optimized
239                         // to absolute short
240                         if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
241                                 AMn = ABSW;
242
243                         // Is .L forced here?
244                         if (*tok == DOTL)
245                         {
246                                 tok++;
247                                 AMn = ABSL;
248                         }
249
250                         goto AnOK;
251                 }
252
253                 tok++;
254
255                 if ((*tok >= KW_A0) && (*tok <= KW_A7))
256                 {
257                         AnREG = *tok++ & 7;
258
259                         if (*tok == ')')
260                         {
261                                 AMn = ADISP;
262                                 tok++;
263                                 goto AnOK;
264                         }
265
266                         AMn = AINDEXED;
267                         goto AMn_IXN;
268                 }
269                 else if (*tok == KW_PC)
270                 {
271                         if (*++tok == ')')
272                         {
273                                 AMn = PCDISP;
274                                 tok++;
275                                 goto AnOK;
276                         }
277
278                         AMn = PCINDEXED;
279                         goto AMn_IXN;
280                 }
281                 goto badmode;
282         }
283
284         // Addressing mode OK
285
286         AnOK:
287         ;
288 }
289
290 // Cleanup dirty little macros
291 #undef AnOK
292 #undef AMn
293 #undef AnREG
294 #undef AnIXREG
295 #undef AnIXSIZ
296 #undef AnEXPR
297 #undef AnEXVAL
298 #undef AnEXATTR
299 #undef AnOEXPR
300 #undef AnOEXVAL
301 #undef AnOEXATTR
302 #undef AnESYM
303 #undef AMn_IX0
304 #undef AMn_IXN