f4b12afc53aebefc3e52192f119a73f070e2e572
[fw/sdcc] / as / z80 / z80adr.c
1 /* z80adr.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  */
11
12 /*
13  * Extensions: P. Felber
14  */
15
16 #include <stdio.h>
17 #include <setjmp.h>
18 #include "asm.h"
19 #include "z80.h"
20
21 /*
22  * Read an address specifier. Pack the
23  * address information into the supplied
24  * `expr' structure. Return the mode of
25  * the address.
26  *
27  * This addr(esp) routine performs the following addressing decoding:
28  *
29  *      address         mode            flag            addr            base
30  *      #n              S_IMMED         0               n               NULL
31  *      label           s_type          ----            s_addr          s_area
32  *      [REG]           S_IND+icode     0               0               NULL
33  *      [label]         S_INDM          ----            s_addr          s_area
34  *      offset[REG]     S_IND+icode     ----            offset          ----
35  */
36 int
37 addr(esp)
38 register struct expr *esp;
39 {
40         register int c, mode = 0, indx;
41
42         if ((c = getnb()) == '#') {
43                 expr(esp, 0);
44                 esp->e_mode = S_IMMED;
45         } else
46         if (c == LFIND) {
47                 if ((indx = admode(R8)) != 0) {
48                         mode = S_INDB;
49                 } else
50                 if ((indx = admode(R16)) != 0) {
51                         mode = S_INDR;
52                 } else
53                 if ((indx = admode(R8X)) != 0) {
54                         mode = S_R8X;
55                         aerr();
56                 } else
57                 if ((indx = admode(R16X)) != 0) {
58                         mode = S_R16X;
59                         aerr();
60                 } else {
61                         expr(esp, 0);
62                         esp->e_mode = S_INDM;
63                 }
64                 if (indx) {
65                         esp->e_mode = (mode + indx)&0xFF;
66                         esp->e_base.e_ap = NULL;
67                 }
68                 if ((c = getnb()) != RTIND)
69                         qerr();
70         } else {
71                 unget(c);
72                 if ((indx = admode(R8)) != 0) {
73                         mode = S_R8;
74                 } else
75                 if ((indx = admode(R16)) != 0) {
76                         mode = S_R16;
77                 } else
78                 if ((indx = admode(R8X)) != 0) {
79                         mode = S_R8X;
80                 } else
81                 if ((indx = admode(R16X)) != 0) {
82                         mode = S_R16X;
83                 } else {
84                         expr(esp, 0);
85                         esp->e_mode = S_USER;
86                 }
87                 if (indx) {
88                         esp->e_addr = indx&0xFF;
89                         esp->e_mode = mode;
90                         esp->e_base.e_ap = NULL;
91                 }
92                 if ((c = getnb()) == LFIND) {
93 #ifndef GAMEBOY
94                         if ((indx=admode(R16))!=0
95                                 && ((indx&0xFF)==IX || (indx&0xFF)==IY)) {
96 #else /* GAMEBOY */
97                         if ((indx=admode(R16))!=0) {
98 #endif /* GAMEBOY */
99                                 esp->e_mode = S_INDR + (indx&0xFF);
100                         } else {
101                                 aerr();
102                         }
103                         if ((c = getnb()) != RTIND)
104                                 qerr();
105                 } else {
106                         unget(c);
107                 }
108         }
109         return (esp->e_mode);
110 }
111
112 /*
113  * Enter admode() to search a specific addressing mode table
114  * for a match. Return the addressing value on a match or
115  * zero for no match.
116  */
117 int
118 admode(sp)
119 register struct adsym *sp;
120 {
121         register char *ptr;
122         register int i;
123         register const char *ips;
124
125         ips = ip;
126         unget(getnb());
127
128         i = 0;
129         while ( *(ptr = (char *) &sp[i]) ) {
130                 if (srch(ptr)) {
131                         return(sp[i].a_val);
132                 }
133                 i++;
134         }
135         ip = ips;
136         return(0);
137 }
138
139 /*
140  *      srch --- does string match ?
141  */
142 int
143 srch(str)
144 register char *str;
145 {
146         register const char *ptr;
147         ptr = ip;
148
149 #if     CASE_SENSITIVE
150         while (*ptr && *str) {
151                 if (*ptr != *str)
152                         break;
153                 ptr++;
154                 str++;
155         }
156         if (*ptr == *str) {
157                 ip = ptr;
158                 return(1);
159         }
160 #else
161         while (*ptr && *str) {
162                 if (ccase[(unsigned char)(*ptr)] != ccase[(unsigned char)(*str)])
163                         break;
164                 ptr++;
165                 str++;
166         }
167         if (ccase[(unsigned char)(*ptr)] == ccase[(unsigned char)(*str)]) {
168                 ip = ptr;
169                 return(1);
170         }
171 #endif
172
173         if (!*str)
174                 if (any(*ptr," \t\n,);")) {
175                         ip = ptr;
176                         return(1);
177                 }
178         return(0);
179 }
180
181 /*
182  *      any --- does str contain c?
183  */
184 int
185 any(c,str)
186 char    c, *str;
187 {
188         while (*str)
189                 if(*str++ == c)
190                         return(1);
191         return(0);
192 }
193
194 /*
195  * Registers
196  */
197
198 struct  adsym   R8[] = {
199     { "b",      B|0400 },
200     { "c",      C|0400 },
201     { "d",      D|0400 },
202     { "e",      E|0400 },
203     { "h",      H|0400 },
204     { "l",      L|0400 },
205     { "a",      A|0400 },
206     { "B",      B|0400 },
207     { "C",      C|0400 },
208     { "D",      D|0400 },
209     { "E",      E|0400 },
210     { "H",      H|0400 },
211     { "L",      L|0400 },
212     { "A",      A|0400 },
213     { "",       000 }
214 };
215
216 struct  adsym   R8X[] = {
217     { "i",      I|0400 },
218     { "r",      R|0400 },
219     { "I",      I|0400 },
220     { "R",      R|0400 },
221     { "",       000 }
222 };
223
224 struct  adsym   R16[] = {
225     { "bc",     BC|0400 },
226     { "de",     DE|0400 },
227     { "hl",     HL|0400 },
228     { "sp",     SP|0400 },
229     { "BC",     BC|0400 },
230     { "DE",     DE|0400 },
231     { "HL",     HL|0400 },
232     { "SP",     SP|0400 },
233 #ifndef GAMEBOY
234     { "ix",     IX|0400 },
235     { "iy",     IY|0400 },
236     { "IX",     IX|0400 },
237     { "IY",     IY|0400 },
238 #else /* GAMEBOY */
239     { "hl-",    HLD|0400 },
240     { "hl+",    HLI|0400 },
241     { "hld",    HLD|0400 },
242     { "hli",    HLI|0400 },
243     { "HL-",    HLD|0400 },
244     { "HL+",    HLI|0400 },
245     { "HLD",    HLD|0400 },
246     { "HLI",    HLI|0400 },
247 #endif /* GAMEBOY */
248     { "",       000 }
249 };
250
251 struct  adsym   R16X[] = {
252     { "af",     AF|0400 },
253     { "AF",     AF|0400 },
254 #ifndef GAMEBOY
255     { "af'",    AF|0400 },
256     { "AF'",    AF|0400 },
257 #endif /* GAMEBOY */
258     { "",       000 }
259 };
260
261 /*
262  * Conditional definitions
263  */
264
265 struct  adsym   CND[] = {
266     { "NZ",     NZ|0400 },
267     { "Z",      Z |0400 },
268     { "NC",     NC|0400 },
269     { "C",      CS|0400 },
270     { "nz",     NZ|0400 },
271     { "z",      Z |0400 },
272     { "nc",     NC|0400 },
273     { "c",      CS|0400 },
274 #ifndef GAMEBOY
275     { "PO",     PO|0400 },
276     { "PE",     PE|0400 },
277     { "P",      P |0400 },
278     { "M",      M |0400 },
279     { "po",     PO|0400 },
280     { "pe",     PE|0400 },
281     { "p",      P |0400 },
282     { "m",      M |0400 },
283 #endif /* GAMEBOY */
284     { "",       000 }
285 };