* asranlib/asranlib.c, link/lkar.h, link/lkar.c:
[fw/sdcc] / as / hc08 / m08adr.c
1 /* m08adr.c
2
3    Copyright (C) 1989-1995 Alan R. Baldwin
4    721 Berkeley St., Kent, Ohio 44240
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10
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.
15
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/>. */
18
19 #include <stdio.h>
20 #include <setjmp.h>
21 #include "asm.h"
22 #include "m6808.h"
23
24 int
25 addr(esp)
26 register struct expr *esp;
27 {
28         register int c;
29         register struct area *espa;
30         register Addr_T espv;
31         const char *tcp;
32
33         if ((c = getnb()) == '#') {
34                 expr(esp, 0);
35                 esp->e_mode = S_IMMED;
36         } else if (c == ',') {
37                 switch(admode(axs)) {
38                 default:
39                         aerr();
40
41                 case S_X:
42                         c = S_IX;
43                         break;
44
45                 case S_S:
46                         c = S_IS;
47                         break;
48
49                 case S_XP:
50                         c = S_IXP;
51                         break;
52                 }
53                 esp->e_mode = c;
54         } else if (c == '*') {
55                 expr(esp, 0);
56                 esp->e_mode = S_DIR;
57                 if (esp->e_addr & ~0xFF)
58                         err('d');
59                 if (more()) {
60                         comma();
61                         tcp = ip;
62                         switch(admode(axs)) {
63                         case S_X:
64                                 esp->e_mode = S_IX1;
65                                 break;
66
67                         case S_S:
68                                 esp->e_mode = S_SP1;
69                                 break;
70
71                         case S_XP:
72                                 esp->e_mode = S_IX1P;
73                                 break;
74
75                         default:
76                                 ip = --tcp;
77                         }
78                 }
79         } else {
80                 unget(c);
81                 if ((esp->e_mode = admode(axs)) != 0) {
82                         ;
83                 } else {
84                         expr(esp, 0);
85                         espa = esp->e_base.e_ap;
86                         espv = esp->e_addr;
87                         if (more()) {
88                                 comma();
89                                 c = admode(axs);
90                                 if (esp->e_flag == 0 &&
91                                     espa == NULL &&
92                                     (espv & ~0xFF) == 0) {
93                                         switch(c) {
94                                         default:
95                                                 aerr();
96
97                                         case S_X:
98                                                 c = S_IX1;
99                                                 break;
100
101                                         case S_S:
102                                                 c = S_SP1;
103                                                 break;
104
105                                         case S_XP:
106                                                 c = S_IX1P;
107                                                 break;
108                                         }
109                                 } else {
110                                         switch(c) {
111                                         default:
112                                                 aerr();
113
114                                         case S_X:
115                                                 c = S_IX2;
116                                                 break;
117
118                                         case S_S:
119                                                 c = S_SP2;
120                                                 break;
121
122                                         case S_XP:
123                                                 c = S_IX2P;
124                                                 break;
125                                         }
126                                 }
127                                 esp->e_mode = c;
128                         } else {
129                                 esp->e_mode = S_EXT;
130                         }
131                 }
132         }
133         return (esp->e_mode);
134 }
135
136 /*
137  * Enter admode() to search a specific addressing mode table
138  * for a match. Return the addressing value on a match or
139  * zero for no match.
140  */
141 int
142 admode(sp)
143 register struct adsym *sp;
144 {
145         register char *ptr;
146         register int i;
147         register const char *ips;
148
149         ips = ip;
150         unget(getnb());
151
152         i = 0;
153         while ( *(ptr = &sp[i].a_str[0]) ) {
154                 if (srch(ptr)) {
155                         return(sp[i].a_val);
156                 }
157                 i++;
158         }
159         ip = ips;
160         return(0);
161 }
162
163 /*
164  *      srch --- does string match ?
165  */
166 int
167 srch(str)
168 register char *str;
169 {
170         register const char *ptr;
171         ptr = ip;
172
173         while (*ptr && *str) {
174                 if(ccase[*ptr & 0x007F] != ccase[*str & 0x007F])
175                         break;
176                 ptr++;
177                 str++;
178         }
179         if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) {
180                 ip = ptr;
181                 return(1);
182         }
183
184         if (!*str)
185                 if (any(*ptr," \t\n,];")) {
186                         ip = ptr;
187                         return(1);
188                 }
189         return(0);
190 }
191
192 /*
193  *      any --- does str contain c?
194  */
195 int
196 any(c,str)
197 int c;
198 char*str;
199 {
200         while (*str)
201                 if(*str++ == c)
202                         return(1);
203         return(0);
204 }
205
206 struct adsym    axs[] = {       /* a, x, or s registers */
207     {   "a",    S_A     },
208     {   "x",    S_X     },
209     {   "s",    S_S     },
210     {   "x+",   S_XP    },
211     {   "",     0x00    }
212 };