1 /* xa65 - 65xx/65816 cross-assembler and utility suite
2 *
3 * Copyright (C) 1989-1997 Andr� Fachat (a.fachat@physik.tu-chemnitz.de)
4 *
5 * Label management module (also see xau.c)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26
27 /* structs and defs */
28
29 #include "xad.h"
30 #include "xah.h"
31 #include "xar.h"
32 #include "xah2.h"
33 #include "xap.h"
34 #include "xa.h"
35
36 /* externals */
37
38 #include "xam.h"
39 #include "xal.h"
40
41 /* exported globals */
42
43 char *lz;
44
45 /* local prototypes */
46
47 static int b_fget(int*,int);
48 static int b_ltest(int,int);
49 static int b_get(int*);
50 static int b_test(int);
51 static int ll_def(char *s, int *n, int b);
52
53 /* local variables */
54
55 /*
56 static int hashindex[256];
57 static Labtab *lt = NULL;
58 static int lti = 0;
59 static int ltm = 0;
60 */
61
62 /*
63 static char *ln;
64 static unsigned long lni;
65 static long sl;
66 */
67
68 static Labtab *ltp;
69
l_init(void)70 int l_init(void)
71 {
72 return 0;
73 #if 0
74 int er;
75
76 for(er=0;er<256;er++)
77 hashindex[er]=0;
78
79 /*sl=(long)sizeof(Labtab);*/
80
81 /* if(!(er=m_alloc((long)(sizeof(Labtab)*ANZLAB),(char**)<)))
82 er=m_alloc((long)LABMEM,&ln);*/
83
84 er=m_alloc((long)(sizeof(Labtab)*ANZLAB),(char**)<);
85
86 lti=0;
87 /* lni=0L;*/
88
89 return(er);
90 #endif
91 }
92
ga_lab(void)93 int ga_lab(void)
94 {
95 return(afile->la.lti);
96 }
97
gm_lab(void)98 int gm_lab(void)
99 {
100 return(ANZLAB);
101 }
102
gm_labm(void)103 long gm_labm(void)
104 {
105 return((long)LABMEM);
106 }
107
ga_labm(void)108 long ga_labm(void)
109 {
110 return(0 /*lni*/);
111 }
112
printllist(fp)113 void printllist(fp)
114 FILE *fp;
115 {
116 int i;
117 LabOcc *p;
118 char *fname = NULL;
119
120 for(i=0;i<afile->la.lti;i++)
121 {
122 ltp=afile->la.lt+i;
123 fprintf(fp,"%s, 0x%04x, %d, 0x%04x\n",ltp->n,ltp->val,ltp->blk,
124 ltp->afl);
125 p = ltp->occlist;
126 if(p) {
127 while(p) {
128 if(fname != p->fname) {
129 if(p!=ltp->occlist) fprintf(fp,"\n");
130 fprintf(fp," %s",p->fname);
131 fname=p->fname;
132 }
133 fprintf(fp," %d", p->line);
134 p=p->next;
135 }
136 fprintf(fp,"\n");
137 }
138 fname=NULL;
139 }
140 }
141
lg_set(char * s)142 int lg_set(char *s ) {
143 int n, er;
144
145 er = ll_search(s,&n);
146
147 if(er==E_OK) {
148 fprintf(stderr,"Warning: global label doubly defined!\n");
149 } else {
150 if(!(er=ll_def(s,&n,0))) {
151 ltp=afile->la.lt+n;
152 ltp->fl=2;
153 ltp->afl=SEG_UNDEF;
154 }
155 }
156 return er;
157 }
158
159
l_def(char * s,int * l,int * x,int * f)160 int l_def(char *s, int *l, int *x, int *f)
161 {
162 int n,er,b,i=0;
163
164 *f=0;
165 b=0;
166 n=0;
167
168 if(s[0]=='-')
169 {
170 *f+=1;
171 i++;
172 } else
173 if(s[0]=='+')
174 {
175 i++;
176 n++;
177 b=0;
178 }
179 while(s[i]=='&')
180 {
181 n=0;
182 i++;
183 b++;
184 }
185 if(!n)
186 b_fget(&b,b);
187
188
189 if(!isalpha(s[i]) && s[i]!='_')
190 er=E_SYNTAX;
191 else
192 {
193 er=ll_search(s+i,&n);
194
195 if(er==E_OK)
196 {
197 ltp=afile->la.lt+n;
198
199 if(*f)
200 {
201 *l=ltp->len+i;
202 } else
203 if(ltp->fl==0)
204 {
205 *l=ltp->len+i;
206 if(b_ltest(ltp->blk,b))
207 er=E_LABDEF;
208 else
209 ltp->blk=b;
210
211 } else
212 er=E_LABDEF;
213 } else
214 if(er==E_NODEF)
215 {
216 if(!(er=ll_def(s+i,&n,b))) /* ll_def(...,*f) */
217 {
218 ltp=afile->la.lt+n;
219 *l=ltp->len+i;
220 ltp->fl=0;
221 }
222 }
223
224 *x=n;
225 }
226 return(er);
227 }
228
l_search(char * s,int * l,int * x,int * v,int * afl)229 int l_search(char *s, int *l, int *x, int *v, int *afl)
230 {
231 int n,er,b;
232
233 *afl=0;
234
235 er=ll_search(s,&n);
236 /*printf("l_search: lab=%s(l=%d), afl=%d, er=%d, n=%d\n",s,*l, *afl,er,n);*/
237 if(er==E_OK)
238 {
239 ltp=afile->la.lt+n;
240 *l=ltp->len;
241 if(ltp->fl == 1)
242 {
243 l_get(n,v,afl);/* *v=lt[n].val;*/
244 *x=n;
245 } else
246 {
247 er=E_NODEF;
248 lz=ltp->n;
249 *x=n;
250 }
251 }
252 else
253 {
254 b_get(&b);
255 er=ll_def(s,x,b); /* ll_def(...,*v); */
256
257 ltp=afile->la.lt+(*x);
258
259 *l=ltp->len;
260
261 if(!er)
262 {
263 er=E_NODEF;
264 lz=ltp->n;
265 }
266 }
267 return(er);
268 }
269
l_vget(int n,int * v,char ** s)270 int l_vget(int n, int *v, char **s)
271 {
272 ltp=afile->la.lt+n;
273 (*v)=ltp->val;
274 *s=ltp->n;
275 return 0;
276 }
277
l_addocc(int n,int * v,int * afl)278 void l_addocc(int n, int *v, int *afl) {
279 LabOcc *p, *pp;
280
281 (void)v; /* quench warning */
282 (void)afl; /* quench warning */
283 ltp = afile->la.lt+n;
284 pp=NULL;
285 p = ltp->occlist;
286 while(p) {
287 if (p->line == filep->fline && p->fname == filep->fname) return;
288 pp = p;
289 p = p->next;
290 }
291 p = malloc(sizeof(LabOcc));
292 if(!p) {
293 fprintf(stderr,"Oops, out of memory!\n");
294 exit(1);
295 }
296 p->next = NULL;
297 p->line = filep->fline;
298 p->fname = filep->fname;
299 if(pp) {
300 pp->next = p;
301 } else {
302 ltp->occlist = p;
303 }
304 }
305
l_get(int n,int * v,int * afl)306 int l_get(int n, int *v, int *afl)
307 {
308 if(crossref) l_addocc(n,v,afl);
309
310 ltp=afile->la.lt+n;
311 (*v)=ltp->val;
312 lz=ltp->n;
313 *afl = ltp->afl;
314 /*printf("l_get('%s'(%d), v=$%04x, afl=%d, fl=%d\n",ltp->n, n, *v, *afl, ltp->fl);*/
315 return( (ltp->fl==1) ? E_OK : E_NODEF);
316 }
317
l_set(int n,int v,int afl)318 void l_set(int n, int v, int afl)
319 {
320 ltp=afile->la.lt+n;
321 ltp->val = v;
322 ltp->fl = 1;
323 ltp->afl = afl;
324 /*printf("l_set('%s'(%d), v=$%04x, afl=%d\n",ltp->n, n, v, afl);*/
325 }
326
ll_exblk(int a,int b)327 static void ll_exblk(int a, int b)
328 {
329 int i;
330 for (i=0;i<afile->la.lti;i++)
331 {
332 ltp=afile->la.lt+i;
333 if((!ltp->fl) && (ltp->blk==a))
334 ltp->blk=b;
335 }
336 }
337
ll_def(char * s,int * n,int b)338 static int ll_def(char *s, int *n, int b) /* definiert naechstes Label nr->n */
339 {
340 int j=0,er=E_NOMEM,hash;
341 char *s2;
342
343 /*printf("ll_def: s=%s\n",s); */
344
345 if(!afile->la.lt) {
346 afile->la.lti = 0;
347 afile->la.ltm = 1000;
348 afile->la.lt = malloc(afile->la.ltm * sizeof(Labtab));
349 }
350 if(afile->la.lti>=afile->la.ltm) {
351 afile->la.ltm *= 1.5;
352 afile->la.lt = realloc(afile->la.lt, afile->la.ltm * sizeof(Labtab));
353 }
354 if(!afile->la.lt) {
355 fprintf(stderr, "Oops: no memory!\n");
356 exit(1);
357 }
358 #if 0
359 if((lti<ANZLAB) /*&&(lni<(long)(LABMEM-MAXLAB))*/)
360 {
361 #endif
362 ltp=afile->la.lt+afile->la.lti;
363 /*
364 s2=ltp->n=ln+lni;
365
366 while((j<MAXLAB-1) && (s[j]!='\0') && (isalnum(s[j]) || s[j]=='_'))
367 {
368 s2[j]=s[j];
369 j++;
370 }
371 */
372 while((s[j]!='\0') && (isalnum(s[j]) || (s[j]=='_'))) j++;
373 s2 = malloc(j+1);
374 if(!s2) {
375 fprintf(stderr,"Oops: no memory!\n");
376 exit(1);
377 }
378 strncpy(s2,s,j);
379 s2[j]=0;
380 /*
381 if(j<MAXLAB)
382 {
383 */
384 er=E_OK;
385 ltp->len=j;
386 ltp->n = s2;
387 ltp->blk=b;
388 ltp->fl=0;
389 ltp->afl=0;
390 ltp->occlist=NULL;
391 hash=hashcode(s,j);
392 ltp->nextindex=afile->la.hashindex[hash];
393 afile->la.hashindex[hash]=afile->la.lti;
394 *n=afile->la.lti;
395 afile->la.lti++;
396 /* lni+=j+1;*/
397 /* }
398 }
399 */
400 /*printf("ll_def return: %d\n",er);*/
401 return(er);
402 }
403
404
405 int ll_search(char *s, int *n) /* search Label in Tabelle ,nr->n */
406 {
407 int i,j=0,k,er=E_NODEF,hash;
408
409 while(s[j] && (isalnum(s[j])||(s[j]=='_'))) j++;
410
411 hash=hashcode(s,j);
412 i=afile->la.hashindex[hash];
413
414 /*printf("search?\n");*/
415 if(i>=afile->la.ltm) return E_NODEF;
416
417 do
418 {
419 ltp=afile->la.lt+i;
420
421 if(j==ltp->len)
422 {
423 for (k=0;(k<j)&&(ltp->n[k]==s[k]);k++);
424
425 if((j==k)&&(!b_test(ltp->blk)))
426 {
427 er=E_OK;
428 break;
429 }
430 }
431
432 if(!i)
433 break;
434
435 i=ltp->nextindex;
436
437 }while(1);
438
439 *n=i;
440 #if 0
441 if(er!=E_OK && er!=E_NODEF)
442 {
443 fprintf(stderr, "Fehler in ll_search:er=%d\n",er);
444 getchar();
445 }
446 #endif
447 return(er);
448 }
449
450 int ll_pdef(char *t)
451 {
452 int n;
453
454 if(ll_search(t,&n)==E_OK)
455 {
456 ltp=afile->la.lt+n;
457 if(ltp->fl)
458 return(E_OK);
459 }
460 return(E_NODEF);
461 }
462
463 int l_write(FILE *fp)
464 {
465 int i, afl, n=0;
466
467 if(noglob) {
468 fputc(0, fp);
469 fputc(0, fp);
470 return 0;
471 }
472 for (i=0;i<afile->la.lti;i++) {
473 ltp=afile->la.lt+i;
474 if((!ltp->blk) && (ltp->fl==1)) {
475 n++;
476 }
477 }
478 fputc(n&255, fp);
479 fputc((n>>8)&255, fp);
480 for (i=0;i<afile->la.lti;i++)
481 {
482 ltp=afile->la.lt+i;
483 if((!ltp->blk) && (ltp->fl==1)) {
484 fprintf(fp, "%s",ltp->n);
485 fputc(0,fp);
486 afl = ltp->afl;
487 /* hack to switch undef and abs flag from internal to file format */
488 /*printf("label %s, afl=%04x, A_FMASK>>8=%04x\n", ltp->n, afl, A_FMASK>>8);*/
489 if( (afl & (A_FMASK>>8)) < SEG_TEXT) afl^=1;
490 fputc(afl,fp);
491 fputc(ltp->val&255, fp);
492 fputc((ltp->val>>8)&255, fp);
493 }
494 }
495 /*fputc(0,fp);*/
496 return 0;
497 }
498
499 static int bt[MAXBLK];
500 static int blk;
501 static int bi;
502
503 int b_init(void)
504 {
505 blk =0;
506 bi =0;
507 bt[bi]=blk;
508
509 return(E_OK);
510 }
511
512 int b_depth(void)
513 {
514 return bi;
515 }
516
517 int ga_blk(void)
518 {
519 return(blk);
520 }
521
522 int b_open(void)
523 {
524 int er=E_BLKOVR;
525
526 if(bi<MAXBLK-1)
527 {
528 bt[++bi]=++blk;
529
530 er=E_OK;
531 }
532 return(er);
533 }
534
535 int b_close(void)
536 {
537
538 if(bi)
539 {
540 ll_exblk(bt[bi],bt[bi-1]);
541 bi--;
542 } else {
543 return E_BLOCK;
544 }
545
546 return(E_OK);
547 }
548
549 static int b_get(int *n)
550 {
551 *n=bt[bi];
552
553 return(E_OK);
554 }
555
556 static int b_fget(int *n, int i)
557 {
558 if((bi-i)>=0)
559 *n=bt[bi-i];
560 else
561 *n=0;
562 return(E_OK);
563 }
564
565 static int b_test(int n)
566 {
567 int i=bi;
568
569 while( i>=0 && n!=bt[i] )
570 i--;
571
572 return( i+1 ? E_OK : E_NOBLK );
573 }
574
575 static int b_ltest(int a, int b) /* testet ob bt^-1(b) in intervall [0,bt^-1(a)] */
576 {
577 int i=0,er=E_OK;
578
579 if(a!=b)
580 {
581 er=E_OK;
582
583 while(i<=bi && b!=bt[i])
584 {
585 if(bt[i]==a)
586 {
587 er=E_NOBLK;
588 break;
589 }
590 i++;
591 }
592 }
593 return(er);
594 }
595
596