]> git.sur5r.net Git - cc65/blob - src/ca65/ea65.c
Merge pull request #297 from groessler/something_to_pull
[cc65] / src / ca65 / ea65.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                  ea65.c                                   */
4 /*                                                                           */
5 /*        65XX effective address parsing for the ca65 macroassembler         */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2011, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 /* ca65 */
37 #include "ea.h"
38 #include "ea65.h"
39 #include "error.h"
40 #include "expr.h"
41 #include "instr.h"
42 #include "nexttok.h"
43 #include "global.h"
44
45
46
47 /*****************************************************************************/
48 /*                                   Code                                    */
49 /*****************************************************************************/
50
51
52
53 void GetEA (EffAddr* A)
54 /* Parse an effective address, return the result in A */
55 {
56     unsigned long Restrictions;
57     token_t IndirectEnter;
58     token_t IndirectLeave;
59     const char* IndirectExpect;
60
61     /* Choose syntax for indirection */
62     if (BracketAsIndirect) {
63         IndirectEnter = TOK_LBRACK;
64         IndirectLeave = TOK_RBRACK;
65         IndirectExpect = "']' expected";
66     } else {
67         IndirectEnter = TOK_LPAREN;
68         IndirectLeave = TOK_RPAREN;
69         IndirectExpect = "')' expected";
70     }
71
72     /* Clear the output struct */
73     A->AddrModeSet = 0;
74     A->Expr = 0;
75
76     /* Handle an addressing size override */
77     switch (CurTok.Tok) {
78         case TOK_OVERRIDE_ZP:
79             Restrictions = AM65_DIR | AM65_DIR_X | AM65_DIR_Y;
80             NextTok ();
81             break;
82
83         case TOK_OVERRIDE_ABS:
84             Restrictions = AM65_ABS | AM65_ABS_X | AM65_ABS_Y;
85             NextTok ();
86             break;
87
88         case TOK_OVERRIDE_FAR:
89             Restrictions = AM65_ABS_LONG | AM65_ABS_LONG_X;
90             NextTok ();
91             break;
92
93         default:
94             Restrictions = ~0UL;        /* None */
95             break;
96     }
97
98     /* Parse the effective address */
99     if (TokIsSep (CurTok.Tok)) {
100
101         A->AddrModeSet = AM65_IMPLICIT;
102
103     } else if (CurTok.Tok == TOK_HASH) {
104
105         /* #val */
106         NextTok ();
107         A->Expr  = Expression ();
108         A->AddrModeSet = AM65_ALL_IMM;
109
110     } else if (CurTok.Tok == TOK_A) {
111
112         NextTok ();
113         A->AddrModeSet = AM65_ACCU;
114
115     } else if (CurTok.Tok == IndirectEnter) {
116
117         /* One of the indirect modes */
118         NextTok ();
119         A->Expr = Expression ();
120
121         if (CurTok.Tok == TOK_COMMA) {
122
123             /* (expr,X) or (rel,S),y */
124             NextTok ();
125             if (CurTok.Tok == TOK_X) {
126                 /* (adr,x) */
127                 NextTok ();
128                 A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
129                 Consume (IndirectLeave, IndirectExpect);
130             } else if (CurTok.Tok == TOK_S) {
131                 /* (rel,s),y */
132                 NextTok ();
133                 A->AddrModeSet = AM65_STACK_REL_IND_Y;
134                 Consume (IndirectLeave, IndirectExpect);
135                 ConsumeComma ();
136                 Consume (TOK_Y, "`Y' expected");
137             } else {
138                 Error ("Syntax error");
139             }
140
141         } else {
142
143             /* (adr) or (adr),y */
144             Consume (IndirectLeave, IndirectExpect);
145             if (CurTok.Tok == TOK_COMMA) {
146                 /* (adr),y */
147                 NextTok ();
148                 Consume (TOK_Y, "`Y' expected");
149                 A->AddrModeSet = AM65_DIR_IND_Y;
150             } else {
151                 /* (adr) */
152                 A->AddrModeSet = AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND;
153             }
154         }
155
156     } else if (CurTok.Tok == TOK_LBRACK) {
157
158         /* Never executed if BracketAsIndirect feature is enabled. */
159         /* [dir] or [dir],y */
160         NextTok ();
161         A->Expr = Expression ();
162         Consume (TOK_RBRACK, "']' expected");
163         if (CurTok.Tok == TOK_COMMA) {
164             /* [dir],y */
165             NextTok ();
166             Consume (TOK_Y, "`Y' expected");
167             A->AddrModeSet = AM65_DIR_IND_LONG_Y;
168         } else {
169             /* [dir] */
170             A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG;
171         }
172
173     } else {
174
175         /* Remaining stuff:
176         **
177         ** adr
178         ** adr,x
179         ** adr,y
180         ** adr,s
181         */
182         A->Expr = Expression ();
183
184         if (CurTok.Tok == TOK_COMMA) {
185
186             NextTok ();
187             switch (CurTok.Tok) {
188
189                 case TOK_X:
190                     A->AddrModeSet = AM65_ABS_LONG_X | AM65_ABS_X | AM65_DIR_X;
191                     NextTok ();
192                     break;
193
194                 case TOK_Y:
195                     A->AddrModeSet = AM65_ABS_Y | AM65_DIR_Y;
196                     NextTok ();
197                     break;
198
199                 case TOK_S:
200                     A->AddrModeSet = AM65_STACK_REL;
201                     NextTok ();
202                     break;
203
204                 default:
205                     Error ("Syntax error");
206
207             }
208
209         } else {
210
211             A->AddrModeSet = AM65_ABS_LONG | AM65_ABS | AM65_DIR;
212
213         }
214     }
215
216     /* Apply addressing mode overrides */
217     A->AddrModeSet &= Restrictions;
218 }