mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 17:04:19 +00:00
866 lines
26 KiB
Plaintext
866 lines
26 KiB
Plaintext
1File: SYMT.C Page 1
|
|
1 /*
|
|
2 Copyright 1981
|
|
3 Alcyon Corporation
|
|
4 8716 Production Ave.
|
|
5 San Diego, Ca. 92121
|
|
6 */
|
|
7
|
|
8 #include "as68.h"
|
|
9
|
|
10 /* symbol table and misc routines*/
|
|
11
|
|
12 int errno;
|
|
13 char *ermsg[];
|
|
14 char tfilname[];
|
|
15 char initfnam[];
|
|
16 char ldfn[];
|
|
17 char tlab1[];
|
|
18 int stdofd;
|
|
19 int ftudp;
|
|
20 int poslab;
|
|
21
|
|
22 /*output it for beginning of statement*/
|
|
23 opitb()
|
|
24 {
|
|
25 stbuf[0].itty = ITBS; /*beginning of statement*/
|
|
26 stbuf[0].itop = (fchr!=EOLC) ? absln : absln-1;
|
|
27 stbuf[1].itty = ITSY; /*label entry*/
|
|
28 stbuf[1].itop.ptrw2 = lblpt; /*pointer to symbol or 0*/
|
|
29
|
|
30 /*put opcode in it buffer*/
|
|
31 stbuf[2].itty = ITSY;
|
|
32 stbuf[2].itrl = modelen; /*mode of instr(byte, word, long)*/
|
|
33 stbuf[2].itop.ptrw2 = opcpt; /*pointer to opcode in main table*/
|
|
34 stbuf[3].itty = ITCN;
|
|
35 stbuf[3].itrl = rlflg; /*relocation base*/
|
|
36 stbuf[3].itop = loctr; /*pass1 location counter*/
|
|
37 itwc = ITOP1; /*next available slot-currently 4*/
|
|
38 pitw = &stbuf[ITOP1].itty; /*init the pointer*/
|
|
39 }
|
|
40
|
|
41 /*
|
|
42 * get an input term (symbol, constant, or special character)
|
|
43 * call with:
|
|
44 * the first character in fchr
|
|
45 * returns:
|
|
46 * item type in itype
|
|
47 * item value in ival if item is a constant or special character
|
|
48 * if it is a symbol it is placed at the end of the main table
|
|
49
|
|
50 * meaning of state table:
|
|
51
|
|
52 * currently getting: symbol(0) constant(1) beginning(2)
|
|
53
|
|
54 * next char:
|
|
55 * digit(0) 0 1 1
|
|
56
|
|
57 * letter(3) 0 3 0
|
|
58
|
|
59 * special char(6) 3 3 3
|
|
1File: SYMT.C Page 2
|
|
60
|
|
61 * contents of the state table is the next state. processing stops when
|
|
62 * state 3 is encountered. state 2 is the beginning state.
|
|
63 */
|
|
64 int sttbl[] {0,1,1,0,3,0,3,3,3}; /*state table for parser*/
|
|
65
|
|
66 gterm(constpc)
|
|
67 int constpc;
|
|
68 {
|
|
69 register smode, i;
|
|
70 register char *p;
|
|
71 register int tmode;
|
|
72 register char *j;
|
|
73 long num;
|
|
74 char istr[80];
|
|
75
|
|
76 /* if(fchr == '\'' || fchr == '"') */ /* Fucking Whitesmith's */
|
|
77 if(fchr == 047 || fchr == 042)
|
|
78 if(astring()) /*maybe ascii string*/
|
|
79 return;
|
|
80 smode = 2; /*beginning state*/
|
|
81 i = 0;
|
|
82 p = istr;
|
|
83
|
|
84 /*loop to put item on istr*/
|
|
85 while(fchr>=' ') { /*until a control char*/
|
|
86 if(smode==2 && fchr=='.')
|
|
87 tmode = 3;
|
|
88 else if(isalpha(fchr) || fchr=='~' || fchr=='_' || (fchr=='$'&&i))
|
|
89 tmode=3;
|
|
90 else if(isdigit(fchr))
|
|
91 tmode=0;
|
|
92 else
|
|
93 tmode = 6;
|
|
94 tmode = sttbl[tmode+smode]; /*new state*/
|
|
95 if(tmode==3) break; /*end of item*/
|
|
96 smode = tmode;
|
|
97 *p++ = fchr; /*save character*/
|
|
98 i++;
|
|
99 fchr=gchr();
|
|
100 }
|
|
101
|
|
102 /* end of item*/
|
|
103 switch(smode) {
|
|
104
|
|
105 case 0: /*symbol*/
|
|
106 *p = '\0'; /*end of symbol*/
|
|
107 itype = ITSY; /*symbol*/
|
|
108 pack(istr,lmte); /*put symbol at end of main table*/
|
|
109 j = lemt(sirt,FALSE);
|
|
110 if(istr[0]!='~' && !poslab && (j->flags&(SYEQ|SYER))==SYEQ) {
|
|
111 itype = (j->flags&SYRM) ? ITRM : ITCN; /* [vlh] */
|
|
112 ival = j->vl1;
|
|
113 reloc = ((j->flags)&SYRO) ? TEXT : ((j->flags)&SYRA) ? DATA :
|
|
114 ((j->flags)&SYBS) ? BSS : ABS;
|
|
115 }
|
|
116 return;
|
|
117
|
|
118 case 1: /*constant*/
|
|
1File: SYMT.C Page 3
|
|
119 if(!constant(&num,istr,i)) {
|
|
120 uerr(17); /*illegal constant*/
|
|
121 num = 0;
|
|
122 }
|
|
123 ival = num;
|
|
124 itype = ITCN;
|
|
125 reloc = ABS;
|
|
126 return;
|
|
127
|
|
128 case 2: /*just a special char*/
|
|
129 switch(fchr) {
|
|
130
|
|
131 case '*': /*location counter*/
|
|
132 if(starmul) { /*multiply*/
|
|
133 starmul = 0;
|
|
134 goto specsy;
|
|
135 }
|
|
136 refpc++; /*referenced pgm ctr*/
|
|
137 reloc = rlflg; /*relocation of location counter*/
|
|
138 ival = loctr;
|
|
139 itype = (constpc) ? ITCN : ITPC;
|
|
140 break;
|
|
141
|
|
142
|
|
143 case '$': /*hex constant*/
|
|
144 oconst(16);
|
|
145 return;
|
|
146
|
|
147 case '@': /*octal const*/
|
|
148 oconst(8);
|
|
149 return;
|
|
150
|
|
151 case '%': /*binary const*/
|
|
152 oconst(2);
|
|
153 return;
|
|
154
|
|
155 case '#':
|
|
156 immed[opdix]++;
|
|
157 goto specsy;
|
|
158
|
|
159 case '(':
|
|
160 indir[opdix]++;
|
|
161 plevel++;
|
|
162 goto specsy;
|
|
163
|
|
164 case ')':
|
|
165 plevel--;
|
|
166 goto specsy;
|
|
167
|
|
168 default:
|
|
169 specsy:
|
|
170 itype = ITSP; /*return special char*/
|
|
171 ival = fchr;
|
|
172 }
|
|
173 if(fchr != EOLC)
|
|
174 fchr=gchr(); /*get next char*/
|
|
175 if((ival=='>' && fchr=='>') || (ival=='<' && fchr=='<'))
|
|
176 fchr=gchr(); /*shift op, ignore second char*/
|
|
177 return;
|
|
1File: SYMT.C Page 4
|
|
178
|
|
179 default:
|
|
180 abort(); /*not possible*/
|
|
181 }
|
|
182 }
|
|
183
|
|
184 /*check for an ascii string enclosed in single quotes*/
|
|
185
|
|
186 astring()
|
|
187 {
|
|
188 register char delim;
|
|
189
|
|
190 /* if(fchr != '\'' && fchr != '"') *//*valid delimiter*/
|
|
191 if(fchr != 047 && fchr != 042)
|
|
192 return;
|
|
193 delim = fchr;
|
|
194 if(equflg || (itype==ITSP && ival.wd2=='#')) { /*immediate operand*/
|
|
195 if(astr1(delim)) {
|
|
196 fchr = gchr();
|
|
197 if(fchr!=delim)
|
|
198 xerr(19);
|
|
199 fchr=gchr();
|
|
200 }
|
|
201 return((equflg) ? 1 : 0);
|
|
202 }
|
|
203 while(astr1(delim)) {
|
|
204 itype = ITSP;
|
|
205 ival = ','; /*separate by commas*/
|
|
206 reloc = ABS;
|
|
207 opitoo();
|
|
208 }
|
|
209 return(0);
|
|
210 }
|
|
211
|
|
212 astr1(adelim)
|
|
213 {
|
|
214 register delim,i,retv;
|
|
215 register long l;
|
|
216
|
|
217 delim = adelim;
|
|
218 i = 0; l = 0;
|
|
219 retv = 1;
|
|
220 while((fchr=gchr()) != EOF) {
|
|
221 if(fchr==delim) {
|
|
222 fchr = gchr();
|
|
223 if(fchr != delim) {
|
|
224 retv = 0; /*end of string*/
|
|
225 break;
|
|
226 }
|
|
227 }
|
|
228 if(fchr == EOLC) {
|
|
229 xerr(19);
|
|
230 retv = 0; /*end of string*/
|
|
231 break;
|
|
232 }
|
|
233 l = (l<<8) | fchr;
|
|
234 if(++i >= modelen) {
|
|
235 if((fchr=gchr()) == delim) {
|
|
236 fchr = gchr();
|
|
1File: SYMT.C Page 5
|
|
237 retv = 0; /*end of string*/
|
|
238 }
|
|
239 else
|
|
240 peekc = fchr; /*next char in string*/
|
|
241 break; /*filled one bucket*/
|
|
242 }
|
|
243 }
|
|
244 while(i < modelen) {
|
|
245 l =<< 8;
|
|
246 i++;
|
|
247 }
|
|
248 itype = ITCN;
|
|
249 ival = l;
|
|
250 reloc = ABS;
|
|
251 if(!equflg)
|
|
252 opitoo(); /*output one operand*/
|
|
253 return(retv);
|
|
254 }
|
|
255
|
|
256 /*get constant given radix*/
|
|
257 oconst(ardx)
|
|
258 {
|
|
259 register trdx,j;
|
|
260 register long i;
|
|
261
|
|
262 switch (ardx) { /* radix as power of 2 */
|
|
263 case 16 : trdx = 4; break;
|
|
264 case 8 : trdx = 3; break;
|
|
265 case 2 : trdx = 1; break;
|
|
266 default :
|
|
267 rpterr("invalid radix in oconst");
|
|
268 abort();
|
|
269 }
|
|
270 i=0;
|
|
271 while(1) {
|
|
272 fchr=gchr();
|
|
273 j=fchr;
|
|
274 if(isdigit(j))
|
|
275 j =- '0';
|
|
276 else if((j=tolower(j))>='a' && j<='f')
|
|
277 j = j-'a'+10;
|
|
278 else
|
|
279 break; /*not valid numeric char*/
|
|
280 if(j>=0 && j<ardx)
|
|
281 i = (i<<trdx)+j;
|
|
282 else
|
|
283 break;
|
|
284 }
|
|
285 ival = i;
|
|
286 itype = ITCN;
|
|
287 reloc = ABS;
|
|
288 }
|
|
289
|
|
290
|
|
291 /*convert ascii constant to binary*/
|
|
292 constant(pnum,pstr,idx)
|
|
293 long *pnum;
|
|
294 char *pstr;
|
|
295 {
|
|
1File: SYMT.C Page 6
|
|
296 register i,j;
|
|
297 register char *p;
|
|
298 register long l;
|
|
299
|
|
300 p = pstr;
|
|
301 l = 0;
|
|
302 for(i=0; i<idx; i++) {
|
|
303 j = *pstr++;
|
|
304 if(isdigit(j))
|
|
305 j =- '0';
|
|
306 if(j<0 || j>=10)
|
|
307 return(0);
|
|
308 l = (l<<3) + (l<<1) + j; /* l = l*10 + j*/
|
|
309 }
|
|
310 *pnum = l;
|
|
311 return(1);
|
|
312 }
|
|
313
|
|
314 /*
|
|
315 * method for looking up entries in the main table
|
|
316 *
|
|
317 * Note: The entry to be looked up must be placed at the end
|
|
318 * of the main table. The global cell 'lmte'(last main
|
|
319 * entry) points to the next available entry in the main
|
|
320 * table. The address of an initial reference table must
|
|
321 * also be provided.
|
|
322 *
|
|
323 * 1) Compute the hash code for the symbol and add it to the base address
|
|
324 * of the initial reference table given as input. Thus, two words are
|
|
325 * accessed which define the chain on which the symbol must be if it
|
|
326 * is in the table at all.
|
|
327 *
|
|
328 * 2) Alter the table link of the last symbol in the chain so that it
|
|
329 * points to the symbol being looked up. Note that the symbol to be
|
|
330 * looked up is always placed at the end of the main table before
|
|
331 * calling the lookup routine. This essentially adds one more element
|
|
332 * to the end of the chain, namely the symbol to be looked up.
|
|
333 *
|
|
334 * 3) Now start at the first symbol in the chain and follow the chain
|
|
335 * looking for a symbol equal to the smbol being looked up. It is
|
|
336 * guaranteed that such a symbol will be found because it is always
|
|
337 * the last symbol on the chain.
|
|
338 *
|
|
339 * 4) When the symbol is found, check to see if it is the last symbol
|
|
340 * on the chain. If not, the symbol being looked for is in the table
|
|
341 * and has been found. If it is the last symbol, the symbol being
|
|
342 * looked up is not in the table.
|
|
343 *
|
|
344 * 5) In the case the looked up symbol is not found, it is usually added
|
|
345 * to the end of the table. This is done simply b changing the
|
|
346 * initial reference table entry which points to the previous
|
|
347 * last symbol on the chain so that is now points to the symbol at the
|
|
348 * end of the main table. In case the symbol just looked up is not to
|
|
349 * be added to the main table then no action is needed . This means
|
|
350 * that the table link of the last symbol on a chain may point any-
|
|
351 * where.
|
|
352 *
|
|
353 * look up entry in the main table
|
|
354 * call with:
|
|
1File: SYMT.C Page 7
|
|
355 * address of initial reference table
|
|
356 * entry to be looked up at the end of the main table
|
|
357 * returns:
|
|
358 * a pointer to the entry. if this pointer is equal to
|
|
359 * lmte then the symbol was not previously in the table.
|
|
360 */
|
|
361
|
|
362 char *lemt(airt,oplook)
|
|
363 char **airt;
|
|
364 int oplook; /* if true then looking in opcode table */
|
|
365 {
|
|
366 register char *mtpt;
|
|
367 register int *p1, *p2;
|
|
368 register int i, j;
|
|
369
|
|
370 if (oplook) { /* [vlh] get rid of preceding '.', to lowercase */
|
|
371 if (lmte->name[0]=='.') {
|
|
372 lmte->name[NAMELEN-1] = NULL; /* in case of '.' */
|
|
373 j = 1;
|
|
374 }
|
|
375 else j = 0;
|
|
376 for (i=0; j<NAMELEN; i++, j++)
|
|
377 lmte->name[i] = tolower(lmte->name[j]);
|
|
378 }
|
|
379
|
|
380 pirt = airt + hash(); /*hashed ptr to irt*/
|
|
381 mtpt = pirt->irfe; /*pointer to first entry in chain*/
|
|
382 if(!mtpt) /*empty chain*/
|
|
383 mtpt = lmte; /*start at end of main table*/
|
|
384 else
|
|
385 (pirt->irle)->tlnk = lmte; /*last entry in chain is new symbol*/
|
|
386
|
|
387 /*loop to locate entry in main table*/
|
|
388 lemtl:
|
|
389 p1 = &mtpt->name[0];
|
|
390 p2 = &lmte->name[0];
|
|
391 i = NAMELEN/(sizeof i);
|
|
392 while(i) {
|
|
393 if(*p1++ != *p2++) {
|
|
394 mtpt = mtpt->tlnk; /*go to next entry in chain*/
|
|
395 goto lemtl;
|
|
396 }
|
|
397 i--;
|
|
398 }
|
|
399 return(mtpt);
|
|
400 }
|
|
401
|
|
402 /* compute a hash code for the last entry in the main table*/
|
|
403 /* returns the hash code*/
|
|
404 hash()
|
|
405 {
|
|
406 register int i;
|
|
407 register ht1;
|
|
408 register char *p;
|
|
409
|
|
410 ht1 = 0;
|
|
411 p = &lmte->name[0];
|
|
412 for(i=0; i<NAMELEN; i++)
|
|
413 ht1 =+ *p++;
|
|
1File: SYMT.C Page 8
|
|
414 return(ht1&(SZIRT-2)); /*make hash code even and between 0 & SZIRT-2*/
|
|
415 }
|
|
416
|
|
417 /*
|
|
418 * Make an entry in the main table
|
|
419 * assumes :
|
|
420 * entry to be made is pointed at by lmte
|
|
421 * pirt points to the correct initial reference table entry.
|
|
422 */
|
|
423 mmte()
|
|
424 {
|
|
425 pirt->irle = lmte; /*pointer to last entry in chain*/
|
|
426 if(pirt->irfe == 0) /*first entry in chain*/
|
|
427 pirt->irfe = lmte;
|
|
428 lmte =+ STESIZE; /*bump last main table entry pointer*/
|
|
429 if(lmte>=emte) { /*main table overflow*/
|
|
430 if(sbrk(STESIZE*ICRSZMT) == -1){ /*get more memory*/
|
|
431 rpterr("symbol table overflow\n");
|
|
432 endit();
|
|
433 }
|
|
434 else {
|
|
435 emte =+ STESIZE*ICRSZMT; /*move end of main table*/
|
|
436 cszmt =+ ICRSZMT;
|
|
437 }
|
|
438 }
|
|
439 }
|
|
440
|
|
441 /*
|
|
442 * make an entry in the main table for a directive
|
|
443 * call with:
|
|
444 * pointer to string containing directive name
|
|
445 * address of routine to handle directive in pass one
|
|
446 * address of routine to handle directive in pass two
|
|
447 */
|
|
448 mdemt(mdstr,dirnum)
|
|
449 char *mdstr;
|
|
450 {
|
|
451 register char *mdept;
|
|
452
|
|
453 pack(mdstr,lmte); /*pack name at end of main table*/
|
|
454 mdept=lemt(oirt,TRUE); /*look up in opcode table*/
|
|
455 if(mdept != lmte) { /*best not be there already*/
|
|
456 uerr(5);
|
|
457 abort();
|
|
458 return;
|
|
459 }
|
|
460 mmte(); /*make main table entry*/
|
|
461 mdept->flags =| OPDR|SYIN; /*directive*/
|
|
462 mdept->vl1 = dirnum; /*directive #*/
|
|
463 }
|
|
464
|
|
465 /*
|
|
466 * pack a string into an entry in the main table
|
|
467 * call with:
|
|
468 * pointer to the string
|
|
469 * pointer to desired entry in the main table
|
|
470 */
|
|
471 pack(apkstr,apkptr)
|
|
472 char *apkstr, *apkptr;
|
|
1File: SYMT.C Page 9
|
|
473 {
|
|
474 register i;
|
|
475 register char *pkstr, *pkptr;
|
|
476
|
|
477 pkstr = apkstr;
|
|
478 pkptr = apkptr;
|
|
479 i = NAMELEN;
|
|
480 while(*pkstr && i) {
|
|
481 *pkptr++ = *pkstr++;
|
|
482 i--;
|
|
483 }
|
|
484 while(i--)
|
|
485 *pkptr++ = '\0'; /*pad with nulls*/
|
|
486 }
|
|
487
|
|
488 /* function to get characters for source file*/
|
|
489 int xcol = 0; /* Column Counter */
|
|
490 int spcnt = 0; /* Space count for tab expansion */
|
|
491 gchr()
|
|
492 {
|
|
493 register chr1;
|
|
494
|
|
495 if(peekc) {
|
|
496 chr1 = peekc;
|
|
497 peekc = 0;
|
|
498 if(chr1 != SOH)
|
|
499 xcol--;
|
|
500 }
|
|
501 else if (spcnt)
|
|
502 {
|
|
503 spcnt--;
|
|
504 return(' ');
|
|
505 }
|
|
506 else
|
|
507 {
|
|
508 gchr1:
|
|
509 if(sbuflen<=0){ /*nothing on input buffer*/
|
|
510 sbuflen=read(ifn,sbuf,512); /*read in source*/
|
|
511 if(sbuflen<=0)
|
|
512 return(EOF); /*end of file*/
|
|
513 psbuf = sbuf;
|
|
514 }
|
|
515 chr1 = *psbuf++;
|
|
516 sbuflen--;
|
|
517 }
|
|
518 if (chr1 == SOH) /*preprocessor flag*/
|
|
519 goto gchr1; /*ignore it*/
|
|
520 if(chr1 == EOLC) { /*end of line*/
|
|
521 xcol = -1; /* Clear column counter */
|
|
522 if(!p2flg) /*pass 1 only*/
|
|
523 absln++;
|
|
524 }
|
|
525 if(chr1=='\t') /*convert tabs to spaces*/
|
|
526 {
|
|
527 spcnt += 7 - (xcol&7); /* This many spaces */
|
|
528 xcol += spcnt; /* New column number */
|
|
529 chr1 = ' ';
|
|
530 }
|
|
531 xcol++;
|
|
1File: SYMT.C Page 10
|
|
532 return(chr1);
|
|
533 }
|
|
534
|
|
535 /*
|
|
536 * write out intermediate text for one statement
|
|
537 * call with
|
|
538 * the it for the statement in stbuf
|
|
539 */
|
|
540 wostb()
|
|
541 {
|
|
542 register int woix;
|
|
543 register short *itwo;
|
|
544 register int i;
|
|
545
|
|
546 if(stbuf[0].itty != ITBS) abort(); /*not beginning of stmt*/
|
|
547 itwo = &stbuf;
|
|
548 woix = stbuf[0].itrl & 0377; /*unsigned byte*/
|
|
549 while(woix--) {
|
|
550 for(i=0; i<(sizeof stbuf[0])/(sizeof *itwo); i++) {
|
|
551 doitwr(*itwo++);
|
|
552 }
|
|
553 }
|
|
554 /* debug(); //call debug package*/
|
|
555 }
|
|
556
|
|
557 doitwr(word)
|
|
558 short word;
|
|
559 {
|
|
560 short i;
|
|
561
|
|
562 if( pitix < itbuf || pitix > &itbuf[ITBSZ] ) {
|
|
563 printf("doitwr: it buffer botch\n");
|
|
564 endit();
|
|
565 }
|
|
566 if( pitix >= &itbuf[ITBSZ]) {
|
|
567 if(write(itfn,itbuf,ITBSZ*(sizeof i)) != ITBSZ*(sizeof i)) {
|
|
568 rpterr("it write error errno=%o\n",errno);
|
|
569 endit();
|
|
570 }
|
|
571 pitix = itbuf;
|
|
572 }
|
|
573 *pitix++ = word;
|
|
574 }
|
|
575
|
|
576 /*
|
|
577 * user source error
|
|
578 * call with:
|
|
579 * number to indicate reason for error
|
|
580 * types the error number and the line number on which
|
|
581 * the error occured.
|
|
582 */
|
|
583 uerr(errn)
|
|
584 {
|
|
585 if(p2flg) { /*pass 2 gets two ampersands*/
|
|
586 in_err++; /* [vlh] instrlen <- pass1 estimation */
|
|
587 printf("&& %d: %s\n",p2absln,ermsg[errn-1]);
|
|
588 }
|
|
589 else
|
|
590 printf("& %d: %s\n",(fchr==EOLC)?absln-1:absln,ermsg[errn-1]);
|
|
1File: SYMT.C Page 11
|
|
591 nerror++;
|
|
592 }
|
|
593 /*
|
|
594 * user error that causes the statement to be abandoned
|
|
595 * call with:
|
|
596 * error number
|
|
597 */
|
|
598 xerr(xern)
|
|
599 {
|
|
600 uerr(xern); /*type error message*/
|
|
601 if(!p2flg) /*pass one*/
|
|
602 igrst(); /*pass rest of source*/
|
|
603 }
|
|
604
|
|
605 /* abort the assembly*/
|
|
606 abort()
|
|
607 {
|
|
608 rpterr("as68 abort\n");
|
|
609 nerror++;
|
|
610 endit();
|
|
611 }
|
|
612
|
|
613 /*ignore rest of statement*/
|
|
614 igrst()
|
|
615 {
|
|
616 while(fchr!=EOLC && fchr!=EOF) /*until end of line*/
|
|
617 fchr=gchr();
|
|
618 while((fchr=gchr())==EOLC) ; /*ignore null lines*/
|
|
619 }
|
|
620
|
|
621 /*ignore blanks after a label*/
|
|
622 ligblk()
|
|
623 {
|
|
624 if(fchr == EOF) return;
|
|
625 igblk();
|
|
626 if(fchr==EOLC) {
|
|
627 fchr=gchr();
|
|
628 ligblk();
|
|
629 }
|
|
630 }
|
|
631
|
|
632 rubout()
|
|
633 {
|
|
634 nerror = -1;
|
|
635 endit();
|
|
636 }
|
|
637
|
|
638 /* exit from the assembler*/
|
|
639 endit()
|
|
640 {
|
|
641 LASTCHTFN = itfnc;
|
|
642 unlink(tfilname); /*delete temporary files*/
|
|
643 LASTCHTFN = trbfnc;
|
|
644 unlink(tfilname);
|
|
645 LASTCHTFN = dafnc;
|
|
646 unlink(tfilname);
|
|
647 LASTCHTFN = drbfnc;
|
|
648 unlink(tfilname);
|
|
649 if(nerror != -1) { /*not rubout*/
|
|
1File: SYMT.C Page 12
|
|
650 if(ftudp)
|
|
651 putchar('\n');
|
|
652 }
|
|
653 if(nerror > 0) {
|
|
654 fprintf(stderr,"& %d errors\n",nerror);
|
|
655 }
|
|
656 if (initflg)
|
|
657 unlink(ldfn); /* [vlh] get rid of empty .o file */
|
|
658 exit(nerror!=0);
|
|
659 }
|
|
660
|
|
661 /*
|
|
662 * open files
|
|
663 * call with:
|
|
664 * pointer to name of file to open
|
|
665 * flag for how to open
|
|
666 * 0 => read
|
|
667 * 1 => write
|
|
668 */
|
|
669 openfi(pname,hflag)
|
|
670 char *pname;
|
|
671 {
|
|
672 register fd;
|
|
673
|
|
674 fd = (hflag==1) ? creat(pname,0666,1) : open(pname,hflag,1);
|
|
675 if(fd < 0) { /*open failed*/
|
|
676 rpterr("can't open %s errno=%o\n",pname,errno);
|
|
677 endit();
|
|
678 }
|
|
679 return(fd);
|
|
680 }
|
|
681
|
|
682 /* get a temp file for the intermediate text*/
|
|
683 char lastfile = 'A';
|
|
684 gettempf()
|
|
685 {
|
|
686 register i,j;
|
|
687 register char *p;
|
|
688
|
|
689 LASTCHTFN = lastfile++; /* Creat temp name */
|
|
690 if((j=creat(tfilname,0600,1)) >= 0)
|
|
691 return(j); /* File created OK */
|
|
692 rpterr("Unable to open temporary file\n");
|
|
693 endit();
|
|
694 }
|
|
695
|
|
696 /* move label name from lbt to main table entry pointed to by lmte*/
|
|
697 setname()
|
|
698 {
|
|
699 register i;
|
|
700 register int *p1, *p2;
|
|
701
|
|
702 p1 = &lmte->name[0];
|
|
703 for(p2 = &lbt[0]; p2 < &lbt[NAMELEN]; ) {
|
|
704 *p1++ = *p2;
|
|
705 *p2++ = 0;
|
|
706 }
|
|
707 }
|
|
708
|
|
1File: SYMT.C Page 13
|
|
709 /* get the initialized main table and initial reference tables from*/
|
|
710 /* the initialize file*/
|
|
711 getsymtab()
|
|
712 {
|
|
713 long j; /* length for read / write */
|
|
714 register char **p;
|
|
715 register struct symtab *p1;
|
|
716 register char *p2;
|
|
717 register fd,i;
|
|
718
|
|
719 if((fd=open(initfnam,0,1)) < 0) {
|
|
720 rerr:
|
|
721 printf("& Unable to read init file: %s\n", initfnam);
|
|
722 endit();
|
|
723 }
|
|
724 if(read(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
|
|
725 goto rerr;
|
|
726 }
|
|
727
|
|
728 if(read(fd,oirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0]))
|
|
729 goto rerr;
|
|
730
|
|
731 if(read(fd,&j,(sizeof j)) != (sizeof j)) /* Read Count */
|
|
732 goto rerr; /* Y-U-K!!! */
|
|
733
|
|
734 if((i=read(fd,bmte,(int)j)) != j) /* Read table */
|
|
735 goto rerr;
|
|
736
|
|
737 if((i%STESIZE) != 0)
|
|
738 goto rerr;
|
|
739
|
|
740 lmte = bmte + i;
|
|
741 p2 = bmte-1;
|
|
742 for(p=sirt; p<&sirt[SZIRT]; p++) {
|
|
743 if(*p)
|
|
744 *p =+ (long)p2;
|
|
745 }
|
|
746 for(p=oirt; p<&oirt[SZIRT]; p++) {
|
|
747 if(*p)
|
|
748 *p =+ (long)p2;
|
|
749 }
|
|
750 for(p1=bmte; p1<lmte; p1++) {
|
|
751 if(p1->tlnk)
|
|
752 p1->tlnk =+ (long)p2;
|
|
753 }
|
|
754 close(fd);
|
|
755 }
|
|
756
|
|
757 /* write the initialization file*/
|
|
758 putsymtab()
|
|
759 {
|
|
760 long j;
|
|
761 register char **p;
|
|
762 register struct symtab *p1;
|
|
763 register char *p2;
|
|
764 register fd,i;
|
|
765
|
|
766 if((fd=creat(initfnam,0644,1))<0) {
|
|
767 printf("& Cannot create init: %s\n", initfnam);
|
|
1File: SYMT.C Page 14
|
|
768 return;
|
|
769 }
|
|
770 /*
|
|
771 * change all pointers so that they are relative to the beginning
|
|
772 * of the symbol table
|
|
773 */
|
|
774 p2 = bmte-1;
|
|
775 for(p=sirt; p<&sirt[SZIRT]; p++) {
|
|
776 if(*p)
|
|
777 *p =- (long)p2;
|
|
778 }
|
|
779 for(p=oirt; p<&oirt[SZIRT]; p++) {
|
|
780 if(*p)
|
|
781 *p =- (long)p2;
|
|
782 }
|
|
783 for(p1=bmte; p1<lmte; p1++) {
|
|
784 if(p1->tlnk)
|
|
785 p1->tlnk =- (long)p2;
|
|
786 }
|
|
787
|
|
788 if(write(fd,sirt,SZIRT*(sizeof sirt[0])) != SZIRT*(sizeof sirt[0])) {
|
|
789 goto werr;
|
|
790 }
|
|
791
|
|
792 if(write(fd,oirt,SZIRT*(sizeof oirt[0])) != SZIRT*(sizeof oirt[0]))
|
|
793 goto werr;
|
|
794
|
|
795 i = lmte - bmte; /*length of current main table*/
|
|
796 if((i % STESIZE) != 0) {
|
|
797 goto werr;
|
|
798 }
|
|
799 j = i;
|
|
800 if(write(fd,&j,(sizeof j)) != (sizeof j)) /* Y-U-K!! */
|
|
801 goto werr;
|
|
802
|
|
803 if(write(fd,bmte,i) != i) {
|
|
804 werr:
|
|
805 printf("& Write error on init file: %s\n",initfnam);
|
|
806 return;
|
|
807 }
|
|
808 close(fd);
|
|
809 }
|
|
810
|
|
811 /* print an error on file descriptor 2*/
|
|
812 /* used for errors with disasterous consequences*/
|
|
813 rpterr(ptch,x1,x2,x3,x4,x5,x6)
|
|
814 char *ptch;
|
|
815 {
|
|
816 if(prtflg==0) /* Check for paging output */
|
|
817 page(); /* Perform page checks */
|
|
818 fprintf(stderr,"& %d: ",absln);
|
|
819 fprintf(stderr,ptch,x1,x2,x3,x4,x5,x6);
|
|
820 }
|
|
821
|
|
822 /* set the file name for the relocatable object file (sourcefile.o)*/
|
|
823 setldfn(ap)
|
|
824 char *ap;
|
|
825 {
|
|
826 register char *p1,*p2;
|
|
1File: SYMT.C Page 15
|
|
827
|
|
828 p1 = ap;
|
|
829 p2 = ldfn;
|
|
830 while(*p1) {
|
|
831 *p2++ = *p1++;
|
|
832 }
|
|
833 if(*(p2-2) != '.') { /*not name.?*/
|
|
834 *p2++ = '.';
|
|
835 *p2++ = 'o';
|
|
836 }
|
|
837 else { /* is name.? */
|
|
838 *(p2-1) = 'o';
|
|
839 }
|
|
840 *p2 = '\0';
|
|
841 }
|
|
842
|
|
843 savelab()
|
|
844 {
|
|
845 register int *p1, *p2;
|
|
846
|
|
847 p2 = &lmte->name[0];
|
|
848 for(p1= &tlab1[0]; p1 < &tlab1[NAMELEN]; )
|
|
849 *p1++ = *p2++;
|
|
850 }
|