1 /*****************************************************************************/
5 /* Effective address parsing for the ca65 macroassembler */
9 /* (C) 1998-2003 Ullrich von Bassewitz */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
45 /*****************************************************************************/
47 /*****************************************************************************/
51 void GetEA (EffAddr* A)
52 /* Parse an effective address, return the result in A */
54 unsigned long Restrictions;
56 /* Clear the output struct */
60 /* Handle an addressing size override */
63 Restrictions = AM_DIR | AM_DIR_X | AM_DIR_Y;
67 case TOK_OVERRIDE_ABS:
68 Restrictions = AM_ABS | AM_ABS_X | AM_ABS_Y;
72 case TOK_OVERRIDE_FAR:
73 Restrictions = AM_ABS_LONG | AM_ABS_LONG_X;
78 Restrictions = ~0UL; /* None */
82 /* Parse the effective address */
85 A->AddrModeSet = AM_IMPLICIT;
87 } else if (Tok == TOK_HASH) {
91 A->Expr = Expression ();
92 A->AddrModeSet = AM_IMM;
94 } else if (Tok == TOK_A) {
97 A->AddrModeSet = AM_ACCU;
99 } else if (Tok == TOK_LBRACK) {
101 /* [dir] or [dir],y */
103 A->Expr = Expression ();
104 Consume (TOK_RBRACK, "']' expected");
105 if (Tok == TOK_COMMA) {
108 Consume (TOK_Y, "`Y' expected");
109 A->AddrModeSet = AM_DIR_IND_LONG_Y;
112 A->AddrModeSet = AM_DIR_IND_LONG;
115 } else if (Tok == TOK_LPAREN) {
117 /* One of the indirect modes */
119 A->Expr = Expression ();
121 if (Tok == TOK_COMMA) {
123 /* (expr,X) or (rel,S),y */
128 A->AddrModeSet = AM_ABS_X_IND | AM_DIR_X_IND;
130 } else if (Tok == TOK_S) {
133 A->AddrModeSet = AM_STACK_REL_IND_Y;
136 Consume (TOK_Y, "`Y' expected");
138 Error ("Syntax error");
143 /* (adr) or (adr),y */
145 if (Tok == TOK_COMMA) {
148 Consume (TOK_Y, "`Y' expected");
149 A->AddrModeSet = AM_DIR_IND_Y;
152 A->AddrModeSet = AM_ABS_IND | AM_DIR_IND;
165 A->Expr = Expression ();
167 if (Tok == TOK_COMMA) {
173 A->AddrModeSet = AM_ABS_LONG_X | AM_ABS_X | AM_DIR_X;
178 A->AddrModeSet = AM_ABS_Y | AM_DIR_Y;
183 A->AddrModeSet = AM_STACK_REL;
188 Error ("Syntax error");
194 A->AddrModeSet = AM_ABS_LONG | AM_ABS | AM_DIR;
199 /* Apply addressing mode overrides */
200 A->AddrModeSet &= Restrictions;