1 /*****************************************************************************/
5 /* 65XX effective address parsing for the ca65 macroassembler */
9 /* (C) 1998-2011, Ullrich von Bassewitz */
10 /* Roemerstrasse 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 /*****************************************************************************/
47 /*****************************************************************************/
49 /*****************************************************************************/
53 void GetEA (EffAddr* A)
54 /* Parse an effective address, return the result in A */
56 unsigned long Restrictions;
57 token_t IndirectEnter;
58 token_t IndirectLeave;
59 const char* IndirectExpect;
61 /* Choose syntax for indirection */
62 if (BracketAsIndirect) {
63 IndirectEnter = TOK_LBRACK;
64 IndirectLeave = TOK_RBRACK;
65 IndirectExpect = "']' expected";
67 IndirectEnter = TOK_LPAREN;
68 IndirectLeave = TOK_RPAREN;
69 IndirectExpect = "')' expected";
72 /* Clear the output struct */
76 /* Handle an addressing size override */
79 Restrictions = AM65_DIR | AM65_DIR_X | AM65_DIR_Y;
83 case TOK_OVERRIDE_ABS:
84 Restrictions = AM65_ABS | AM65_ABS_X | AM65_ABS_Y;
88 case TOK_OVERRIDE_FAR:
89 Restrictions = AM65_ABS_LONG | AM65_ABS_LONG_X;
94 Restrictions = ~0UL; /* None */
98 /* Parse the effective address */
99 if (TokIsSep (CurTok.Tok)) {
101 A->AddrModeSet = AM65_IMPLICIT;
103 } else if (CurTok.Tok == TOK_HASH) {
107 A->Expr = Expression ();
108 A->AddrModeSet = AM65_ALL_IMM;
110 } else if (CurTok.Tok == TOK_A) {
113 A->AddrModeSet = AM65_ACCU;
115 } else if (CurTok.Tok == IndirectEnter) {
117 /* One of the indirect modes */
119 A->Expr = Expression ();
121 if (CurTok.Tok == TOK_COMMA) {
123 /* (expr,X) or (rel,S),y */
125 if (CurTok.Tok == TOK_X) {
128 A->AddrModeSet = AM65_ABS_X_IND | AM65_DIR_X_IND;
129 Consume (IndirectLeave, IndirectExpect);
130 } else if (CurTok.Tok == TOK_S) {
133 A->AddrModeSet = AM65_STACK_REL_IND_Y;
134 Consume (IndirectLeave, IndirectExpect);
136 Consume (TOK_Y, "'Y' expected");
138 Error ("Syntax error");
143 /* (adr), (adr),y or (adr),z */
144 Consume (IndirectLeave, IndirectExpect);
145 if (CurTok.Tok == TOK_COMMA) {
148 switch (CurTok.Tok) {
150 /* only set by scanner.c if in 4510-mode */
152 A->AddrModeSet = AM65_DIR_IND;
155 Consume (TOK_Y, "'Y' expected");
156 A->AddrModeSet = AM65_DIR_IND_Y;
161 A->AddrModeSet = (CPU == CPU_4510) ? AM65_ABS_IND
162 : AM65_ABS_IND | AM65_ABS_IND_LONG | AM65_DIR_IND;
166 } else if (CurTok.Tok == TOK_LBRACK) {
168 /* Never executed if BracketAsIndirect feature is enabled. */
169 /* [dir] or [dir],y */
171 A->Expr = Expression ();
172 Consume (TOK_RBRACK, "']' expected");
173 if (CurTok.Tok == TOK_COMMA) {
176 Consume (TOK_Y, "'Y' expected");
177 A->AddrModeSet = AM65_DIR_IND_LONG_Y;
180 A->AddrModeSet = AM65_DIR_IND_LONG | AM65_ABS_IND_LONG;
192 A->Expr = Expression ();
194 if (CurTok.Tok == TOK_COMMA) {
197 switch (CurTok.Tok) {
200 A->AddrModeSet = AM65_ABS_LONG_X | AM65_ABS_X | AM65_DIR_X;
205 A->AddrModeSet = AM65_ABS_Y | AM65_DIR_Y;
210 A->AddrModeSet = AM65_STACK_REL;
215 Error ("Syntax error");
221 A->AddrModeSet = AM65_ABS_LONG | AM65_ABS | AM65_DIR;
226 /* Apply addressing mode overrides */
227 A->AddrModeSet &= Restrictions;