* Changed limit on 256$ to > 256
[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 c, mode, 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[*ptr] != ccase[*str])
163                         break;
164                 ptr++;
165                 str++;
166         }
167         if (ccase[*ptr] == ccase[*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         "",     0000
207 };
208
209 struct  adsym   R8X[] = {
210         "i",    I|0400,
211         "r",    R|0400,
212         "",     0000
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         "",     0000
230 };
231
232 struct  adsym   R16X[] = {
233         "af",   AF|0400,
234 #ifndef GAMEBOY
235         "af'",  AF|0400,
236 #endif /* GAMEBOY */
237         "",     0000
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         "",     0000
256 };