]> git.sur5r.net Git - cc65/blob - src/ca65/easw16.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / ca65 / easw16.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 easw16.c                                  */
4 /*                                                                           */
5 /*       SWEET16 effective address parsing for the ca65 macroassembler       */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2004-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
44
45
46 /*****************************************************************************/
47 /*                                   Code                                    */
48 /*****************************************************************************/
49
50
51
52 static long RegNum ()
53 /* Try to read a register number specified not as a register (Rx) but as a
54  * numeric value between 0 and 15. Return the register number or -1 on
55  * failure.
56  */
57 {
58     long Val;
59     ExprNode* Expr = Expression ();
60     if (!IsConstExpr (Expr, &Val) || Val < 0 || Val > 15) {
61         /* Invalid register */
62         Val = -1L;
63     }
64
65     /* Free the expression and return the register number */
66     FreeExpr (Expr);
67     return Val;
68 }
69
70
71
72 void GetSweet16EA (EffAddr* A)
73 /* Parse an effective address, return the result in A */
74 {
75     long Reg;
76
77     /* Clear the output struct */
78     A->AddrModeSet = 0;
79     A->Expr = 0;
80     A->Reg  = 0;
81
82     /* Parse the effective address */
83     if (TokIsSep (CurTok.Tok)) {
84
85         A->AddrModeSet = AMSW16_IMP;
86
87     } else if (CurTok.Tok == TOK_AT) {
88
89         /* @reg or @regnumber */
90         A->AddrModeSet = AMSW16_IND;
91         NextTok ();
92         if (CurTok.Tok == TOK_REG) {
93             A->Reg = (unsigned) CurTok.IVal;
94             NextTok ();
95         } else if ((Reg = RegNum ()) >= 0) {
96             /* Register number */
97             A->Reg = (unsigned) Reg;
98         } else {
99             ErrorSkip ("Register or register number expected");
100             A->Reg = 0;
101         }
102
103     } else if (CurTok.Tok == TOK_REG) {
104
105         A->Reg = (unsigned) CurTok.IVal;
106         NextTok ();
107
108         if (CurTok.Tok == TOK_COMMA) {
109
110             /* Rx, constant */
111             NextTok ();
112             A->Expr = Expression ();
113
114             A->AddrModeSet = AMSW16_IMM;
115
116         } else {
117
118             A->AddrModeSet = AMSW16_REG;
119
120         }
121
122     } else {
123
124         /* OPC ea  or: OPC regnum, constant */
125         A->Expr = Expression ();
126         A->AddrModeSet = AMSW16_BRA;
127
128         /* If the value is a constant between 0 and 15, it may also be a
129          * register number.
130          */
131         if (IsConstExpr (A->Expr, &Reg) && Reg >= 0 && Reg <= 15) {
132             FreeExpr (A->Expr);
133             A->Reg = (unsigned) Reg;
134
135             /* If a comma follows, it is: OPC Rx, constant */
136             if (CurTok.Tok == TOK_COMMA) {
137                 NextTok ();
138                 A->Expr = Expression ();
139                 A->AddrModeSet = AMSW16_IMM;
140             } else {
141                 A->Expr = 0;
142                 A->AddrModeSet |= AMSW16_REG;
143             }
144         }
145
146     }
147 }
148
149
150