struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / as8xcxxx / ds8adr.c
blob5f9884320ec3b1a854b93074ef80be80c0dbc852
1 /* ds8adr.c */
3 /*
4 * Copyright (C) 1998-2009 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
24 * This Assember Ported by
25 * jhartman at compuserve dot com
26 * noice at noicedebugger dot com
28 * Modified from i51pst.c
29 * Bill McKinnon
30 * w_mckinnon at conknet dot com
34 #include "asxxxx.h"
35 #include "ds8.h"
38 struct adsym reg51[] = { /* R0 thru R7 registers */
39 { "R0", R0 },
40 { "R1", R1 },
41 { "R2", R2 },
42 { "R3", R3 },
43 { "R4", R4 },
44 { "R5", R5 },
45 { "R6", R6 },
46 { "R7", R7 },
47 { "A", A },
48 { "DPTR", DPTR },
49 { "PC", PC },
50 { "C", C },
51 { "AB", AB },
52 { "", 0x00 }
55 /* Classify argument as to address mode */
56 int
57 addr(struct expr *esp)
59 int c;
60 unsigned int rd;
62 if ((c = getnb()) == '#') {
63 /* Immediate mode */
64 expr(esp, 0);
65 esp->e_mode = S_IMMED;
67 else if (c == '@') {
68 /* choices are @R0, @R1, @DPTR, @A+PC, @A+DPTR */
69 switch (reg()) {
70 case R0:
71 esp->e_mode = S_AT_R;
72 esp->e_addr = R0;
73 break;
74 case R1:
75 esp->e_mode = S_AT_R;
76 esp->e_addr = R1;
77 break;
78 case DPTR:
79 esp->e_mode = S_AT_DP;
80 esp->e_addr = DPTR;
81 break;
82 case A:
83 if (getnb() == '+') {
84 rd = reg();
85 if (rd == PC) {
86 esp->e_mode = S_AT_APC;
87 esp->e_addr = 0;
88 } else if (rd == DPTR) {
89 esp->e_mode = S_AT_ADP;
90 esp->e_addr = 0;
91 } else {
92 xerr('a', "@A+DPTR and A,@A+PC are the allowed modes.");
94 } else
95 xerr('a', "Invalid Addressing Mode.");
96 break;
99 esp->e_flag = 0;
100 esp->e_base.e_ap = NULL;
102 else if (c == '*') {
103 if ((c = getnb()) == '/') {
104 /* Force inverted bit */
105 expr(esp, 0);
106 esp->e_mode = S_NOT_BIT;
107 } else {
108 unget(c);
109 /* Force direct page */
110 expr(esp, 0);
111 esp->e_mode = S_DIR;
113 if (esp->e_addr & ~0xFF)
114 xerr('d', "A Direct Page addressing error.");
116 else if (c == '/') {
117 /* Force inverted bit */
118 expr(esp, 0);
119 esp->e_mode = S_NOT_BIT;
121 else {
122 unget(c);
124 /* try for register: A, AB, R0-R7, DPTR, PC, Cy */
125 if ((esp->e_addr = admode(reg51)) != -1) {
126 switch (esp->e_addr) {
127 case A:
128 esp->e_mode = S_A;
129 break;
130 case AB:
131 esp->e_mode = S_RAB;
132 break;
133 case DPTR:
134 esp->e_mode = S_DPTR;
135 break;
136 case PC:
137 esp->e_mode = S_PC;
138 break;
139 case C:
140 esp->e_mode = S_C;
141 break;
142 default:
143 /* R0-R7 */
144 esp->e_mode = S_REG;
146 } else {
147 /* Must be an expression */
148 esp->e_addr = 0; /* Vasiliy Petrov */
149 expr(esp, 0);
150 if ((!esp->e_flag)
151 && (esp->e_base.e_ap==NULL)
152 && !(esp->e_addr & ~0xFF)) {
153 esp->e_mode = S_DIR;
154 } else {
155 esp->e_mode = S_EXT;
159 return (esp->e_mode);
163 * Enter admode() to search a specific addressing mode table
164 * for a match. Return the addressing value on a match or
165 * -1 for no match.
168 admode(struct adsym *sp)
170 char *ptr;
171 int i;
173 unget(getnb());
174 i = 0;
175 while ( *(ptr = &sp[i].a_str[0]) ) {
176 if (srch(ptr)) {
177 return(sp[i].a_val);
179 i++;
181 return(-1);
185 * srch --- does string match ?
188 srch(char *str)
190 char *ptr;
191 ptr = ip;
193 while (*ptr && *str) {
194 if(ccase[*ptr & 0x007F] != ccase[*str & 0x007F])
195 break;
196 ptr++;
197 str++;
199 if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) {
200 ip = ptr;
201 return(1);
204 if (!*str)
205 if (any(*ptr," \t\n,];")) {
206 ip = ptr;
207 return(1);
209 return(0);
213 * any --- does str contain c?
216 any(int c, char *str)
218 while (*str)
219 if(*str++ == c)
220 return(1);
221 return(0);
225 * Read a register name. Return register value, -1 if no register found
228 reg(void)
230 struct mne *mp;
231 char id[NCPS];
233 getid(id, -1);
234 if ((mp = mlookup(id))==NULL) {
235 aerr();
236 return (-1);
238 switch (mp->m_type) {
239 case S_A:
240 case S_AB:
241 case S_DPTR:
242 case S_PC:
243 case S_REG:
244 return ((int) mp->m_valu);
246 default:
247 return (-1);