1 /*****************************************************************************/
5 /* Effective address parsing for the ca65 macroassembler */
9 /* (C) 1998-2003 Ullrich von Bassewitz */
10 /* Römerstrasse 52 */
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 */
61 /* Handle an addressing size override */
64 Restrictions = AM_DIR | AM_DIR_X | AM_DIR_Y;
68 case TOK_OVERRIDE_ABS:
69 Restrictions = AM_ABS | AM_ABS_X | AM_ABS_Y;
73 case TOK_OVERRIDE_FAR:
74 Restrictions = AM_ABS_LONG | AM_ABS_LONG_X;
79 Restrictions = ~0UL; /* None */
83 /* Parse the effective address */
86 A->AddrModeSet = AM_IMPLICIT;
88 } else if (Tok == TOK_HASH) {
92 A->Expr = Expression ();
93 A->AddrModeSet = AM_IMM;
95 } else if (Tok == TOK_A) {
98 A->AddrModeSet = AM_ACCU;
100 } else if (Tok == TOK_LBRACK) {
102 /* [dir] or [dir],y */
104 A->Expr = Expression ();
105 Consume (TOK_RBRACK, ERR_RBRACK_EXPECTED);
106 if (Tok == TOK_COMMA) {
109 Consume (TOK_Y, ERR_Y_EXPECTED);
110 A->AddrModeSet = AM_DIR_IND_LONG_Y;
113 A->AddrModeSet = AM_DIR_IND_LONG;
116 } else if (Tok == TOK_LPAREN) {
118 /* One of the indirect modes */
120 A->Expr = Expression ();
122 if (Tok == TOK_COMMA) {
124 /* (expr,X) or (rel,S),y */
129 A->AddrModeSet = AM_ABS_X_IND | AM_DIR_X_IND;
131 } else if (Tok == TOK_S) {
134 A->AddrModeSet = AM_STACK_REL_IND_Y;
137 Consume (TOK_Y, ERR_Y_EXPECTED);
144 /* (adr) or (adr),y */
146 if (Tok == TOK_COMMA) {
149 Consume (TOK_Y, ERR_Y_EXPECTED);
150 A->AddrModeSet = AM_DIR_IND_Y;
153 A->AddrModeSet = AM_ABS_IND | AM_DIR_IND;
168 A->Expr = Expression ();
170 if (Tok == TOK_DOT) {
172 /* Expr was a bank specification: bank.adr or bank.adr,x */
175 A->Expr = Expression ();
176 if (Tok == TOK_COMMA) {
179 Consume (TOK_X, ERR_X_EXPECTED);
180 A->AddrModeSet = AM_ABS_LONG_X;
183 A->AddrModeSet = AM_ABS_LONG;
188 if (Tok == TOK_COMMA) {
194 A->AddrModeSet = AM_ABS_LONG_X | AM_ABS_X | AM_DIR_X;
199 A->AddrModeSet = AM_ABS_Y | AM_DIR_Y;
204 A->AddrModeSet = AM_STACK_REL;
215 A->AddrModeSet = AM_ABS_LONG | AM_ABS | AM_DIR;
221 /* Apply addressing mode overrides */
222 A->AddrModeSet &= Restrictions;