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