d47b8eba4c105f1b820d7e088c7a50753d85e5b9
[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 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 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     { "",       000 }
207 };
208
209 struct  adsym   R8X[] = {
210     { "i",      I|0400 },
211     { "r",      R|0400 },
212     { "",       000 }
213 };
214
215 struct  adsym   R16[] = {
216     { "bc",     BC|0400 },
217     { "de",     DE|0400 },
218     { "hl",     HL|0400 },
219     { "sp",     SP|0400 },
220 #ifndef GAMEBOY
221     { "ix",     IX|0400 },
222     { "iy",     IY|0400 },
223 #else /* GAMEBOY */
224     { "hl-",    HLD|0400 },
225     { "hl+",    HLI|0400 },
226     { "hld",    HLD|0400 },
227     { "hli",    HLI|0400 },
228 #endif /* GAMEBOY */
229     { "",       000 }
230 };
231
232 struct  adsym   R16X[] = {
233     { "af",     AF|0400 },
234 #ifndef GAMEBOY
235     { "af'",    AF|0400 },
236 #endif /* GAMEBOY */
237     { "",       000 }
238 };
239
240 /*
241  * Conditional definitions
242  */
243
244 struct  adsym   CND[] = {
245     { "NZ",     NZ|0400 },
246     { "Z",      Z |0400 },
247     { "NC",     NC|0400 },
248     { "C",      CS|0400 },
249 #ifndef GAMEBOY
250     { "PO",     PO|0400 },
251     { "PE",     PE|0400 },
252     { "P",      P |0400 },
253     { "M",      M |0400 },
254 #endif /* GAMEBOY */
255     { "",       000 }
256 };