]> git.sur5r.net Git - cc65/blob - src/ca65/ea.c
Set the address size once assembly is terminated
[cc65] / src / ca65 / ea.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                   ea.c                                    */
4 /*                                                                           */
5 /*           Effective address parsing for the ca65 macroassembler           */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
10 /*               Römerstraße 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 /* ld65 */
37 #include "error.h"
38 #include "expr.h"
39 #include "instr.h"
40 #include "nexttok.h"
41 #include "ea.h"
42
43
44
45 /*****************************************************************************/
46 /*                                   Code                                    */
47 /*****************************************************************************/
48
49
50
51 void GetEA (EffAddr* A)
52 /* Parse an effective address, return the result in A */
53 {
54     unsigned long Restrictions;
55
56     /* Clear the output struct */
57     A->AddrModeSet = 0;
58     A->Expr = 0;
59
60     /* Handle an addressing size override */
61     switch (Tok) {
62         case TOK_OVERRIDE_ZP:
63             Restrictions = AM_DIR | AM_DIR_X | AM_DIR_Y;
64             NextTok ();
65             break;
66
67         case TOK_OVERRIDE_ABS:
68             Restrictions = AM_ABS | AM_ABS_X | AM_ABS_Y;
69             NextTok ();
70             break;
71
72         case TOK_OVERRIDE_FAR:
73             Restrictions = AM_ABS_LONG | AM_ABS_LONG_X;
74             NextTok ();
75             break;
76
77         default:
78             Restrictions = ~0UL;        /* None */
79             break;
80     }
81
82     /* Parse the effective address */
83     if (TokIsSep (Tok)) {
84
85         A->AddrModeSet = AM_IMPLICIT;
86
87     } else if (Tok == TOK_HASH) {
88
89         /* #val */
90         NextTok ();
91         A->Expr  = Expression ();
92         A->AddrModeSet = AM_IMM;
93
94     } else if (Tok == TOK_A) {
95
96         NextTok ();
97         A->AddrModeSet = AM_ACCU;
98
99     } else if (Tok == TOK_LBRACK) {
100
101         /* [dir] or [dir],y */
102         NextTok ();
103         A->Expr = Expression ();
104         Consume (TOK_RBRACK, "']' expected");
105         if (Tok == TOK_COMMA) {
106             /* [dir],y */
107             NextTok ();
108             Consume (TOK_Y, "`Y' expected");
109             A->AddrModeSet = AM_DIR_IND_LONG_Y;
110         } else {
111             /* [dir] */
112             A->AddrModeSet = AM_DIR_IND_LONG;
113         }
114
115     } else if (Tok == TOK_LPAREN) {
116
117         /* One of the indirect modes */
118         NextTok ();
119         A->Expr = Expression ();
120
121         if (Tok == TOK_COMMA) {
122
123             /* (expr,X) or (rel,S),y */
124             NextTok ();
125             if (Tok == TOK_X) {
126                 /* (adr,x) */
127                 NextTok ();
128                 A->AddrModeSet = AM_ABS_X_IND | AM_DIR_X_IND;
129                 ConsumeRParen ();
130             } else if (Tok == TOK_S) {
131                 /* (rel,s),y */
132                 NextTok ();
133                 A->AddrModeSet = AM_STACK_REL_IND_Y;
134                 ConsumeRParen ();
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             ConsumeRParen ();
145             if (Tok == TOK_COMMA) {
146                 /* (adr),y */
147                 NextTok ();
148                 Consume (TOK_Y, "`Y' expected");
149                 A->AddrModeSet = AM_DIR_IND_Y;
150             } else {
151                 /* (adr) */
152                 A->AddrModeSet = AM_ABS_IND | AM_DIR_IND;
153             }
154         }
155
156     } else {
157
158         /* Remaining stuff:
159          *
160          * adr
161          * adr,x
162          * adr,y
163          * adr,s
164          */
165         A->Expr = Expression ();
166
167         if (Tok == TOK_COMMA) {
168
169             NextTok ();
170             switch (Tok) {
171
172                 case TOK_X:
173                     A->AddrModeSet = AM_ABS_LONG_X | AM_ABS_X | AM_DIR_X;
174                     NextTok ();
175                     break;
176
177                 case TOK_Y:
178                     A->AddrModeSet = AM_ABS_Y | AM_DIR_Y;
179                     NextTok ();
180                     break;
181
182                 case TOK_S:
183                     A->AddrModeSet = AM_STACK_REL;
184                     NextTok ();
185                     break;
186
187                 default:
188                     Error ("Syntax error");
189
190             }
191
192         } else {
193
194             A->AddrModeSet = AM_ABS_LONG | AM_ABS | AM_DIR;
195
196         }
197     }
198
199     /* Apply addressing mode overrides */
200     A->AddrModeSet &= Restrictions;
201 }
202
203
204