In asxlat, translate ! to ~ (not operator; used with bic instruction)
[pdp11_as.git] / as2.c
1 /* as2.c */
2
3 #include <stdio.h> /* temp */
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <signal.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #ifdef pdp11
12 typedef int intptr_t;
13 #include <sys/file.h>
14 #define SEEK_SET L_SET
15 #endif
16 #include "as0.h"
17 #include "as2.h"
18
19 /* Sept 10, 1997 - fix coredump caused by using wrong error reporting */
20 /*      calling convention in three places. */
21
22 /*      .globl  _signal, _close, _lseek, _unlink, _umask, _chmod, __exit */
23 /*      .globl  _write, _read, _brk, _end, _open, _realloc, _fchmod */
24 /*      .globl  pass1, hshsiz, outmod, dot, dotdot, error */
25 /*      .globl  checkeos, curfb, savdot, ch, line, savop, inbuf, errflg */
26 /*      .globl  fbptr, fbtbl, symnum, hshtab, symblk, symleft, dotrel */
27 /*      .globl  symtab, aexit, overlaid, defund, a.outp, passno, filerr */
28 /*      .globl  wrterr, argb, curfb, nxtfb, usymtab */
29 /*      .globl  fin, fout, a.tmp1, ibufc, ibufp, obufp, outbuf, symbol */
30 /*      .globl  PSTENTSZ, SYMENTSZ, SYMBLKSZ, Newsym */
31
32 intptr_t *adrptr; /* r5 */
33 int opcode; /* (sp) or 2(sp) if rvalue is present */
34 int rvalue; /* (sp) */
35 #ifdef LISTING
36 FILE *argfp;
37 #endif
38
39 /* pass1: */
40 /*      mov     fout,fin                / tmp file is now input file */
41 /*      mov     $666,-(sp)              / mode */
42 /*      mov     $3001 ,-(sp)            / O_WRONLY|O_CREAT|O_TRUNC */
43 /*      mov     a.outp,-(sp)            / filename */
44 /*      jsr     pc,_open */
45 /*      add     $6,sp */
46 /*      mov     r0,fout                 / file descriptor any good? */
47 /*      bpl     1f                      / yes - br */
48 /*      mov     a.outp,-(sp) */
49 /*      jsr     pc,filerr */
50 /* 1: */
51
52 void pass1() {
53         int symtot;
54         struct symbol *psymbol;
55         struct symbol **ppsymbol;
56         int flags;
57
58         fin = fout;
59         fout = open(a_outp, O_WRONLY|O_CREAT|O_TRUNC, 0666);
60         if (fout < 0)
61                 filerr(a_outp);
62
63 /* 'symnum' has number of symbols.  The hashtable from pass 0 is no */
64 /* longer needed - we can reuse it directly for 'usymtab' if there are less  */
65 /* than 'hshsiz' symbols.  If there are more than 'hshsiz' (currently */
66 /* 1500) symbols we have to realloc. */
67
68 /* The 'fb' table (usually 0 long) is appended to the 'usymtab' (4 byte */
69 /* entries per symbol). */
70
71 /*      mov     fbptr,r0 */
72 /*      sub     fbtbl,r0                / # bytes in 'fb' table */
73 /*      asr     r0                      / convert to number of words */
74 /*      add     symnum,r0               / add in number of symbols twice */
75 /*      add     symnum,r0               / because we need 2 words per symbol */
76 /*      inc     r0                      / one more for terminator word */
77
78         symtot = (fbptr - fbtbl) + symnum + 1;
79
80 /*      cmp     r0,$hshsiz              / is hashtable big enough already? */
81 /*      blo     1f                      / yes -br */
82 /*      asl     r0                      / convert to bytes */
83 /*      mov     r0,-(sp) */
84 /*      mov     hshtab,-(sp) */
85 /*      jsr     pc,_realloc             / hshtab = realloc(hshtab, r0) */
86 /*      mov     r0,hshtab */
87 /*      bne     1f */
88 /*      iot                             / should never happen */
89 /* 1: */
90
91         if (symtot > hshsiz) {
92                 hshtab = (struct symbol **)realloc(hshtab, symtot * sizeof(struct symbol *));
93                 if (hshtab == NULL)
94                         nomem();
95         }
96
97 /*      mov     hshtab,r1 */
98 /*      mov     usymtab,r2 */
99 /* 9: */
100 /*      mov     r2,symblk               / save ptr to start of block */
101 /*      tst     (r2)+                   / skip link word */
102 /*      mov     $SYMBLKSZ,symleft       / init amount left in block */
103
104         ppsymbol = hshtab;
105         symblk = usymtab;
106         do {
107                 psymbol = symblk->data;
108                 symleft = SYMBLKSZ;
109
110 /* 1: */
111 /*      tst     (r2)                    / end of symbol table block */
112 /*      beq     4f                      / yes - br */
113 /*      add     $8.,symsiz              / size of symbol table */
114 /*      tst     Newsym                  / are we doing new style? */
115 /*      bne     8f                      / yes - br */
116 /*      add     $4,symsiz               / no, symbol table entries are bigger */
117 /* 8: */
118
119                 do {
120                         if (psymbol->name == NULL)
121                                 break;
122 /* printf("%s\n", psymbol->name); */
123                         siz[3] += Newsym ? 8 : 12;
124
125 /*      mov     2(r2),r0                / flags word */
126 /*      bic     $!37,r0 */
127 /*      cmp     r0,$2                   /text */
128 /*      blo     2f */
129 /*      cmp     r0,$3                   /data */
130 /*      bhi     2f */
131 /*      add     $31,r0                  /mark "estimated" */
132 /*      mov     r0,(r1)+                / store flags word */
133 /*      mov     4(r2),(r1)+             / copy value word */
134 /*      br      3f */
135 /* 2: */
136 /*      clr     (r1)+ */
137 /*      clr     (r1)+ */
138 /* 3: */
139
140                         flags = psymbol->flags & 037;
141                         if (flags == FTEXT || flags == FDATA)
142                                 psymbol->flags = flags + FESTTEXT - FTEXT;
143                         else {
144                                 psymbol->flags = 0;
145                                 psymbol->value = 0;
146                         }
147
148 /*      add     $SYMENTSZ,r2            / skip to next symbol entry */
149 /*      sub     $SYMENTSZ,symleft       / one symbol less in block */
150 /*      cmp     symleft,$SYMENTSZ       / room for another symbol? */
151 /*      bge     1b                      / yes - br */
152
153 /* printf("0x%08x 0x%08x\n", (ppsymbol - hshtab), psymbol->number); */
154                         *ppsymbol++ = psymbol++;
155                         symleft--;
156                 } while (symleft);
157
158 /* 4: */
159 /*      mov     *symblk,r2              / follow link to next block */
160 /*      bne     9b                      / if not at end */
161 /* 1: */
162
163                 symblk = symblk->next;
164         } while (symblk);
165
166 /* The 'fb' table needs to be appended to the 'usymtab' table now */
167
168 /*      mov     fbtbl,r0 */
169 /*      mov     r1,fbbufp               / save start of 'fb' table */
170 /* 1: */
171 /*      cmp     r0,fbptr                / at end of table? */
172 /*      bhis    2f                      / yes - br */
173 /*      mov     (r0)+,r4 */
174 /*      add     $31,r4                  / "estimated" */
175 /*      mov     r4,(r1)+ */
176 /*      mov     (r0)+,(r1)+ */
177 /*      br      1b */
178 /* 2: */
179
180         psymbol = fbtbl;
181         fbbufp = ppsymbol;
182         while (psymbol < fbptr) {
183                 psymbol->flags += FESTTEXT - FTEXT; /* FESTBSS ??? */
184                 *ppsymbol++ = psymbol++;
185         }
186
187 /*      mov     r1,endtable */
188 /*      mov     $100000,(r1)+ */
189
190         endtable = ppsymbol;
191         *ppsymbol++ = NULL;
192
193 /*      mov     $savdot,r0              / reset the 'psect' (text,data,bss) */
194 /*      clr     (r0)+                   / counters for the next pass */
195 /*      clr     (r0)+ */
196 /*      clr     (r0)+ */
197 /*      jsr     pc,setup                / init fb stuff */
198
199         savdot[0] = 0;
200         savdot[1] = 0;
201         savdot[2] = 0;
202         setup();
203
204 /*      jsr     pc,pass1_2              / do pass 1 */
205
206         pass1_2();
207
208 /* prepare for pass 2 */
209 /*      inc     passno */
210 /*      cmp     outmod,$777 */
211 /*      beq     1f */
212 /*      jsr     pc,aexit */
213 /* not reached */
214 /* 1: */
215
216 #ifdef LISTING
217         printf("pass 2\n");
218 #endif
219         passno++;
220         if (outmod != 0777)
221                 aexit();
222
223 /*      jsr     pc,setup */
224 /*      inc     bsssiz */
225 /*      bic     $1,bsssiz */
226 /*      mov     txtsiz,r1 */
227 /*      inc     r1 */
228 /*      bic     $1,r1 */
229 /*      mov     r1,txtsiz */
230 /*      mov     datsiz,r2 */
231 /*      inc     r2 */
232 /*      bic     $1,r2 */
233 /*      mov     r2,datsiz */
234
235         setup();
236         siz[0] = (siz[0] + 1) & ~1;
237         siz[1] = (siz[1] + 1) & ~1;
238         siz[2] = (siz[2] + 1) & ~1;
239
240 /*      mov     r1,r3 */
241 /*      mov     r3,datbase              / txtsiz */
242 /*      mov     r3,savdot+2 */
243 /*      add     r2,r3 */
244 /*      mov     r3,bssbase              / txtsiz+datsiz */
245 /*      mov     r3,savdot+4 */
246
247         base[1] = siz[0];
248         savdot[1] = base[1];
249         base[2] = base[1] + siz[1];
250         savdot[2] = base[2];
251
252 /*      clr     r0 */
253 /*      asl     r3 */
254 /*      adc     r0 */
255 /*      add     $20,r3 */
256 /*      adc     r0 */
257 /*      mov     r3,symseek+2            / 2*txtsiz+2*datsiz+20 */
258 /*      mov     r0,symseek */
259
260         seek[6] = (off_t)base[2] * 2 + 020;
261
262 /*      sub     r2,r3 */
263 /*      sbc     r0 */
264 /*      mov     r3,drelseek+2           / 2*txtsiz+datsiz */
265 /*      mov     r0,drelseek */
266
267         seek[4] = seek[6] - siz[1];
268
269 /*      sub     r1,r3 */
270 /*      sbc     r0 */
271 /*      mov     r3,trelseek+2           / txtsiz+datsiz+20 */
272 /*      mov     r0,trelseek */
273
274         seek[3] = seek[4] - siz[0];
275
276 /*      sub     r2,r3 */
277 /*      sbc     r0 */
278 /*      mov     r0,datseek */
279 /*      mov     r3,datseek+2            / txtsiz+20 */
280
281         seek[1] = seek[3] - siz[1];
282         seek[0] = 020;
283
284 /*      mov     hshtab,r1 */
285 /* 1: */
286 /*      jsr     pc,doreloc */
287 /*      add     $4,r1 */
288 /*      cmp     r1,endtable */
289 /*      blo     1b */
290
291         for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++)
292                 doreloc(*ppsymbol);
293
294 /*      clr     r0 */
295 /*      clr     r1 */
296 /*      mov     $txtp,-(sp) */
297 /*      jsr     pc,oset */
298 /*      mov     trelseek,r0 */
299 /*      mov     trelseek+2,r1 */
300 /*      mov     $relp,-(sp) */
301 /*      jsr     pc,oset */
302
303         oset(&txtp, 0L);
304         oset(&relp, seek[3]);
305
306 /*      mov     $8.,r2 */
307 /*      mov     $txtmagic,r1 */
308 /* 1: */
309 /*      mov     (r1)+,r0 */
310 /*      mov     $txtp,-(sp) */
311 /*      jsr     pc,putw */
312 /*      sob     r2,1b */
313
314         p1putw(&txtp, 0407);
315         p1putw(&txtp, siz[0]);
316         p1putw(&txtp, siz[1]);
317         p1putw(&txtp, siz[2]);
318         p1putw(&txtp, siz[3]);
319         p1putw(&txtp, 0);
320         p1putw(&txtp, 0);
321         p1putw(&txtp, 0);
322
323 /*      jsr     pc,pass1_2                      / do pass 2 */
324
325         pass1_2();
326 #ifdef LISTING
327         if (argfp)
328                 fclose(argfp);
329 #endif
330
331 /*polish off text and relocation */
332
333 /*      mov     $txtp,-(sp) */
334 /*      jsr     pc,flush */
335 /*      mov     $relp,-(sp) */
336 /*      jsr     pc,flush */
337
338         flush(&txtp);
339         flush(&relp);
340
341 /* append full symbol table */
342 /*      mov     symseek,r0 */
343 /*      mov     symseek+2,r1 */
344 /*      mov     $txtp,-(sp) */
345 /*      jsr     pc,oset */
346
347         oset(&txtp, seek[6]);
348
349 /*      mov     usymtab,r2              / pointer to first symbol block */
350 /*      mov     hshtab,r1               / 'type' and 'value' array */
351 /*      tst     Newsym */
352 /*      beq     8f */
353 /*      jsr     pc,nsymout */
354 /*      br      9f */
355 /* 8: */
356 /*      jsr     pc,osymout */
357 /* 9: */
358
359         if (Newsym)
360                 nsymout();
361         else
362                 osymout();
363
364 /*      mov     $txtp,-(sp) */
365 /*      jsr     pc,flush */
366 /*      jsr     pc,aexit */
367 /* not reached */
368
369         flush(&txtp);
370         aexit();
371 }
372
373 /* saexit: */
374 /*      mov     pc,errflg */
375
376 void saexit() {
377         errflg = 3;
378         aexit();
379 }
380
381 /* aexit: */
382 /*      mov     $a.tmp1,-(sp)           / unlink(a.tmp1) */
383 /*      jsr     pc,_unlink */
384
385 int aexit() {
386 #if 1
387         unlink(a_tmp1);
388 #endif
389
390 /*      tst     errflg */
391 /*      bne     2f */
392
393         if (errflg == 0) {
394
395 /*      clr     (sp) */
396 /*      jsr     pc,_umask */
397
398 /*      bic     r0,outmod               / fchmod(fout, outmod&umask(0)) */
399 /*      mov     outmod,(sp) */
400 /*      mov     fout,-(sp) */
401 /*      jsr     pc,_fchmod */
402 /*      tst     (sp)+ */
403 /*      clr     (sp) */
404 /*      br      1f */
405
406                 fchmod(fout, outmod & ~umask(0));
407                 exit(0);
408         }
409
410 /* 2: */
411 /*      mov     $2,(sp) */
412 /* 1: */
413 /*      jsr     pc,__exit               / _exit(errflg ? 2 : 0) */
414
415         exit(2);
416 }
417
418 /* filerr: */
419 /*      mov     2(sp),r0                / filename string.  no need to clean */
420 /*      tst     -(sp)                   / stack, this routine goes to saexit. */
421 /*      mov     r0,-(sp) */
422 /*      mov     $1,-(sp) */
423 /* 1: */
424 /*      tstb    (r0)+ */
425 /*      bne     1b */
426 /*      sub     2(sp),r0 */
427 /*      dec     r0 */
428 /*      mov     r0,4(sp) */
429 /*      jsr     pc,_write */
430 /*      add     $6,sp */
431
432 void filerr(p) char *p; {
433         write(1, p, strlen(p));
434
435 /*      mov     $2,-(sp)                / write(1, "?\n", 2) */
436 /*      mov     $qnl,-(sp) */
437 /*      mov     $1,-(sp) */
438 /*      jsr     pc,_write */
439 /*      add     $6,sp */
440 /*      tst     passno */
441 /*      bpl     saexit */
442 /*      rts     pc */
443
444         write(1, "?\n", 2);
445         if (passno >= 0)
446                 saexit();
447 }
448
449 /* osymout: */
450 /* 9: */
451 /*      mov     r2,symblk               / save ptr to current sym block */
452 /*      tst     (r2)+                   / skip link word */
453 /*      mov     $SYMBLKSZ,symleft       / space left in symbol block */
454 /* 1: */
455 /*      mov     (r2),r4                 / pointer to symbol name */
456 /*      beq     4f                      / end of block - br */
457
458 void osymout() {
459         struct symbol **ppsymbol;
460         struct symbol *psymbol;
461         char *p;
462
463         for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++) {
464                 psymbol = *ppsymbol;
465                 p = psymbol->name;
466                 if (p == NULL)
467                         break; /* reached the start of the fbtab */
468
469 /*      mov     $8.,r5                  / max number to copy */
470 /*      mov     $symbol,r0              / destination buffer */
471 /* 2: */
472 /*      movb    (r4),(r0)+              / copy a byte */
473 /*      beq     6f */
474 /*      inc     r4                      / non null - bump source ptr */
475 /* 6: */
476 /*      sob     r5,2b */
477
478                 strncpy(symbol, p, 8);
479
480 /* Now put four words of symbol name to the object file */
481 /*      mov     $4,r5                   / number of words to do */
482 /*      mov     $symbol,r4 */
483 /* 6: */
484 /*      mov     (r4)+,r0                / word (2 chars) of symbol name */
485 /*      mov     $txtp,-(sp) */
486 /*      jsr     pc,putw */
487 /*      sob     r5,6b */
488
489                 p1putw(&txtp, (symbol[0] & 0377) | ((symbol[1] & 0377) << 8));
490                 p1putw(&txtp, (symbol[2] & 0377) | ((symbol[3] & 0377) << 8));
491                 p1putw(&txtp, (symbol[4] & 0377) | ((symbol[5] & 0377) << 8));
492                 p1putw(&txtp, (symbol[6] & 0377) | ((symbol[7] & 0377) << 8));
493
494 /* values from 'hshtab' (parallel array to symbol table) are retrieved now, */
495 /* they take the place of the flags and value entries of the symbol table. */
496 /*      mov     (r1)+,r0 */
497 /*      mov     $txtp,-(sp) */
498 /*      jsr     pc,putw */
499 /*      mov     (r1)+,r0 */
500 /*      mov     $txtp,-(sp) */
501 /*      jsr     pc,putw */
502
503                 p1putw(&txtp, psymbol->flags);
504                 p1putw(&txtp, psymbol->value);
505
506 /*      add     $SYMENTSZ,r2            / skip to next symbol */
507 /*      sub     $SYMENTSZ,symleft       / one less symbol in block */
508 /*      cmp     symleft,$SYMENTSZ       / room for another? */
509 /*      bge     1b                      / yes - br */
510 /* 4: */
511 /*      mov     *symblk,r2              / no, follow link to next block */
512 /*      bne     9b                      / unless it's end of list */
513 /*      rts     pc */
514
515         }
516 }
517
518 /* nsymout: */
519 /*      clr     totalsz */
520 /*      mov     $4,totalsz+2            / string table min size is 4 */
521
522 void nsymout() {
523         struct symbol **ppsymbol;
524         struct symbol *psymbol;
525         char *p;
526
527         totalsz = 4;
528
529 /* 9: */
530 /*      mov     r2,symblk               / save ptr to current symbol block */
531 /*      tst     (r2)+                   / skip link word */
532 /*      mov     $SYMBLKSZ,symleft       / amount of space left in block */
533 /* 1: */
534 /*      mov     (r2),r4                 / pointer to symbol's string */
535 /*      beq     4f                      / end of block - br */
536
537         for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++) {
538                 psymbol = *ppsymbol;
539                 p = psymbol->name;
540                 if (p == NULL)
541                         break; /* reached the start of the fbtab */
542
543 /*      mov     totalsz,r0              / now output the... */
544 /*      mov     $txtp,-(sp)             / high order of the string index... */
545 /*      jsr     pc,putw                 / to the object file */
546 /*      mov     totalsz+2,r0 */
547 /*      mov     $txtp,-(sp) */
548 /*      jsr     pc,putw                 / and the low order word */
549 /* 2: */
550 /*      tstb    (r4)+                   / find the end of the string */
551 /*      bne     2b */
552 /*      sub     (r2),r4                 / compute length including the null */
553 /*      add     r4,totalsz+2            / offset of next string */
554 /*      adc     totalsz */
555
556                 p1putw(&txtp, (int)(totalsz >> 16) & 0177777);
557                 p1putw(&txtp, (int)totalsz & 0177777);
558                 totalsz += strlen(p) + 1;
559
560 /*      mov     (r1)+,r0                / 'type' word of symbol */
561 /*      mov     $txtp,-(sp) */
562 /*      jsr     pc,putw */
563 /*      mov     (r1)+,r0                / 'value' word of symbol */
564 /*      mov     $txtp,-(sp) */
565 /*      jsr     pc,putw */
566
567                 p1putw(&txtp, psymbol->flags);
568                 p1putw(&txtp, psymbol->value);
569
570 /*      add     $SYMENTSZ,r2            / advance to next symbol */
571 /*      sub     $SYMENTSZ,symleft       / adjust amount left in symbol block */
572 /*      cmp     symleft,$SYMENTSZ       / is there enough for another symbol? */
573 /*      bge     1b                      / yes - br */
574 /* 4: */
575 /*      mov     *symblk,r2              / follow link to next symbol block */
576 /*      bne     9b                      / more - br */
577
578         }
579
580 /*      mov     totalsz,r0              / now output the string table length */
581 /*      mov     $txtp,-(sp)             / high order word first */
582 /*      jsr     pc,putw */
583 /*      mov     totalsz+2,r0            / followed by the low order */
584 /*      mov     $txtp,-(sp) */
585 /*      jsr     pc,putw */
586
587         p1putw(&txtp, (int)(totalsz >> 16) & 0177777);
588         p1putw(&txtp, (int)totalsz & 0177777);
589
590 /* Now write the strings out */
591
592 /*      mov     usymtab,r2              / start at beginning of symbols */
593 /* 9: */
594 /*      mov     r2,symblk               / save pointer to current block */
595 /*      tst     (r2)+                   / skip link word */
596 /*      mov     $SYMBLKSZ,symleft       / amount left in block */
597 /* 1: */
598 /*      mov     (r2),r4                 / pointer to symbol's string */
599 /*      beq     4f                      / at end of block - br */
600
601         for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++) {
602                 psymbol = *ppsymbol;
603                 p = psymbol->name;
604                 if (p == NULL)
605                         break; /* reached the start of the fbtab */
606
607 /*      jsr     pc,putstring            / write out the string */
608
609                 putstring(p);
610
611 /*      add     $SYMENTSZ,r2            / advance to next symbol */
612 /*      sub     $SYMENTSZ,symleft       / adjust amount left in block */
613 /*      cmp     symleft,$SYMENTSZ       / enough for another symbol? */
614 /*      bge     1b                      / yes - br */
615 /* 4: */
616 /*      mov     *symblk,r2              / move to next block of symbols */
617 /*      bne     9b                      / any left - br */
618
619         }
620
621 /* probably not necessary but let us leave the file size on an even */
622 /* byte boundary. */
623
624 /*      bit     $1,totalsz+2            / odd number of bytes in string table? */
625 /*      beq     5f                      / no - br */
626 /*      mov     symblk,r4               / we know 'symblk' points to a null */
627 /*      jsr     pc,putstring            / output a single null */
628 /* 5: */
629 /*      rts     pc */
630
631         if (totalsz & 1) {
632                 putstring("");
633         }
634 }
635
636 /* R4 has the address of a null terminated string to write to the output */
637 /* file.  The terminating null is included in the output.  This routine */
638 /* "inlines" the 'txtp seek structure' manipulation because the 'putw' */
639 /* routine was 1) not suitable to byte output and 2) symbol strings are */
640 /* only written using the 'txtp' (as opposed to 'relp' - relocation info) */
641 /* structure. */
642
643 /* putstring: */
644
645 void putstring(p) char *p; {
646         while (1) {
647
648 /*      cmp     txtp,txtp+2             / room for another byte? */
649 /*      bhis    1f                      / no - br */
650 /* 3: */
651 /*      movb    (r4),*txtp              / put byte in buffer */
652 /*      inc     txtp                    / advance output position */
653 /*      tstb    (r4)+                   / did we just do the null? */
654 /*      bne     putstring               / no - go again */
655 /*      rts     pc                      / yes - we're done, return */
656
657                 while (txtp.append < txtp.limit) {
658                         *txtp.append++ = *p;
659                         if (*p++ == 0)
660                                 return;
661                 }
662
663 /* 1: */
664 /*      mov     r2,-(sp)                / save r2 from being destroyed */
665 /*      mov     $txtp,-(sp)             / flush buffered output and... */
666 /*      jsr     pc,flush                / reset the pointers */
667 /*      mov     (sp)+,r2                / restore symbol pointer */
668 /*      br      3b                      / go output a byte */
669
670                 flush(&txtp);
671         }
672 }
673
674 /* doreloc: */
675 /*      movb    (r1),r0 */
676 /*      bne     1f */
677 /*      bisb    defund,(r1) */
678 /* 1: */
679
680 void doreloc(psymbol) struct symbol *psymbol; {
681         int flags;
682
683         flags = psymbol->flags;
684         if (flags == 0)
685                 psymbol->flags = defund;
686
687 /*      bic     $!37,r0 */
688 /*      cmp     r0,$5 */
689 /*      bhis    1f */
690 /*      cmp     r0,$3 */
691 /*      blo     1f */
692 /*      beq     2f */
693
694         flags &= 037;
695         switch (flags) {
696
697 /*      add     bssbase,2(r1) */
698 /*      rts     pc */
699
700         case FBSS:
701                 psymbol->value += base[2];
702                 break;
703
704 /* 2: */
705 /*      add     datbase,2(r1) */
706 /* 1: */
707 /*      rts     pc */
708
709         case FDATA:
710                 psymbol->value += base[1];
711                 break;
712         }
713 }
714
715 /* setup: */
716 /*      clr     dot */
717 /*      mov     $2,dotrel */
718 /*      mov     $..,dotdot */
719 /*      clr     brtabp */
720
721 void setup() {
722         int label;
723
724         pdot->value = 0;
725         pdot->flags = FTEXT;
726         pdotdot->value = 0;
727         brtabp = 0;
728
729 /*      mov     $curfb,r4 */
730 /* 1: */
731 /*      clr     (r4)+ */
732 /*      cmp     r4,$curfb+40. */
733 /*      blo     1b */
734
735         memset(curfb, 0, 10 * sizeof(intptr_t));
736         memset(nxtfb, 0, 10 * sizeof(intptr_t));
737
738 /*      clr     r4 */
739 /* 1: */
740 /*      jsr     pc,fbadv */
741 /*      inc     r4 */
742 /*      cmp     r4,$10. */
743 /*      blt     1b */
744
745         for (label = 0; label < 10; label++)
746                 fbadv(label);
747
748 /* just rewind /tmp/atm1xx rather than close and re-open */
749 /*      clr     -(sp) */
750 /*      clr     -(sp) */
751 /*      clr     -(sp) */
752 /*      mov     fin,-(sp) */
753 /*      jsr     pc,_lseek               / lseek(fin, 0L, 0) */
754 /*      add     $8.,sp */
755
756         lseek(fin, 0L, SEEK_SET);
757
758 /*      clr     ibufc */
759 /*      rts     pc */
760
761         ibufc = 0;
762 }
763
764 /* outw: */
765 /*      cmp     dot-2,$4 */
766 /*      beq     9f */
767
768 void outw(value, flags) int value; int flags; {
769         int relocate;
770
771 #ifdef LISTING
772         if (passno)
773                 printf("%04x: %04x (%04x)\n", pdot->value, value & 0177777,
774                                 flags);
775 #endif
776         if (pdot->flags != FBSS) {
777
778 /*      bit     $1,dot */
779 /*      bne     1f */
780
781                 if ((pdot->value & 1) == 0) {
782
783 /*      add     $2,dot */
784 /*      tst     passno */
785 /*      beq     8f */
786
787                         pdot->value += 2;
788                         if (passno == 0)
789                                 return;
790
791 /*      clr     -(sp) */
792 /*      rol     r3 */
793 /*      adc     (sp) */
794 /*      asr     r3                      / get relative pc bit */
795 /*      cmp     r3,$40 */
796 /*      bne     2f */
797
798                         relocate = (flags >> 15) & 1;
799                         flags &= 077777;
800                         if (flags == FGLOBAL) {
801
802 /* external references */
803 /*      mov     $666,outmod             / make nonexecutable */
804 /*      mov     xsymbol,r3 */
805 /*      sub     hshtab,r3 */
806 /*      asl     r3 */
807 /*      bis     $4,r3                   / external relocation */
808 /*      br      3f */
809 /* 2: */
810
811                                 outmod = 0666;
812                                 flags = (xsymbol->number << 3) | 4;
813                         }
814
815 /*      bic     $40,r3                  / clear any ext bits */
816 /*      cmp     r3,$5 */
817 /*      blo     4f */
818 /*      cmp     r3,$33                  / est. text, data */
819 /*      beq     6f */
820 /*      cmp     r3,$34 */
821 /*      bne     7f */
822 /* 6: */
823 /*      mov     $'r,-(sp) */
824 /*      jsr     pc,error */
825 /* 7: */
826 /*      mov     $1,r3                   / make absolute */
827 /* 4: */
828
829                         else {
830                                 flags &= ~FGLOBAL;
831                                 if (flags > FBSS) {
832                                         if (flags == FESTTEXT ||
833                                                         flags == FESTDATA)
834                                                 error('r');
835                                         flags = FABS;
836                                 }
837
838 /*      cmp     r3,$2 */
839 /*      blo     5f */
840 /*      cmp     r3,$4 */
841 /*      bhi     5f */
842 /*      tst     (sp) */
843 /*      bne     4f */
844 /*      add     dotdot,r2 */
845 /*      br      4f */
846 /* 5: */
847
848                                 if (flags >= FTEXT && flags <= FBSS) {
849                                         if (!relocate)
850                                                 value += pdotdot->value;
851                                 }
852
853 /*      tst     (sp) */
854 /*      beq     4f */
855 /*      sub     dotdot,r2 */
856 /* 4: */
857
858                                 else {
859                                         if (relocate)
860                                                 value -= pdotdot->value;
861                                 }
862
863 /*      dec     r3 */
864 /*      bpl     3f */
865 /*      clr     r3 */
866
867                                 if (flags)
868                                         flags--;
869                         }
870
871 /* 3: */
872 /*      asl     r3 */
873 /*      bis     (sp)+,r3 */
874
875                         flags = (flags << 1) | relocate;
876
877 /*      mov     r2,r0 */
878 /*      mov     $txtp,-(sp) */
879 /*      jsr     pc,putw */
880 /*      mov     tseekp,r0 */
881 /*      add     $2,2(r0) */
882 /*      adc     (r0) */
883
884                         p1putw(&txtp, value);
885                         *tseekp += 2;
886
887 /*      mov     r3,r0 */
888 /*      mov     $relp,-(sp) */
889 /*      jsr     pc,putw */
890 /*      mov     rseekp,r0 */
891 /*      add     $2,2(r0) */
892 /*      adc     (r0) */
893
894                         p1putw(&relp, flags);
895                         *rseekp += 2;
896
897 /* 8: */
898 /*      rts     pc */
899
900                 }
901
902 /* 1: */
903 /*      mov     $'o,-(sp) */
904 /*      jsr     pc,error */
905 /*      clr     r3 */
906 /*      jsr     pc,outb */
907 /*      rts     pc */
908
909                 else {
910                         error('o');
911                         outb(value, 0);
912                 }
913
914 /* 9: */
915 /*      mov     $'x,-(sp) */
916 /*      jsr     pc,error */
917 /*      rts     pc */
918
919         }
920         else
921                 error('x');
922 }
923
924 /* outb: */
925 /*      cmp     dot-2,$4                / test bss mode */
926 /*      beq     9b */
927
928 void outb(value, flags) int value; int flags; {
929 #ifdef LISTING
930         if (passno)
931                 printf("%04x:   %02x (%04x)\n", pdot->value, value & 0377,
932                                 flags);
933 #endif
934         if (pdot->flags == FBSS) {
935                 error('x');
936                 return;
937  /* bug!! didn't increment dot's value */
938         }
939
940 /*      cmp     r3,$1 */
941 /*      blos    1f */
942 /*      mov     $'r,-(sp) */
943 /*      jsr     pc,error */
944 /* 1: */
945
946         if (flags > FABS)
947                 error('r');
948
949 /*      tst     passno */
950 /*      beq     2f */
951
952         if (passno) {
953
954 /*      mov     r2,r0 */
955 /*      bit     $1,dot */
956 /*      bne     1f */
957
958                 if ((pdot->value & 1) == 0) {
959
960 /*      mov     $txtp,-(sp) */
961 /*      jsr     pc,putw */
962 /*      clr     r0 */
963 /*      mov     $relp,-(sp) */
964 /*      jsr     pc,putw */
965
966                         p1putw(&txtp, value);
967                         p1putw(&relp, 0);
968
969 /*      mov     tseekp,r0 */
970 /*      add     $2,2(r0) */
971 /*      adc     (r0) */
972 /*      mov     rseekp,r0 */
973 /*      add     $2,2(r0) */
974 /*      adc     (r0) */
975 /*      br      2f */
976
977                         *tseekp += 2;
978                         *rseekp += 2;
979                 }
980
981 /* 1: */
982 /*      mov     txtp,r0 */
983 /*      movb    r2,-1(r0) */
984
985                 else
986                         *(txtp.append - 1) = (char)value;
987         }
988
989 /* 2: */
990 /*      inc     dot */
991 /*      rts     pc */
992
993         pdot->value++;
994 }
995
996 /* pass 1 and 2 common code */
997
998 /* pass1_2: */
999 /*      jsr     pc,readop */
1000 /*      cmp     r4,$5 */
1001 /*      beq     2f */
1002 /*      cmp     r4,$'< */
1003 /*      beq     2f */
1004 /*      jsr     pc,checkeos */
1005 /*              br eal1 */
1006
1007 void pass1_2() {
1008         intptr_t tokensave;
1009         int flags;
1010         struct symbol *psymbol;
1011         int label;
1012 #ifdef LISTING
1013         int argch;
1014 #endif
1015
1016         while (1) {
1017                 readop();
1018                 if (token != TNEWFILE && token != TSTRING) {
1019                         if (checkeos())
1020                                 goto eal1;
1021
1022 /*      mov     r4,-(sp) */
1023 /*      cmp     (sp),$1 */
1024 /*      bne     1f */
1025 /*      mov     $2,(sp) */
1026 /*      jsr     pc,getw */
1027 /*      mov     r4,numval */
1028 /* 1: */
1029
1030                         tokensave = token;
1031                         if (token == TABS) {
1032                                 tokensave = TABS2;
1033                                 p1getw();
1034                                 numval = token;
1035                         }
1036
1037 /*      jsr     pc,readop */
1038 /*      cmp     r4,$'= */
1039 /*      beq     4f */
1040 /*      cmp     r4,$': */
1041 /*      beq     1f */
1042 /*      mov     r4,savop */
1043 /*      mov     (sp)+,r4 */
1044 /* 2: */
1045 /*      jsr     pc,opline */
1046
1047                         readop();
1048                         if (token == TEQUAL)
1049                                 goto equal;
1050                         if (token == TCOLON)
1051                                 goto colon;
1052                         savop = token;
1053                         token = tokensave;
1054                 }
1055                 opline();
1056
1057 /* dotmax: */
1058 /*      tst     passno */
1059 /*      bne     eal1 */
1060 /*      movb    dotrel,r0 */
1061 /*      asl     r0 */
1062 /*      cmp     dot,txtsiz-4(r0) */
1063 /*      bhi     8f */
1064 /*      jmp     ealoop */
1065 /* 8: */
1066 /*      mov     dot,txtsiz-4(r0) */
1067 /* eal1: */
1068 /*      jmp     ealoop */
1069
1070         dotmax:
1071                 if (passno == 0) {
1072                         flags = pdot->flags - FTEXT;
1073                         if (siz[flags] < pdot->value)
1074                                 siz[flags] = pdot->value;
1075                 }
1076         eal1:
1077                 goto ealoop;
1078
1079 /* 1: */
1080 /*      mov     (sp)+,r4 */
1081 /*      cmp     r4,$200 */
1082 /*      bhis    1f */
1083 /*      cmp     r4,$2 */
1084 /*      beq     3f */
1085 /*      mov     $'x,-(sp) */
1086 /*      jsr     pc,error */
1087 /*      br      pass1_2 */
1088 /* 1: */
1089
1090         colon:
1091                 if (tokensave >= 0 && tokensave < TASCII) {
1092                         if (tokensave != TABS2) {
1093                                 error('x');
1094                                 continue;
1095                         }
1096                         goto digit;
1097                 }
1098
1099 /*      tst     passno */
1100 /*      bne     2f */
1101 /*      movb    (r4),r0 */
1102 /*      bic     $!37,r0 */
1103 /*      beq     5f */
1104 /*      cmp     r0,$33 */
1105 /*      blt     6f */
1106 /*      cmp     r0,$34 */
1107 /*      ble     5f */
1108 /* 6: */
1109 /*      mov     $'m,-(sp) */
1110 /*      jsr     pc,error */
1111 /* 5: */
1112
1113                 psymbol = (struct symbol *)tokensave;
1114                 if (passno == 0) {
1115                         flags = psymbol->flags & 037;
1116                         if (flags && (flags < FESTTEXT || flags > FESTDATA))
1117                                 error('m');
1118
1119 /*      bic     $37,(r4) */
1120 /*      bis     dotrel,(r4) */
1121 /*      mov     2(r4),brdelt */
1122 /*      sub     dot,brdelt */
1123 /*      mov     dot,2(r4) */
1124 /*      br      pass1_2 */
1125
1126                         psymbol->flags = (psymbol->flags & ~037) | pdot->flags;
1127                         brdelt = psymbol->value - pdot->value;
1128                         psymbol->value = pdot->value;
1129                         continue;
1130                 }
1131
1132 /* 2: */
1133 /*      cmp     dot,2(r4) */
1134 /*      beq     pass1_2 */
1135 /*      mov     $'p,-(sp) */
1136 /*      jsr     pc,error */
1137 /*      br      pass1_2 */
1138
1139                 if (psymbol->value != pdot->value)
1140                         error('p');
1141 #ifdef LISTING
1142                 printf("%04x: %s\n", psymbol->value & 0177777, psymbol->name);
1143 #endif
1144                 continue;
1145
1146 /* 3: */
1147 /*      mov     numval,r4 */
1148 /*      jsr     pc,fbadv */
1149 /*      asl     r4 */
1150 /*      mov     curfb(r4),r0 */
1151 /*      movb    dotrel,(r0) */
1152 /*      mov     2(r0),brdelt */
1153 /*      sub     dot,brdelt */
1154 /*      mov     dot,2(r0) */
1155 /*      br      pass1_2 */
1156
1157         digit:
1158                 label = numval;
1159                 fbadv(label);
1160                 psymbol = *(struct symbol **)curfb[label];
1161                 psymbol->flags = pdot->flags;
1162                 brdelt = psymbol->value - pdot->value;
1163                 psymbol->value = pdot->value;
1164 #ifdef LISTING
1165                 if (passno)
1166                         printf("%04x: %d\n", psymbol->value & 0177777, label);
1167 #endif
1168                 continue;
1169
1170 /* 4: */
1171 /*      jsr     pc,readop */
1172 /*      jsr     pc,expres */
1173 /*      mov     (sp)+,r1 */
1174 /*      cmp     r1,$dotrel              /test for dot */
1175 /*      bne     1f */
1176 /*      bic     $40,r3 */
1177 /*      cmp     r3,dotrel               / can't change relocation */
1178 /*      bne     2f */
1179
1180         equal:
1181                 readop();
1182                 expres();
1183                 psymbol = (struct symbol *)tokensave;
1184                 if (psymbol == pdot) {
1185                         leftflags &= ~FGLOBAL;
1186 /* printf("leftflags 0%o pdot->flags 0%o\n", leftflags, pdot->flags); */
1187                         if (leftflags != pdot->flags)
1188                                 goto doterr;
1189
1190 /*      cmp     r3,$4                   / bss */
1191 /*      bne     3f */
1192 /*      mov     r2,dot */
1193 /*      br      dotmax */
1194 /* 3: */
1195
1196                         if (leftflags == FBSS) {
1197                                 pdot->value = leftvalue;
1198 #ifdef LISTING
1199                         if (passno)
1200                                 printf("%04x: .\n", pdot->value & 0177777);
1201 #endif
1202                                 goto dotmax;
1203                         }
1204
1205 /*      sub     dot,r2 */
1206 /*      bmi     2f */
1207 /*      mov     r2,-(sp) */
1208 /* 3: */
1209 /*      dec     (sp) */
1210 /*      bmi     3f */
1211 /*      clr     r2 */
1212 /*      mov     $1,r3 */
1213 /*      jsr     pc,outb */
1214 /*      br      3b */
1215 /* 3: */
1216 /*      tst     (sp)+ */
1217 /*      br      dotmax */
1218
1219                         leftvalue -= pdot->value;
1220                         if (leftvalue < 0)
1221                                 goto doterr;
1222                         while (leftvalue) {
1223                                 leftvalue--;
1224                                 outb(0, FABS);
1225                         }
1226                         goto dotmax;
1227
1228 /* 2: */
1229 /*      mov     $'.,-(sp) */
1230 /*      jsr     pc,error */
1231 /*      br      ealoop */
1232 /* 1: */
1233
1234                 doterr:
1235                         error('.');
1236                         goto ealoop;
1237                 }
1238
1239 /*      cmp     r3,$40 */
1240 /*      bne     1f */
1241 /*      mov     $'r,-(sp) */
1242 /*      jsr     pc,error */
1243 /* 1: */
1244
1245                 if (leftflags == FGLOBAL)
1246                         error('r');
1247
1248 /*      bic     $37,(r1) */
1249 /*      bic     $!37,r3 */
1250 /*      bne     1f */
1251 /*      clr     r2 */
1252 /* 1: */
1253
1254                 psymbol->flags &= ~037;
1255                 leftflags &= 037;
1256                 if (leftflags == 0)
1257                         leftvalue = 0;
1258
1259 /*      bisb    r3,(r1) */
1260 /*      mov     r2,2(r1) */
1261
1262                 psymbol->flags |= leftflags;
1263                 psymbol->value = leftvalue;
1264 #ifdef LISTING
1265                 if (passno)
1266                         printf("%04x: %s\n", psymbol->value & 0177777,
1267                                         psymbol->name);
1268 #endif
1269
1270 /* ealoop: */
1271 /*      cmp     r4,$'\n */
1272 /*      beq     1f */
1273 /*      cmp     r4,$'\e */
1274 /*      bne     9f */
1275 /*      rts     pc */
1276 /* 1: */
1277 /*      inc     line */
1278 /* 9: */
1279 /*      jmp     pass1_2 */
1280
1281         ealoop:
1282 /* printf("ealoop token = 0x%08x\n", token); */
1283                 if (token == TNEWLINE) {
1284                         line++;
1285 #ifdef LISTING
1286                         if (argfp)
1287                                 while ((argch = getc(argfp)) != EOF) {
1288                                         putchar(argch);
1289                                         if (argch == '\n')
1290                                                 break;
1291                                 }
1292 #endif
1293                 }
1294                 else if (token == TENDFILE)
1295                         break;
1296         }
1297 }
1298
1299 /* checkeos: */
1300 /*      cmp     r4,$'\n */
1301 /*      beq     1f */
1302 /*      cmp     r4,$'; */
1303 /*      beq     1f */
1304 /*      cmp     r4,$'\e */
1305 /*      beq     1f */
1306 /*      add     $2,(sp) */
1307 /* 1: */
1308 /*      rts     pc */
1309
1310 int checkeos() {
1311         return token == TNEWLINE || token == TSEMICOLON || token == TENDFILE;
1312 }
1313
1314 /* fbadv: */
1315 /*      asl     r4 */
1316 /*      mov     nxtfb(r4),r1 */
1317 /*      mov     r1,curfb(r4) */
1318 /*      bne     1f */
1319 /*      mov     fbbufp,r1 */
1320 /*      br      2f */
1321 /* 1: */
1322 /*      add     $4,r1 */
1323
1324 void fbadv(label) int label; {
1325         struct symbol **ppsymbol;
1326         struct symbol *psymbol;
1327
1328         ppsymbol = (struct symbol **)nxtfb[label];
1329         curfb[label] = (intptr_t)ppsymbol;
1330         if (ppsymbol == NULL) {
1331                 ppsymbol = fbbufp;
1332                 goto entry;
1333         }
1334         do {
1335                 ppsymbol++;
1336
1337 /* 2: */
1338 /*      cmpb    1(r1),r4 */
1339 /*      beq     1f */
1340 /*      tst     (r1) */
1341 /*      bpl     1b */
1342 /* 1: */
1343
1344         entry:
1345                 psymbol = *ppsymbol;
1346         } while (psymbol && psymbol->number != label);
1347
1348 /*      mov     r1,nxtfb(r4) */
1349 /*      asr     r4 */
1350 /*      rts     pc */
1351
1352         nxtfb[label] = (intptr_t)ppsymbol;
1353 }
1354
1355 /* oset: */
1356 /*      mov     r2,-(sp) */
1357 /*      mov     r3,-(sp) */
1358 /*      mov     6(sp),r3 */
1359 /*      mov     r1,r2 */
1360 /*      bic     $!1777,r1 */
1361 /*      add     r3,r1 */
1362 /*      add     $8,r1 */
1363 /*      mov     r1,(r3)+                / next slot */
1364
1365 void oset(pstream, offset) struct stream *pstream; off_t offset; {
1366         pstream->append = pstream->data + ((int)offset & 01777);
1367
1368 /*      mov     r3,r1 */
1369 /*      add     $2006,r1 */
1370 /*      mov     r1,(r3)+                / buf max */
1371
1372         pstream->limit = pstream->data + 02000;
1373
1374 /*      mov     r0,(r3)+ */
1375 /*      mov     r2,(r3)+                / seek addr */
1376
1377         pstream->offset = offset;
1378
1379 /*      mov     (sp)+,r3 */
1380 /*      mov     (sp)+,r2 */
1381 /*      mov     (sp)+,(sp) */
1382 /*      rts     pc */
1383
1384 }
1385
1386 /* putw: */
1387 /*      mov     r1,-(sp) */
1388 /*      mov     r2,-(sp) */
1389 /*      mov     6(sp),r2 */
1390 /*      mov     (r2)+,r1                / slot */
1391 /*      cmp     r1,(r2)                 / buf max */
1392 /*      bhis    1f */
1393 /*      mov     r0,(r1)+ */
1394 /*      mov     r1,-(r2) */
1395 /*      br      2f */
1396 /* 1: */
1397 /*      tst     (r2)+ */
1398 /*      mov     r0,-(sp) */
1399 /*      jsr     pc,flush1 */
1400 /*      mov     (sp)+,r0 */
1401 /*      mov     r0,*(r2)+ */
1402 /*      add     $2,-(r2) */
1403 /* 2: */
1404 /*      mov     (sp)+,r2 */
1405 /*      mov     (sp)+,r1 */
1406 /*      mov     (sp)+,(sp) */
1407 /* ret: */
1408 /*      rts     pc */
1409
1410 void p1putw(pstream, word) struct stream *pstream; int word; {
1411 /* printf("p1putw 0x%08x %04x\n", pstream, word); */
1412         if (pstream->append >= pstream->limit)
1413  /* note!! should be pstream->limit - 1, but it never makes any difference */
1414                 flush(pstream);
1415         *pstream->append++ = (char)word;
1416         *pstream->append++ = (char)(word >> 8);
1417 }
1418
1419 /* flush: */
1420 /*      mov     2(sp),r2 */
1421 /*      mov     (sp)+,(sp) */
1422 /*      cmp     (r2)+,(r2)+ */
1423 /* flush1: */
1424 /*      clr     -(sp)                   / lseek(fout, (r2)L+, L_SET) */
1425 /*      mov     2(r2),-(sp) */
1426 /*      mov     (r2)+,-(sp) */
1427 /*      tst     (r2)+ */
1428 /*      mov     fout,-(sp) */
1429 /*      jsr     pc,_lseek */
1430 /*      add     $8.,sp */
1431
1432 void flush(pstream) struct stream *pstream; {
1433         char *start;
1434         int count;
1435
1436         lseek(fout, pstream->offset, SEEK_SET);
1437
1438 /*      cmp     -(sp),-(sp)             / write(fout, <buf>, <len>) */
1439 /*      bic     $!1777,r1 */
1440 /*      add     r2,r1                   / write address */
1441
1442         start = pstream->data + ((int)pstream->offset & 01777);
1443
1444 /*      mov     r1,-(sp)                / { <buf> } */
1445 /*      mov     r2,r0 */
1446 /*      bis     $1777,-(r2) */
1447 /*      add     $1,(r2)                 / new seek addr */
1448 /*      adc     -(r2) */
1449 /*      cmp     -(r2),-(r2) */
1450
1451         pstream->offset = (pstream->offset | 01777) + 1;
1452
1453 /*      sub     (r2),r1 */
1454 /*      neg     r1 */
1455 /*      mov     r1,2(sp)                / count */
1456 /*      mov     r0,(r2)                 / new next slot */
1457
1458         count = pstream->append - start;
1459         pstream->append = pstream->data;
1460
1461 /*      mov     fout,-(sp) */
1462 /*      mov     r1,6(sp)                / protect r1 from library */
1463 /*      jsr     pc,_write */
1464 /*      add     $6,sp */
1465 /*      mov     (sp)+,r1 */
1466 /*      tst     r0 */
1467 /*      bpl     ret */
1468 /* fall thru to wrterr */
1469
1470         if (write(fout, start, count) < 0)
1471                 wrterr();
1472 }
1473
1474 /* wrterr: */
1475 /*      mov     $8f-9f,-(sp)            / write(1, 9f, 8f-9f) */
1476 /*      mov     $9f,-(sp) */
1477 /*      mov     $1,-(sp) */
1478 /*      jsr     pc,_write */
1479 /*      add     $6,sp */
1480 /*      jsr     pc,saexit */
1481 /* not reached */
1482
1483 void wrterr() {
1484         write(1, "as: write error\n", 16);
1485         saexit();
1486 }
1487
1488 /*      .data */
1489 /* 9: */
1490 /*      <as: write error\n> */
1491 /* 8: */
1492 /*      .even */
1493 /*      .text */
1494
1495 /* readop: */
1496 /*      mov     savop,r4 */
1497 /*      beq     1f */
1498 /*      clr     savop */
1499 /*      rts     pc */
1500 /* 1: */
1501
1502 void readop() {
1503         int word;
1504
1505 /* printf("readop() savop = 0x%08x\n", savop); */
1506         if (savop) {
1507                 token = savop;
1508                 savop = 0;
1509                 return;
1510         }
1511
1512 /*      jsr     pc,getw1 */
1513 /*      cmp     r4,$200 */
1514 /*      blo     1f */
1515 /*      cmp     r4,$4000 */
1516 /*      blo     2f */
1517 /*      sub     $4000,r4 */
1518 /*      asl     r4 */
1519 /*      asl     r4 */
1520 /*      add     hshtab,r4 */
1521 /*      rts     pc */
1522 /* 2: */
1523
1524         word = getw1();
1525         if (word >= 0 && word < TASCII)
1526                 token = word;
1527         else {
1528                 if (word >= 04000)
1529                         token = (intptr_t)hshtab[word - 04000];
1530
1531 /* remove PST flag (1000) then multiply by PSTENTSZ.  In pass 0 the PST */
1532 /* symbol number was divided by PSTENTSZ(to make it fit) - we now reverse */
1533 /* that process. */
1534 /*      mov     r5,-(sp) */
1535 /*      mov     r4,r5 */
1536 /*      sub     $1000,r5 */
1537 /*      mul     $PSTENTSZ,r5 */
1538 /*      mov     r5,r4 */
1539 /*      mov     (sp)+,r5 */
1540 /*      add     $dotrel,r4              / point at dot's flag field */
1541 /* 1: */
1542 /*      rts     pc */
1543
1544                 else
1545                         token = (intptr_t)(symtab + (word - 01000));
1546         }
1547 }
1548
1549 /* getw: */
1550 /*      mov     savop,r4 */
1551 /*      beq     getw1 */
1552 /*      clr     savop */
1553 /*      rts     pc */
1554
1555 void p1getw() {
1556         if (savop) {
1557                 token = savop;
1558                 savop = 0;
1559                 return;
1560         }
1561         token = getw1();
1562 }
1563
1564 /* getw1: */
1565 /*      dec     ibufc */
1566 /*      bgt     1f */
1567
1568 int getw1() {
1569         ibufc--;
1570         if (ibufc <= 0) {
1571
1572 /*      mov     r1,-(sp)                / protect r1 from library */
1573 /*      mov     $1024.,-(sp)            / read(fin, inbuf, 1024) */
1574 /*      mov     $inbuf,-(sp) */
1575 /*      mov     fin,-(sp) */
1576 /*      jsr     pc,_read */
1577 /*      add     $6,sp */
1578 /*      mov     (sp)+,r1 */
1579
1580                 ibufc = read(fin, inbuf, 1024);
1581                 if (ibufc <= 0)
1582                         return TENDFILE;
1583
1584 /*      asr     r0 */
1585 /*      mov     r0,ibufc */
1586 /*      bgt     2f */
1587 /*      mov     $4,r4 */
1588 /*      sev */
1589 /*      rts     pc */
1590 /* 2: */
1591 /*      mov     $inbuf,ibufp */
1592 /* 1: */
1593
1594                 ibufc /= sizeof(short);
1595                 ibufp = (short *)inbuf;
1596  /* note!! rather silly, ibufc doesn't get decremented through this path */
1597         }
1598
1599 /*      mov     *ibufp,r4 */
1600 /*      add     $2,ibufp */
1601 /*      rts     pc */
1602
1603         return *ibufp++;
1604 }
1605
1606 /* opline: */
1607 /*      mov     r4,r0 */
1608 /*      bmi     2f */
1609 /*      cmp     r0,$177 */
1610 /*      bgt     2f */
1611 /*      cmp     r4,$5 */
1612 /*      beq     opeof */
1613 /*      cmp     r4,$'< */
1614 /*      bne     xpr */
1615 /*      jmp     opl17 */
1616 /* xxpr: */
1617 /*      tst     (sp)+ */
1618 /* xpr: */
1619 /*      jsr     pc,expres */
1620 /*      jsr     pc,outw */
1621 /*      rts     pc */
1622 /* 2: */
1623
1624 void xpr() {
1625         expres();
1626         outw(leftvalue, leftflags);
1627 }
1628
1629 void opline() {
1630         struct symbol *psymbol;
1631         int flags;
1632
1633 /* printf("opline() token 0x%08x\n", token); */
1634         if (token >= 0 && token < TASCII) {
1635                 if (token == TNEWFILE)
1636                         opeof();
1637                 else if (token == TSTRING)
1638                         opl17();
1639                 else
1640                         xpr();
1641                 return;
1642         }
1643
1644 /*      movb    (r4),r0 */
1645 /*      cmp     r0,$24                  /reg */
1646 /*      beq     xpr */
1647 /*      cmp     r0,$33                  /est text */
1648 /*      beq     xpr */
1649 /*      cmp     r0,$34                  / est data */
1650 /*      beq     xpr */
1651 /*      cmp     r0,$5 */
1652 /*      blt     xpr */
1653 /*      cmp     r0,$36 */
1654 /*      bgt     xpr */
1655
1656         psymbol = (struct symbol *)token;
1657         flags = psymbol->flags;
1658         if (flags <= FBSS || flags == FREGISTER || flags == FESTTEXT ||
1659                         flags == FESTDATA || flags > FJCOND) {
1660                 xpr();
1661                 return;
1662         }
1663
1664 /*      mov     2(r4),-(sp) */
1665 /*      mov     r0,-(sp) */
1666 /*      jsr     pc,readop */
1667 /*      mov     (sp)+,r0 */
1668 /*      asl     r0 */
1669 /*      mov     $adrbuf,r5 */
1670 /*      clr     swapf */
1671 /*      mov     $-1,rlimit */
1672 /*      jmp     *1f-10.(r0) */
1673
1674         opcode = psymbol->value;
1675         readop();
1676         adrptr = adrbuf;
1677         swapf = 0;
1678         rlimit = 0177777;
1679         switch (flags) {
1680
1681 /*      .data */
1682 /* 1: */
1683 /*      opl5 */
1684
1685         case FMOVFO:
1686                 opl5();
1687                 return;
1688
1689 /*      opl6 */
1690
1691         case FBRANCH:
1692                 opl6();
1693                 return;
1694
1695 /*      opl7 */
1696
1697         case FJSR:
1698                 opl7();
1699                 return;
1700
1701 /*      opl10 */
1702
1703         case FRTS:
1704                 opl10();
1705                 return;
1706
1707 /*      opl11 */
1708
1709         case FSYSTRAP:
1710                 opl11();
1711                 return;
1712
1713 /*      opl12 */
1714
1715         case FMOVF:
1716                 opl12();
1717                 return;
1718
1719 /*      opl13 */
1720
1721         case FDOUBLE:
1722                 opl13();
1723                 return;
1724
1725 /*      opl14 */
1726
1727         case FFLOP:
1728                 opl14();
1729                 return;
1730
1731 /*      opl15 */
1732
1733         case FSINGLE:
1734                 opl15();
1735                 return;
1736
1737 /*      opl16 */
1738
1739         case FDOTBYTE:
1740                 opl16();
1741                 return;
1742
1743 #if 1 /* modifications for dec syntax */
1744         case FDOTWORD:
1745                 opldotword();
1746                 return;
1747 #endif
1748
1749 /*      opl17 */
1750
1751         case FSTRING:
1752                 opl17();
1753                 return;
1754
1755 /*      opl20 */
1756
1757         case FDOTEVEN:
1758                 opl20();
1759                 return;
1760
1761 /*      opl21 */
1762
1763         case FDOTIF:
1764                 opl21();
1765                 return;
1766
1767 /*      opl22 */
1768
1769         case FDOTENDIF:
1770                 opl22();
1771                 return;
1772
1773 /*      opl23 */
1774
1775         case FDOTGLOBL:
1776                 opl23();
1777                 return;
1778
1779 /*      xxpr */
1780
1781         case FREGISTER: /* can never get here */
1782                 xpr();
1783                 return;
1784
1785 /*      opl25 */
1786
1787         case FDOTTEXT:
1788                 opl25();
1789                 return;
1790
1791 /*      opl26 */
1792
1793         case FDOTDATA:
1794                 opl26();
1795                 return;
1796
1797 /*      opl27 */
1798
1799         case FDOTBSS:
1800                 opl27();
1801                 return;
1802
1803 /*      opl30 */
1804
1805         case FMULDIV:
1806                 opl30();
1807                 return;
1808
1809 /*      opl31 */
1810
1811         case FSOB:
1812                 opl31();
1813                 return;
1814
1815 /*      opl32 */
1816
1817         case FDOTCOMM:
1818                 opl32();
1819                 return;
1820
1821 /*      xxpr */
1822 /*      xxpr */
1823
1824         case FESTTEXT:
1825         case FESTDATA:
1826                 xpr();
1827                 return;
1828
1829 /*      opl35 */
1830
1831         case FJBR:
1832                 opl35();
1833                 return;
1834
1835 /*      opl36 */
1836
1837         case FJCOND:
1838                 opl36();
1839                 return;
1840
1841 /*      .text */
1842
1843         }
1844 }
1845
1846 /* opeof: */
1847 /*      mov     $1,line */
1848 /*      mov     $20,-(sp) */
1849 /*      mov     $argb,r1 */
1850 /* 1: */
1851 /*      jsr     pc,getw */
1852 /*      tst     r4 */
1853 /*      bmi     1f */
1854 /*      movb    r4,(r1)+ */
1855 /*      dec     (sp) */
1856 /*      bgt     1b */
1857 /*      tstb    -(r1) */
1858 /*      br      1b */
1859 /* 1: */
1860 /*      movb    $'\n,(r1)+ */
1861 /*      clrb    (r1)+ */
1862 /*      tst     (sp)+ */
1863 /*      rts     pc */
1864
1865 void opeof() {
1866         int count;
1867         char *p;
1868 #ifdef LISTING
1869         int argch;
1870 #endif
1871
1872         line = 1;
1873         count = 20;
1874         p = argb;
1875         while (1) {
1876                 p1getw();
1877                 if (token == -1)
1878                         break;
1879                 if (count) {
1880                         count--;
1881                         *p++ = (char)token;
1882                 }
1883         }
1884 #ifdef LISTING
1885         if (passno) {
1886                 if (argfp)
1887                         fclose(argfp);
1888                 *p = 0;
1889                 argfp = fopen(argb, "r");
1890                 if (argfp)
1891                         while ((argch = getc(argfp)) != EOF) {
1892                                 putchar(argch);
1893                                 if (argch == '\n')
1894                                         break;
1895                         }
1896         }
1897 #endif
1898         *p++ = '\n';
1899         *p = 0;
1900 }
1901
1902 /* opl30:                                       / mul, div etc */
1903 /*      inc     swapf */
1904 /*      mov     $1000,rlimit */
1905 /*      br      opl13 */
1906
1907 void opl30() {
1908         swapf = 1;
1909         rlimit = 01000;
1910         opl13();
1911 }
1912
1913 /* opl14:                                       / flop freg,fsrc */
1914 /*      inc     swapf */
1915
1916 void opl14() {
1917         swapf = 1;
1918         opl5();
1919 }
1920
1921 /* opl5:                                        / flop src,freg */
1922 /*      mov     $400,rlimit */
1923
1924 void opl5() {
1925         rlimit = 0400;
1926         opl13();
1927 }
1928
1929 /* opl13:                                       /double */
1930 /*      jsr     pc,addres */
1931
1932 void opl13() {
1933         addres();
1934         op2a();
1935 }
1936
1937 /* op2a: */
1938 /*      mov     r2,-(sp) */
1939 /*      jsr     pc,readop */
1940
1941 void op2a() {
1942         rvalue = leftvalue;
1943         readop();
1944         op2b();
1945 }
1946
1947 /* op2b: */
1948 /*      jsr     pc,addres */
1949 /*      tst     swapf */
1950 /*      beq     1f */
1951 /*      mov     (sp),r0 */
1952 /*      mov     r2,(sp) */
1953 /*      mov     r0,r2 */
1954 /* 1: */
1955
1956 void op2b() {
1957         int tempvalue;
1958         intptr_t *adrtmp;
1959
1960         addres();
1961 /* printf("op2b %d 0x%08x 0x%08x\n", swapf, rvalue, leftvalue); */
1962         if (swapf) {
1963                 tempvalue = rvalue;
1964                 rvalue = leftvalue;
1965                 leftvalue = tempvalue;
1966         }
1967
1968 /*      swab    (sp) */
1969 /*      asr     (sp) */
1970 /*      asr     (sp) */
1971 /*      cmp     (sp),rlimit */
1972 /*      blo     1f */
1973 /*      mov     $'x,-(sp) */
1974 /*      jsr     pc,error */
1975 /* 1: */
1976
1977 #if 1
1978  rvalue <<= 6;
1979 #else
1980         rvalue = (rvalue & 0377) << 6; /* seems a bit stupid */
1981 #endif
1982         if ((unsigned int)rvalue >= (unsigned int)rlimit)
1983  {
1984  printf("a 0x%08x 0x%08x\n", rvalue, rlimit);
1985                 error('x');
1986  }
1987
1988 /*      bis     (sp)+,r2 */
1989 /*      bis     (sp)+,r2 */
1990 /*      clr     r3 */
1991 /*      jsr     pc,outw */
1992
1993         outw(leftvalue | rvalue | opcode, 0);
1994
1995 /*      mov     $adrbuf,r1 */
1996 /* 1: */
1997 /*      cmp     r1,r5 */
1998 /*      bhis    1f */
1999 /*      mov     (r1)+,r2 */
2000 /*      mov     (r1)+,r3 */
2001 /*      mov     (r1)+,xsymbol */
2002 /*      jsr     pc,outw */
2003 /*      br      1b */
2004 /* 1: */
2005 /*      rts     pc */
2006
2007         adrtmp = adrbuf;
2008         while (adrtmp < adrptr) {
2009                 leftvalue = *adrtmp++;
2010                 leftflags = *adrtmp++;
2011                 xsymbol = (struct symbol *)*adrtmp++;
2012                 outw(leftvalue, leftflags);
2013         }
2014 }
2015
2016 /* opl15:                                       / single operand */
2017 /*      clr     -(sp) */
2018 /*      br      op2b */
2019
2020 void opl15() {
2021         rvalue = 0;
2022         op2b();
2023 }
2024
2025 /* opl12:                                       / movf */
2026 /*      mov     $400,rlimit */
2027 /*      jsr     pc,addres */
2028 /*      cmp     r2,$4                   / see if source is fregister */
2029 /*      blo     1f */
2030 /*      inc     swapf */
2031 /*      br      op2a */
2032 /* 1: */
2033 /*      mov     $174000,(sp) */
2034 /*      br      op2a */
2035
2036 void opl12() {
2037         rlimit = 0400;
2038         addres();
2039         if (leftvalue >= 4)
2040                 swapf = 1;
2041         else
2042                 opcode = 0174000;
2043         op2a();
2044 }
2045
2046 /* opl35:                                       / jbr */
2047 /* opl36:                                       / jeq, jne, etc */
2048 /*      jsr     pc,expres */
2049 /*      tst     passno */
2050 /*      bne     1f */
2051 /*      mov     r2,r0 */
2052 /*      jsr     pc,setbr */
2053 /*      tst     r2 */
2054 /*      beq     2f */
2055 /*      cmp     (sp),$br */
2056 /*      beq     2f */
2057 /*      add     $2,r2 */
2058 /* 2: */
2059 /*      add     r2,dot                  / if doesn't fit */
2060 /*      add     $2,dot */
2061 /*      tst     (sp)+ */
2062 /*      rts     pc */
2063 /* 1: */
2064 /*      jsr     pc,getbr */
2065 /*      bcc     dobranch */
2066 /*      mov     (sp)+,r0 */
2067 /*      mov     r2,-(sp) */
2068 /*      mov     r3,-(sp) */
2069 /*      cmp     r0,$br */
2070 /*      beq     2f */
2071 /*      mov     $402,r2 */
2072 /*      xor     r0,r2                   / flip cond, add ".+6" */
2073 /*      mov     $1,r3 */
2074 /*      jsr     pc,outw */
2075 /* 2: */
2076 /*      mov     $1,r3 */
2077 /*      mov     $jmp+37,r2 */
2078 /*      jsr     pc,outw */
2079 /*      mov     (sp)+,r3 */
2080 /*      mov     (sp)+,r2 */
2081 /*      jsr     pc,outw */
2082 /*      rts     pc */
2083
2084 void opl35() {
2085         expres();
2086         if (passno == 0)
2087                 pdot->value += setbr(leftvalue) ? 4 : 2;
2088         else {
2089                 if (getbr() == 0)
2090                         dobranch();
2091                 else {
2092                         outw(0000137, FABS); /* jmp */
2093                         outw(leftvalue, leftflags);
2094                 }
2095         }
2096 }
2097
2098 void opl36() {
2099         expres();
2100         if (passno == 0)
2101                 pdot->value += setbr(leftvalue) ? 6 : 2;
2102         else {
2103                 if (getbr() == 0)
2104                         dobranch();
2105                 else {
2106                         outw(opcode ^ 0402, FABS); /* jne, jeq, etc .+6 */
2107                         outw(0000137, FABS); /* jmp */
2108                         outw(leftvalue, leftflags);
2109                 }
2110         }
2111 }
2112
2113 /* opl31:                                       / sob */
2114 /*      jsr     pc,expres */
2115 /*      jsr     pc,checkreg */
2116 /*      swab    r2 */
2117 /*      asr     r2 */
2118 /*      asr     r2 */
2119 /*      bis     r2,(sp) */
2120 /*      jsr     pc,readop */
2121 /*      jsr     pc,expres */
2122 /*      tst     passno */
2123 /*      beq     3f */
2124 /*      sub     dot,r2 */
2125 /*      neg     r2 */
2126 /*      mov     r2,r0 */
2127 /*      cmp     r0,$-2 */
2128 /*      blt     2f */
2129 /*      cmp     r0,$175 */
2130 /*      bgt     2f */
2131 /*      add     $4,r2 */
2132 /*      br      1f */
2133
2134 void opl31() {
2135         expres();
2136         checkreg();
2137         opcode |= leftvalue << 6;
2138         readop();
2139         expres();
2140         if (passno == 0)
2141                 binstr();
2142         else {
2143                 leftvalue = pdot->value - leftvalue;
2144                 if (leftvalue < -2 || leftvalue > 0175)
2145                         errorb();
2146                 else {
2147                         leftvalue += 4;
2148                         branch();
2149                 }
2150         }
2151 }
2152
2153 /* opl6:                                        /branch */
2154 /*      jsr     pc,expres */
2155 /*      tst     passno */
2156 /*      beq     3f */
2157
2158 void opl6() {
2159         expres();
2160         if (passno == 0)
2161                 binstr();
2162         else
2163                 dobranch();
2164 }
2165
2166 /* dobranch: */
2167 /*      sub     dot,r2 */
2168 /*      mov     r2,r0 */
2169 /*      cmp     r0,$-254. */
2170 /*      blt     2f */
2171 /*      cmp     r0,$256. */
2172 /*      bgt     2f */
2173
2174 void dobranch() {
2175         leftvalue -= pdot->value;
2176         if (leftvalue < -254 || leftvalue > 256)
2177                 errorb();
2178         else
2179                 branch();
2180 }
2181
2182 /* 1: */
2183 /*      bit     $1,r2 */
2184 /*      bne     2f */
2185 /*      cmp     r3,dot-2                / same relocation as . */
2186 /*      bne     2f */
2187 /*      asr     r2 */
2188 /*      dec     r2 */
2189 /*      bic     $177400,r2 */
2190
2191 void branch() {
2192         if (leftvalue & 1)
2193                 errorb();
2194         else {
2195                 leftvalue = ((leftvalue >> 1) - 1) & 0377;
2196                 binstr();
2197         }
2198 }
2199
2200 /* 3: */
2201 /*      bis     (sp)+,r2 */
2202 /*      clr     r3 */
2203 /*      jsr     pc,outw */
2204 /*      rts     pc */
2205
2206 void binstr() {
2207         outw(leftvalue | opcode, 0);
2208 }
2209
2210 /* 2: */
2211 /*      mov     $'b,-(sp) */
2212 /*      jsr     pc,error */
2213 /*      clr     r2 */
2214 /*      br      3b */
2215
2216 void errorb() {
2217         error('b');
2218         leftvalue = 0;
2219         branch();
2220 }
2221
2222 /* opl7:                                        /jsr */
2223 /*      jsr     pc,expres */
2224 /*      jsr     pc,checkreg */
2225 /*      jmp     op2a */
2226
2227 void opl7() {
2228         expres();
2229         checkreg();
2230         op2a();
2231 }
2232
2233 /* opl10:                                       / rts */
2234 /*      jsr     pc,expres */
2235 /*      jsr     pc,checkreg */
2236 /*      br      1f */
2237
2238 void opl10() {
2239         expres();
2240         checkreg();
2241         rinstr();
2242 }
2243
2244 /* opl11:                                       / sys */
2245 /*      jsr     pc,expres */
2246 /*      cmp     r2,$256. */
2247 /*      bhis    0f */
2248 /*      cmp     r3,$1 */
2249 /*      ble     1f */
2250 /* 0: */
2251 /*      mov     $'a,-(sp) */
2252 /*      jsr     pc,error */
2253
2254 void opl11() {
2255         expres();
2256         if (leftvalue < 0 || leftvalue >= 256)
2257                 error('a');
2258         rinstr();
2259 }
2260
2261 /* 1: */
2262 /*      bis     (sp)+,r2 */
2263 /*      jsr     pc,outw */
2264 /*      rts     pc */
2265
2266 void rinstr() {
2267         outw(leftvalue | opcode, leftflags);
2268 }
2269
2270 /* opl16:                                       / .byte */
2271 /*      jsr     pc,expres */
2272 /*      jsr     pc,outb */
2273 /*      cmp     r4,$', */
2274 /*      bne     1f */
2275 /*      jsr     pc,readop */
2276 /*      br      opl16 */
2277 /* 1: */
2278 /*      tst     (sp)+ */
2279 /*      rts     pc */
2280
2281 void opl16() {
2282         while (1) {
2283                 expres();
2284                 outb(leftvalue, leftflags);
2285                 if (token != TCOMMA)
2286                         break;
2287                 readop();
2288         }
2289 }
2290
2291 #if 1 /* modifications for dec syntax */
2292 void opldotword() {
2293         while (1) {
2294                 expres();
2295                 outw(leftvalue, leftflags);
2296                 if (token != TCOMMA)
2297                         break;
2298                 readop();
2299         }
2300 }
2301 #endif
2302
2303 /* opl17:                                       / < (.ascii) */
2304 /*      jsr     pc,getw */
2305 /*      mov     $1,r3 */
2306 /*      mov     r4,r2 */
2307 /*      bmi     2f */
2308 /*      bic     $!377,r2 */
2309 /*      jsr     pc,outb */
2310 /*      br      opl17 */
2311 /* 2: */
2312 /*      jsr     pc,getw */
2313 /*      rts     pc */
2314
2315 void opl17() {
2316         while (1) {
2317                 p1getw();
2318                 if (token == -1)
2319                         break;
2320                 outb(token & 0377, FABS);
2321         }
2322         p1getw();
2323 }
2324
2325 /* opl20:                                       /.even */
2326 /*      bit     $1,dot */
2327 /*      beq     1f */
2328 /*      cmp     dot-2,$4 */
2329 /*      beq     2f                      / bss mode */
2330 /*      clr     r2 */
2331 /*      clr     r3 */
2332 /*      jsr     pc,outb */
2333 /*      br      1f */
2334 /* 2: */
2335 /*      inc     dot */
2336 /* 1: */
2337 /*      tst     (sp)+ */
2338 /*      rts     pc */
2339
2340 void opl20() {
2341         if (pdot->value & 1) {
2342                 if (pdot->flags != FBSS)
2343                         outb(0, 0);
2344                 else
2345                         pdot->value++;
2346         }
2347 }
2348
2349 /* opl21:                                       /if */
2350 /*      jsr     pc,expres */
2351
2352 void opl21() {
2353         expres();
2354 }
2355
2356 /* opl22: */
2357 /* oplret: */
2358 /*      tst     (sp)+ */
2359 /*      rts     pc */
2360
2361 void opl22() {
2362 }
2363
2364 void oplret() {
2365 }
2366
2367 /* opl23:                                       /.globl */
2368 /*      cmp     r4,$200 */
2369 /*      blo     1f */
2370 /*      bisb    $40,(r4) */
2371 /*      jsr     pc,readop */
2372 /*      cmp     r4,$', */
2373 /*      bne     1f */
2374 /*      jsr     pc,readop */
2375 /*      br      opl23 */
2376 /* 1: */
2377 /*      tst     (sp)+ */
2378 /*      rts     pc */
2379
2380 void opl23() {
2381         struct symbol *psymbol;
2382
2383         while (1) {
2384                 if (token >= 0 && token < TASCII)
2385                         break;
2386                 psymbol = (struct symbol *)token;
2387                 psymbol->flags |= FGLOBAL;
2388                 readop();
2389                 if (token != TCOMMA)
2390                         break;
2391                 readop();
2392         }
2393 }
2394
2395 /* opl25:                                       / .text, .data, .bss */
2396 /* opl26: */
2397 /* opl27: */
2398 /*      inc     dot */
2399 /*      bic     $1,dot */
2400 /*      mov     r0,-(sp) */
2401 /*      mov     dot-2,r1 */
2402 /*      asl     r1 */
2403 /*      mov     dot,savdot-4(r1) */
2404 /*      tst     passno */
2405 /*      beq     1f */
2406 /*      mov     $txtp,-(sp) */
2407 /*      jsr     pc,flush */
2408 /*      mov     $relp,-(sp) */
2409 /*      jsr     pc,flush */
2410 /*      mov     (sp),r2 */
2411 /*      asl     r2 */
2412 /*      add     $txtseek-[4*25],r2 */
2413 /*      mov     r2,tseekp */
2414 /*      mov     (r2),r0 */
2415 /*      mov     2(r2),r1 */
2416 /*      mov     $txtp,-(sp) */
2417 /*      jsr     pc,oset */
2418 /*      add     $trelseek-txtseek,r2 */
2419 /*      mov     (r2),r0 */
2420 /*      mov     2(r2),r1 */
2421 /*      mov     r2,rseekp */
2422 /*      mov     $relp,-(sp) */
2423 /*      jsr     pc,oset */
2424 /* 1: */
2425 /*      mov     (sp)+,r0 */
2426 /*      mov     savdot-[2*25](r0),dot */
2427 /*      asr     r0 */
2428 /*      sub     $25-2,r0 */
2429 /*      mov     r0,dot-2                / new . relocation */
2430 /*      tst     (sp)+ */
2431 /*      rts     pc */
2432
2433 void opl25() {
2434         pdot->value = (pdot->value + 1) & ~1;
2435         savdot[pdot->flags - FTEXT] = pdot->value;
2436         if (passno) {
2437                 flush(&txtp);
2438                 flush(&relp);
2439                 tseekp = seek;
2440                 oset(&txtp, seek[0]);
2441                 rseekp = seek + 3;
2442                 oset(&relp, seek[3]);
2443         }
2444         pdot->value = savdot[0];
2445         pdot->flags = FTEXT;
2446 }
2447
2448 void opl26() {
2449         pdot->value = (pdot->value + 1) & ~1;
2450         savdot[pdot->flags - FTEXT] = pdot->value;
2451         if (passno) {
2452                 flush(&txtp);
2453                 flush(&relp);
2454                 tseekp = seek + 1;
2455                 oset(&txtp, seek[1]);
2456                 rseekp = seek + 4;
2457                 oset(&relp, seek[4]);
2458         }
2459         pdot->value = savdot[1];
2460         pdot->flags = FDATA;
2461 }
2462
2463 void opl27() {
2464         pdot->value = (pdot->value + 1) & ~1;
2465         savdot[pdot->flags - FTEXT] = pdot->value;
2466         if (passno) { /* this is not really needed: */
2467                 flush(&txtp);
2468                 flush(&relp);
2469                 tseekp = seek + 2;
2470                 oset(&txtp, seek[2]);
2471                 rseekp = seek + 5;
2472                 oset(&relp, seek[5]);
2473         }
2474         pdot->value = savdot[2];
2475         pdot->flags = FBSS;
2476 }
2477
2478 /* opl32: */
2479 /*      cmp     r4,$200 */
2480 /*      blo     1f */
2481 /*      mov     r4,-(sp) */
2482 /*      jsr     pc,readop */
2483 /*      jsr     pc,readop */
2484 /*      jsr     pc,expres */
2485 /*      mov     (sp)+,r0 */
2486 /*      bit     $37,(r0) */
2487 /*      bne     1f */
2488 /*      bis     $40,(r0) */
2489 /*      mov     r2,2(r0) */
2490 /* 1: */
2491 /*      tst     (sp)+ */
2492 /*      rts     pc */
2493
2494 void opl32() {
2495         struct symbol *psymbol;
2496
2497         if (token >= 0 && token < TASCII)
2498                 return;
2499         psymbol = (struct symbol *)token;
2500         readop();
2501         readop();
2502         expres();
2503         if ((psymbol->flags & 037) == 0) {
2504                 psymbol->flags |= FGLOBAL;
2505                 psymbol->value = leftvalue;
2506         }
2507 }
2508
2509 /* addres: */
2510 /*      clr     -(sp) */
2511
2512 void addres() {
2513 /* printf("addres() token = 0x%08x\n", token); */
2514         indirect = 0; /* it has a different meaning on pass 1/2 */
2515         addres1();
2516 }
2517
2518 /* 4: */
2519 /*      cmp     r4,$'( */
2520 /*      beq     alp */
2521 /*      cmp     r4,$'- */
2522 /*      beq     amin */
2523 /*      cmp     r4,$'$ */
2524 /*      beq     adoll */
2525 /*      cmp     r4,$'* */
2526 /*      bne     getx */
2527 /*      jmp     astar */
2528
2529 void addres1() {
2530         switch (token) {
2531         case TLPAREN:
2532                 alp();
2533                 return;
2534         case TMIN:
2535                 amin();
2536                 return;
2537         case TDOLL:
2538                 adoll();
2539                 return;
2540         case TSTAR:
2541                 astar();
2542                 return;
2543         }
2544         getx();
2545 }
2546
2547 /* getx: */
2548 /*      jsr     pc,expres */
2549 /*      cmp     r4,$'( */
2550 /*      bne     2f */
2551 /*      jsr     pc,readop */
2552 /*      mov     r2,(r5)+ */
2553 /*      mov     r3,(r5)+ */
2554 /*      mov     xsymbol,(r5)+ */
2555 /*      jsr     pc,expres */
2556 /*      jsr     pc,checkreg */
2557 /*      jsr     pc,checkrp */
2558 /*      bis     $60,r2 */
2559 /*      bis     (sp)+,r2 */
2560 /*      rts     pc */
2561 /* 2: */
2562
2563 void getx() {
2564         expres();
2565         if (token == TLPAREN) {
2566                 readop();
2567                 *adrptr++ = leftvalue;
2568                 *adrptr++ = leftflags;
2569                 *adrptr++ = (intptr_t)xsymbol;
2570                 expres();
2571                 checkreg();
2572                 checkrp();
2573                 leftvalue |= 060 | indirect;
2574         }
2575
2576 /*      cmp     r3,$24 */
2577 /*      bne     1f */
2578 /*      jsr     pc,checkreg */
2579 /*      bis     (sp)+,r2 */
2580 /*      rts     pc */
2581 /* 1: */
2582
2583         else if (leftflags == FREGISTER) {
2584                 checkreg();
2585                 leftvalue |= indirect;
2586         }
2587
2588 /*      mov     r3,-(sp) */
2589 /*      bic     $40,r3 */
2590 /*      mov     (sp)+,r3 */
2591 /*      bis     $100000,r3 */
2592 /*      sub     dot,r2 */
2593 /*      sub     $4,r2 */
2594 /*      cmp     r5,$adrbuf */
2595 /*      beq     1f */
2596 /*      sub     $2,r2 */
2597 /* 1: */
2598
2599         else {
2600                 leftflags |= 0100000; /* relocate flag */
2601                 leftvalue -= (pdot->value + 4);
2602                 if (adrptr != adrbuf)
2603                         leftvalue -= 2;
2604
2605 /*      mov     r2,(r5)+                / index */
2606 /*      mov     r3,(r5)+                / index reloc. */
2607 /*      mov     xsymbol,(r5)+           / index global */
2608 /*      mov     $67,r2                  / address mode */
2609 /*      bis     (sp)+,r2 */
2610 /*      rts     pc */
2611
2612                 *adrptr++ = leftvalue;
2613                 *adrptr++ = leftflags;
2614                 *adrptr++ = (intptr_t)xsymbol;
2615                 leftvalue = 067 | indirect;
2616         }
2617 }
2618
2619 /* alp: */
2620 /*      jsr     pc,readop */
2621 /*      jsr     pc,expres */
2622 /*      jsr     pc,checkrp */
2623 /*      jsr     pc,checkreg */
2624 /*      cmp     r4,$'+ */
2625 /*      beq     1f */
2626
2627 void alp() {
2628         readop();
2629         expres();
2630         checkrp();
2631         checkreg();
2632         if (token != TPLUS) {
2633
2634 /*      tst     (sp)+ */
2635 /*      beq     2f */
2636 /*      bis     $70,r2 */
2637 /*      clr     (r5)+ */
2638 /*      clr     (r5)+ */
2639 /*      mov     xsymbol,(r5)+ */
2640 /*      rts     pc */
2641 /* 2: */
2642
2643                 if (indirect) {
2644                         leftvalue |= 070;
2645                         *adrptr++ = 0;
2646                         *adrptr++ = 0;
2647                         *adrptr++ = (intptr_t)xsymbol;
2648                 }
2649
2650 /*      bis     $10,r2 */
2651 /*      rts     pc */
2652
2653                 else
2654                         leftvalue |= 010;
2655
2656 /* 1: */
2657 /*      jsr     pc,readop */
2658 /*      bis     $20,r2 */
2659 /*      bis     (sp)+,r2 */
2660 /*      rts     pc */
2661
2662         }
2663         else {
2664                 readop();
2665                 leftvalue |= 020 | indirect;
2666         }
2667 }
2668
2669 /* amin: */
2670 /*      jsr     pc,readop */
2671 /*      cmp     r4,$'( */
2672 /*      beq     1f */
2673 /*      mov     r4,savop */
2674 /*      mov     $'-,r4 */
2675 /*      br      getx */
2676 /* 1: */
2677 /*      jsr     pc,readop */
2678 /*      jsr     pc,expres */
2679 /*      jsr     pc,checkrp */
2680 /*      jsr     pc,checkreg */
2681 /*      bis     (sp)+,r2 */
2682 /*      bis     $40,r2 */
2683 /*      rts     pc */
2684
2685
2686 void amin() {
2687         readop();
2688         if (token != TLPAREN) {
2689                 savop = token;
2690                 token = TMIN;
2691                 getx();
2692         }
2693         else {
2694                 readop();
2695                 expres();
2696                 checkrp();
2697                 checkreg();
2698                 leftvalue |= indirect | 040;
2699         }
2700 }
2701
2702 /* adoll: */
2703 /*      jsr     pc,readop */
2704 /*      jsr     pc,expres */
2705 /*      mov     r2,(r5)+ */
2706 /*      mov     r3,(r5)+ */
2707 /*      mov     xsymbol,(r5)+ */
2708 /*      mov     (sp)+,r2 */
2709 /*      bis     $27,r2 */
2710 /*      rts     pc */
2711
2712 void adoll() {
2713         readop();
2714         expres();
2715         *adrptr++ = leftvalue;
2716         *adrptr++ = leftflags;
2717         *adrptr++ = (intptr_t)xsymbol;
2718         leftvalue = indirect | 027; /* means (pc)+ */
2719 }
2720
2721 /* astar: */
2722 /*      tst     (sp) */
2723 /*      beq     1f */
2724 /*      mov     $'*,-(sp) */
2725 /*      jsr     pc,error */
2726 /* 1: */
2727 /*      mov     $10,(sp) */
2728 /*      jsr     pc,readop */
2729 /*      jmp     4b */
2730
2731 void astar() {
2732         if (indirect)
2733                 error('*');
2734         indirect = 010;
2735         readop();
2736         addres1();
2737 }
2738
2739 /* checkreg: */
2740 /*      cmp     r2,$7 */
2741 /*      bhi     1f */
2742 /*      cmp     r1,$1 */
2743 /*      blos    2f */
2744 /*      cmp     r3,$5 */
2745 /*      blo     1f */
2746 /* 2: */
2747 /*      rts     pc */
2748 /* 1: */
2749 /*      mov     $'a,-(sp) */
2750 /*      jsr     pc,error */
2751 /*      clr     r2 */
2752 /*      clr     r3 */
2753 /*      rts     pc */
2754
2755 void checkreg() {
2756         if (leftvalue > 7 || (leftflags >= FTEXT && leftflags <= FBSS)) {
2757                 error('a');
2758                 leftvalue = 0;
2759                 leftflags = 0;
2760         }
2761 }
2762
2763 /* checkrp: */
2764 /*      cmp     r4,$') */
2765 /*      beq     1f */
2766 /*      mov     $'),-(sp) */
2767 /*      jsr     pc,error */
2768 /*      rts     pc */
2769 /* 1: */
2770 /*      jsr     pc,readop */
2771 /*      rts     pc */
2772
2773 void checkrp() {
2774         if (token != TRPAREN)
2775                 error(')');
2776         else
2777                 readop();
2778 }
2779
2780 /* setbr: */
2781 /*      mov     brtabp,r1 */
2782 /*      cmp     r1,$brlen */
2783 /*      blt     1f */
2784 /*      mov     $2,r2 */
2785 /*      rts     pc */
2786 /* 1: */
2787
2788 int setbr(value) int value; {
2789         int index;
2790
2791         if (brtabp >= brlen)
2792                 return 2;
2793
2794 /*      inc     brtabp */
2795 /*      clr     -(sp) */
2796 /*      sub     dot,r0 */
2797 /*      ble     1f */
2798 /*      sub     brdelt,r0 */
2799 /* 1: */
2800
2801         index = brtabp++;
2802         value -= pdot->value;
2803         if (value > 0)
2804                 value -= brdelt;
2805
2806 /*      cmp     r0,$-254. */
2807 /*      blt     1f */
2808 /*      cmp     r0,$256. */
2809 /*      ble     2f */
2810 /* 1: */
2811
2812         if (value < -254 || value > 256) {
2813
2814 /*      mov     r1,-(sp) */
2815 /*      bic     $!7,(sp) */
2816 /*      mov     $1,r0 */
2817 /*      ash     (sp)+,r0 */
2818 /*      ash     $-3,r1 */
2819 /*      bisb    r0,brtab(r1) */
2820 /*      mov     $2,(sp) */
2821
2822                 brtab[index >> 3] |= 1 << (index & 7);
2823                 return 2;
2824
2825 /* 2: */
2826 /*      mov     (sp)+,r2 */
2827 /*      rts     pc */
2828
2829         }
2830         return 0;
2831 }
2832
2833 /* getbr: */
2834 /*      mov     brtabp,r1 */
2835 /*      cmp     r1,$brlen */
2836 /*      blt     1f */
2837 /*      sec */
2838 /*      rts     pc */
2839 /* 1: */
2840
2841 int getbr() {
2842         int index;
2843
2844         if (brtabp >= brlen)
2845                 return 1;
2846
2847 /*      mov     r1,-(sp) */
2848 /*      bic     $!7,(sp) */
2849 /*      neg     (sp) */
2850 /*      inc     brtabp */
2851 /*      ash     $-3,r1 */
2852 /*      movb    brtab(r1),r1 */
2853 /*      ash     (sp)+,r1 */
2854 /*      ror     r1                      / 0-bit into c-bit */
2855 /*      rts     pc */
2856
2857         index = brtabp++;
2858         return brtab[index >> 3] & (1 << (index & 7));
2859 }
2860
2861 /* expres: */
2862 /*      clr     xsymbol */
2863
2864 void expres() {
2865         xsymbol = NULL;
2866         expres1();
2867 }
2868
2869 /* expres1: */
2870 /*      mov     r5,-(sp) */
2871 /*      mov     $'+,-(sp) */
2872 /*      clr     r2 */
2873 /*      mov     $1,r3 */
2874 /*      br      1f */
2875
2876 void expres1() {
2877         struct symbol *psymbol;
2878
2879 /* printf("expres()\n"); */
2880         optoken = TPLUS;
2881         opfound = 0;
2882         leftvalue = 0;
2883         leftflags = FABS;
2884         goto entry;
2885
2886 /* advanc: */
2887 /*      jsr     pc,readop */
2888 /* 1: */
2889 /*      mov     r4,r0 */
2890 /*      blt     6f */
2891 /*      cmp     r0,$177 */
2892 /*      ble     7f */
2893 /* 6: */
2894 /*      movb    (r4),r0 */
2895 /*      bne     1f */
2896 /*      tst     passno */
2897 /*      beq     1f */
2898 /*      mov     $'u,-(sp) */
2899 /*      jsr     pc,error */
2900 /* 1: */
2901
2902         while (1) {
2903                 readop();
2904         entry:
2905                 rightflags = token;
2906                 if (token < 0 || token >= TASCII) {
2907                         psymbol = (struct symbol *)token;
2908                         rightflags = psymbol->flags;
2909                         if (rightflags == 0 && passno)
2910                                 error('u');
2911
2912 /*      tst     overlaid */
2913 /*      beq     0f */
2914
2915 /* Bill Shannon's hack to the assembler to force globl text */
2916 /* references to remain undefined so that the link editor may */
2917 /* resolve them. This is necessary if a function is used as an */
2918 /* arg in an overlay located piece of code, and the function is */
2919 /* actually in another overlay. Elsewise, the assembler fix's up */
2920 /* the reference before the link editor changes the globl refrence */
2921 /* to the thunk. -wfj 5/80 */
2922 /*      cmp     r0,$42                  / is it globl text ? */
2923 /*      bne     0f                      / nope */
2924 /*      mov     $40,r0                  / yes, treat it as undefined external */
2925 /* 0: */
2926
2927                         if (overlaid && rightflags == (FTEXT | FGLOBAL))
2928                                 rightflags = FGLOBAL;
2929
2930 /*      cmp     r0,$40 */
2931 /*      bne     1f */
2932 /*      mov     r4,xsymbol */
2933 /*      clr     r1 */
2934 /*      br      oprand */
2935 /* 1: */
2936
2937                         if (rightflags == FGLOBAL) {
2938                                 xsymbol = (struct symbol *)token;
2939                                 rightvalue = 0;
2940                         }
2941
2942 /*      mov     2(r4),r1 */
2943 /*      br      oprand */
2944
2945                         else
2946                                 rightvalue = psymbol->value;
2947                         oprand();
2948                         continue;
2949                 }
2950
2951 /* 7: */
2952 /*      cmp     r4,$141 */
2953 /*      blo     1f */
2954 /*      asl     r4 */
2955 /*      mov     curfb-[2*141](r4),r0 */
2956 /*      mov     2(r0),r1 */
2957 /*      movb    (r0),r0 */
2958 /*      br      oprand */
2959 /* 1: */
2960
2961                 if (token >= TLABEL) {
2962                         if (token < TLABEL + 10)
2963                                 psymbol = *(struct symbol **)
2964                                                 curfb[token - TLABEL];
2965                         else
2966                                 psymbol = *(struct symbol **)
2967                                                 nxtfb[token - (TLABEL + 10)];
2968                         rightvalue = psymbol->value;
2969                         rightflags = psymbol->flags;
2970                         oprand();
2971                         continue;
2972                 }
2973
2974 /*      mov     $esw1,r1 */
2975 /* 1: */
2976 /*      cmp     (r1)+,r4 */
2977 /*      beq     1f */
2978 /*      tst     (r1)+ */
2979 /*      bne     1b */
2980 /*      tst     (sp)+ */
2981 /*      mov     (sp)+,r5 */
2982 /*      rts     pc */
2983 /* 1: */
2984 /*      jmp     *(r1) */
2985
2986                 switch (token) {
2987                 default:
2988                         return;
2989
2990 /*      .data */
2991 /* esw1: */
2992 /*      '+;     binop */
2993 /*      '-;     binop */
2994 /*      '*;     binop */
2995 /*      '/;     binop */
2996 /*      '&;     binop */
2997 /*      037;    binop */
2998 /*      035;    binop */
2999 /*      036;    binop */
3000 /*      '%;     binop */
3001
3002                 case TPLUS:
3003                 case TMIN:
3004                 case TSTAR:
3005                 case TSLASH:
3006                 case TAND:
3007                 case TOR:
3008                 case TLSH:
3009                 case TRSH:
3010                 case TMOD:
3011                         binop();
3012                         break;
3013
3014 /*      '[;     brack */
3015
3016                 case TLBRACK:
3017                         brack();
3018                         break;
3019
3020 /*      '^;     binop */
3021
3022                 case TCARET:
3023                         binop();
3024                         break;
3025
3026 /*      1;      exnum */
3027
3028                 case TABS:
3029                         exnum();
3030                         break;
3031
3032 /*      2;      exnum1 */
3033
3034                 case TABS2:
3035                         exnum1();
3036                         break;
3037
3038 /*      '!;     binop */
3039
3040                 case TNOT:
3041                         binop();
3042                         break;
3043
3044 /*      200;    0 */
3045 /*      .text */
3046
3047                 }
3048         }
3049 }
3050
3051 /* binop: */
3052 /*      cmpb    (sp),$'+ */
3053 /*      beq     1f */
3054 /*      mov     $'e,-(sp) */
3055 /*      jsr     pc,error */
3056 /* 1: */
3057 /*      movb    r4,(sp) */
3058 /*      br      advanc */
3059
3060
3061 void binop() {
3062         if (optoken != TPLUS)
3063                 error('e');
3064         optoken = token;
3065 }
3066
3067 /* exnum1: */
3068 /*      mov     numval,r1 */
3069 /*      br      1f */
3070
3071 /* exnum: */
3072 /*      jsr     pc,getw */
3073 /*      mov     r4,r1 */
3074 /* 1: */
3075 /*      mov     $1,r0 */
3076 /*      br      oprand */
3077
3078 void exnum1() {
3079 /* printf("exnum1() numval = 0%o\n", numval); */
3080         rightvalue = numval;
3081         rightflags = FABS;
3082         oprand();
3083 }
3084
3085 void exnum() {
3086         p1getw();
3087 /* printf("exnum() token = 0%o\n", rightvalue); */
3088         rightvalue = token;
3089         rightflags = FABS;
3090         oprand();
3091 }
3092
3093 /* brack: */
3094 /*      mov     r2,-(sp) */
3095 /*      mov     r3,-(sp) */
3096 /*      jsr     pc,readop */
3097 /*      jsr     pc,expres1 */
3098 /*      cmp     r4,$'] */
3099 /*      beq     1f */
3100 /*      mov     $'],-(sp) */
3101 /*      jsr     pc,error */
3102 /* 1: */
3103 /*      mov     r3,r0 */
3104 /*      mov     r2,r1 */
3105 /*      mov     (sp)+,r3 */
3106 /*      mov     (sp)+,r2 */
3107
3108 void brack() {
3109         int tempvalue;
3110         int tempflags;
3111         int temptoken;
3112
3113         tempvalue = leftvalue;
3114         tempflags = leftflags;
3115         temptoken = optoken;
3116         readop();
3117         expres1();
3118         if (token != TRBRACK)
3119                 error(']');
3120         rightflags = leftflags;
3121         rightvalue = leftvalue;
3122         leftflags = tempflags;
3123         leftvalue = tempvalue;
3124         optoken = temptoken;
3125         oprand();
3126 }
3127
3128 /* oprand: */
3129 /*      mov     $exsw2,r5 */
3130 /* 1: */
3131 /*      cmp     (sp),(r5)+ */
3132 /*      beq     1f */
3133 /*      tst     (r5)+ */
3134 /*      bne     1b */
3135 /*      br      eoprnd */
3136 /* 1: */
3137 /*      jmp     *(r5) */
3138
3139
3140 void oprand() {
3141         opfound = 1;
3142         switch (optoken) {
3143         default:
3144                 eoprnd();
3145                 return;
3146
3147 /*      .data */
3148 /* exsw2: */
3149 /*      '+; exadd */
3150
3151         case TPLUS:
3152                 exadd();
3153                 return;
3154
3155 /*      '-; exsub */
3156
3157         case TMIN:
3158                 exsub();
3159                 return;
3160
3161 /*      '*; exmul */
3162
3163         case TSTAR:
3164                 exmul();
3165                 return;
3166
3167 /*      '/; exdiv */
3168
3169         case TSLASH:
3170                 exdiv();
3171                 return;
3172
3173 /*      037; exor */
3174
3175         case TOR:
3176                 exor();
3177                 return;
3178
3179 /*      '&; exand */
3180
3181         case TAND:
3182                 exand();
3183                 return;
3184
3185 /*      035;exlsh */
3186
3187         case TLSH:
3188                 exlsh();
3189                 return;
3190
3191 /*      036;exrsh */
3192
3193         case TRSH:
3194                 exrsh();
3195                 return;
3196
3197 /*      '%; exmod */
3198
3199         case TMOD:
3200                 exmod();
3201                 return;
3202
3203 /*      '^; excmbin */
3204
3205         case TCARET:
3206                 excmbin();
3207                 return;
3208
3209 /*      '!; exnot */
3210
3211         case TNOT:
3212                 exnot();
3213                 return;
3214
3215 /*      200;  0 */
3216 /*      .text */
3217
3218         }
3219 }
3220
3221 /* excmbin: */
3222 /*      mov     r0,r3 */
3223 /*      br      eoprnd */
3224
3225 void excmbin() {
3226         leftflags = rightflags;
3227         eoprnd();
3228 }
3229
3230 /* exrsh: */
3231 /*      neg     r1 */
3232 /*      beq     exlsh */
3233 /*      inc     r1 */
3234 /*      clc */
3235 /*      ror     r2 */
3236 /* exlsh: */
3237 /*      mov     $relte2,r5 */
3238 /*      jsr     pc,combin */
3239 /*      ash     r1,r2 */
3240 /*      br      eoprnd */
3241
3242
3243 void exrsh() {
3244         combin(relte2);
3245         leftvalue = ((unsigned int)leftvalue & 0177777) >> rightvalue;
3246         eoprnd();
3247 }
3248
3249 void exlsh() {
3250         combin(relte2);
3251         leftvalue <<= rightvalue;
3252         eoprnd();
3253 }
3254
3255 /* exmod: */
3256 /*      mov     $relte2,r5 */
3257 /*      jsr     pc,combin */
3258 /*      mov     r3,r0 */
3259 /*      mov     r2,r3 */
3260 /*      clr     r2 */
3261 /*      div     r1,r2 */
3262 /*      mov     r3,r2 */
3263 /*      mov     r0,r3 */
3264 /*      br      eoprnd */
3265
3266 void exmod() {
3267         int temp;
3268
3269         combin(relte2);
3270         temp = rightvalue & 0177777;
3271         if (temp)
3272                 leftvalue = (leftvalue & 0177777) % temp;
3273         else {
3274                 error('0'); /* a nick innovation */
3275                 leftvalue = 0;
3276         }
3277         eoprnd();
3278 }
3279
3280 /* exadd: */
3281 /*      mov     $reltp2,r5 */
3282 /*      jsr     pc,combin */
3283 /*      add     r1,r2 */
3284 /*      br      eoprnd */
3285
3286
3287 void exadd() {
3288         combin(reltp2);
3289         leftvalue += rightvalue;
3290         eoprnd();
3291 }
3292
3293 /* exsub: */
3294 /*      mov     $reltm2,r5 */
3295 /*      jsr     pc,combin */
3296 /*      sub     r1,r2 */
3297 /*      br      eoprnd */
3298
3299 void exsub() {
3300         combin(reltm2);
3301         leftvalue -= rightvalue;
3302         eoprnd();
3303 }
3304
3305 /* exand: */
3306 /*      mov     $relte2,r5 */
3307 /*      jsr     pc,combin */
3308 /*      com     r1 */
3309 /*      bic     r1,r2 */
3310 /*      br      eoprnd */
3311
3312 void exand() {
3313         combin(relte2);
3314         leftvalue &= rightvalue;
3315         eoprnd();
3316 }
3317
3318 /* exor: */
3319 /*      mov     $relte2,r5 */
3320 /*      jsr     pc,combin */
3321 /*      bis     r1,r2 */
3322 /*      br      eoprnd */
3323
3324 void exor() {
3325         combin(relte2);
3326         leftvalue |= rightvalue;
3327         eoprnd();
3328 }
3329
3330 /* exmul: */
3331 /*      mov     $relte2,r5 */
3332 /*      jsr     pc,combin */
3333 /*      mul     r2,r1 */
3334 /*      mov     r1,r2 */
3335 /*      br      eoprnd */
3336
3337 void exmul() {
3338         combin(relte2);
3339         leftvalue *= rightvalue;
3340         eoprnd();
3341 }
3342
3343 /* exdiv: */
3344 /*      mov     $relte2,r5 */
3345 /*      jsr     pc,combin */
3346 /*      mov     r3,r0 */
3347 /*      mov     r2,r3 */
3348 /*      clr     r2 */
3349 /*      div     r1,r2 */
3350 /*      mov     r0,r3 */
3351 /*      br      eoprnd */
3352
3353 void exdiv() {
3354         int temp;
3355
3356         combin(relte2);
3357         temp = rightvalue & 0177777;
3358         if (temp)
3359                 leftvalue = (leftvalue & 0177777) / temp;
3360         else {
3361                 error('0'); /* a nick innovation */
3362                 leftvalue = 0;
3363         }
3364         eoprnd();
3365 }
3366
3367 /* exnot: */
3368 /*      mov     $relte2,r5 */
3369 /*      jsr     pc,combin */
3370 /*      com     r1 */
3371 /*      add     r1,r2 */
3372 /*      br      eoprnd */
3373
3374 void exnot() {
3375         combin(relte2);
3376         leftvalue += ~rightvalue;
3377         eoprnd();
3378 }
3379
3380 /* eoprnd: */
3381 /*      mov     $'+,(sp) */
3382 /*      jmp     advanc */
3383
3384 void eoprnd() {
3385         optoken = TPLUS;
3386 }
3387
3388 /* combin: */
3389 /*      tst     passno */
3390 /*      bne     combin1 */
3391
3392 void combin(table) char *table; {
3393         int global;
3394         int flags;
3395
3396         if (passno == 0) {
3397
3398 /*      mov     r0,-(sp) */
3399 /*      bis     r3,(sp) */
3400 /*      bic     $!40,(sp) */
3401 /*      bic     $!37,r0 */
3402 /*      bic     $!37,r3 */
3403 /*      cmp     r0,r3 */
3404 /*      ble     1f */
3405 /*      mov     r0,-(sp) */
3406 /*      mov     r3,r0 */
3407 /*      mov     (sp)+,r3 */
3408 /* 1: */
3409
3410                 global = (rightflags | leftflags) & FGLOBAL;
3411                 rightflags &= 037;
3412                 leftflags &= 037;
3413                 if (rightflags > leftflags) {
3414                         flags = rightflags;
3415                         rightflags = leftflags;
3416                         leftflags = flags;
3417                 }
3418
3419 /*      tst     r0 */
3420 /*      beq     1f */
3421 /*      cmp     r5,$reltm2 */
3422 /*      bne     2f */
3423 /*      cmp     r0,r3 */
3424 /*      bne     2f */
3425 /*      mov     $1,r3 */
3426 /*      br      2f */
3427 /* 1: */
3428 /*      clr     r3 */
3429 /* 2: */
3430 /*      bis     (sp)+,r3 */
3431 /*      rts     pc */
3432
3433                 if (rightflags) {
3434                         if (table == reltm2 && rightflags == leftflags)
3435                                 leftflags = TABS;
3436                 }
3437                 else {
3438                         leftflags = 0;
3439                 }
3440                 leftflags |= global;
3441         }
3442
3443 /* combin1: */
3444 /*      mov     r1,-(sp) */
3445 /*      clr     maxtyp */
3446
3447         else {
3448                 maxtyp = 0;
3449
3450 /*      jsr     pc,maprel */
3451 /*      mov     r0,r1 */
3452 /*      mul     $6,r1 */
3453 /*      mov     r3,r0 */
3454 /*      jsr     pc,maprel */
3455 /*      add     r5,r0 */
3456 /*      add     r1,r0 */
3457 /*      movb    (r0),r3 */
3458
3459                 leftflags = table[maprel(rightflags) * 6 + maprel(leftflags)];
3460
3461 /*      bpl     1f */
3462 /*      cmp     r3,$-1 */
3463 /*      beq     2f */
3464 /*      mov     $'r,-(sp) */
3465 /*      jsr     pc,error */
3466 /* 2: */
3467 /*      mov     maxtyp,r3 */
3468 /* 1: */
3469
3470                 if (leftflags < 0) {
3471                         if (leftflags != M)
3472                                 error('r');
3473                         leftflags = maxtyp;
3474                 }
3475
3476 /*      mov     (sp)+,r1 */
3477 /*      rts     pc */
3478
3479         }
3480 }
3481
3482 /* maprel: */
3483 /*      cmp     r0,$40 */
3484 /*      bne     1f */
3485 /*      mov     $5,r0 */
3486 /*      rts     pc */
3487 /* 1: */
3488 /*      bic     $!37,r0 */
3489 /*      cmp     r0,maxtyp */
3490 /*      blos    1f */
3491 /*      mov     r0,maxtyp */
3492 /* 1: */
3493 /*      cmp     r0,$5 */
3494 /*      blo     1f */
3495 /*      mov     $1,r0 */
3496 /* 1: */
3497 /*      rts     pc */
3498
3499 int maprel(flags) int flags; {
3500         if (flags == FGLOBAL)
3501                 return 5;
3502         flags &= 037;
3503         if (maxtyp < flags)
3504                 maxtyp = flags;
3505         if (flags > FBSS)
3506                 flags = FABS;
3507         return flags;
3508 }
3509
3510 /*      .data */
3511 /* X = -2 */
3512 /* M = -1 */
3513 /* reltp2: */
3514 /*      .byte 0, 0, 0, 0, 0, 0 */
3515 /*      .byte 0, M, 2, 3, 4,40 */
3516 /*      .byte 0, 2, X, X, X, X */
3517 /*      .byte 0, 3, X, X, X, X */
3518 /*      .byte 0, 4, X, X, X, X */
3519 /*      .byte 0,40, X, X, X, X */
3520
3521 char reltp2[36] = {
3522         0,  0, 0, 0, 0,  0,
3523         0,  M, 2, 3, 4,040,
3524         0,  2, X, X, X,  X,
3525         0,  3, X, X, X,  X,
3526         0,  4, X, X, X,  X,
3527         0,040, X, X, X,  X
3528 };
3529
3530 /* reltm2: */
3531 /*      .byte 0, 0, 0, 0, 0, 0 */
3532 /*      .byte 0, M, 2, 3, 4,40 */
3533 /*      .byte 0, X, 1, X, X, X */
3534 /*      .byte 0, X, X, 1, X, X */
3535 /*      .byte 0, X, X, X, 1, X */
3536 /*      .byte 0, X, X, X, X, X */
3537
3538 char reltm2[36] = {
3539         0, 0, 0, 0, 0,  0,
3540         0, M, 2, 3, 4,040,
3541         0, X, 1, X, X,  X,
3542         0, X, X, 1, X,  X,
3543         0, X, X, X, 1,  X,
3544         0, X, X, X, X,  X
3545 };
3546
3547 /* relte2: */
3548 /*      .byte 0, 0, 0, 0, 0, 0 */
3549 /*      .byte 0, M, X, X, X, X */
3550 /*      .byte 0, X, X, X, X, X */
3551 /*      .byte 0, X, X, X, X, X */
3552 /*      .byte 0, X, X, X, X, X */
3553 /*      .byte 0, X, X, X, X, X */
3554
3555 char relte2[36] = {
3556         0, 0, 0, 0, 0, 0,
3557         0, M, X, X, X, X,
3558         0, X, X, X, X, X,
3559         0, X, X, X, X, X,
3560         0, X, X, X, X, X,
3561         0, X, X, X, X, X
3562 };
3563
3564 /* qnl: <?\n> */
3565 /* a.out:       <a.out\0> */
3566 /*      .even */
3567 /* a.outp:      a.out */
3568
3569 char *a_outp = "a.out";
3570
3571 /* obufp:       outbuf */
3572
3573 short *obufp = outbuf;
3574
3575 /* passno: -1 */
3576
3577 int passno = -1;
3578
3579 /* outmod:      0777 */
3580
3581 int outmod = 0777;
3582
3583 /* tseekp:      txtseek */
3584
3585 off_t *tseekp = seek;
3586
3587 /* rseekp:      trelseek */
3588
3589 off_t *rseekp = seek + 3;
3590
3591 /* txtmagic: */
3592 /*      br      .+20 */
3593 /* txtsiz:      .=.+2 */
3594 /* datsiz:      .=.+2 */
3595 /* bsssiz:      .=.+2 */
3596 /* symsiz:      .=.+2 */
3597 /*      .=.+6 */
3598
3599 int siz[4];
3600
3601 /* txtseek:0; 20 */
3602 /* datseek:.=.+4 */
3603 /*      .=.+4 */
3604 /* trelseek:.=.+4 */
3605 /* drelseek:.=.+4 */
3606 /*      .=.+4 */
3607 /* symseek:.=.+4 */
3608
3609 off_t seek[7];
3610
3611 /*      .bss */
3612 /* brlen        = 1024. */
3613 /* brtab:       .=.+[brlen\/8.] */
3614
3615 char brtab[brlen / 8];
3616
3617 /* brtabp:      .=.+2 */
3618
3619 int brtabp;
3620
3621 /* brdelt:      .=.+2 */
3622
3623 int brdelt;
3624
3625 /* fbbufp: .=.+2 */
3626
3627 struct symbol **fbbufp;
3628
3629 /* defund:      .=.+2 */
3630
3631 int defund;
3632
3633 /* datbase:.=.+2 */
3634 /* bssbase:.=.+2 */
3635
3636 int base[3];
3637
3638 /* ibufc:       .=.+2 */
3639
3640 int ibufc;
3641
3642 /* overlaid: .=.+2 */
3643
3644 int overlaid;
3645
3646 /* adrbuf:      .=.+12. */
3647
3648 intptr_t adrbuf[6];
3649
3650 /* xsymbol:.=.+2 */
3651
3652 struct symbol *xsymbol;
3653
3654 /* errflg:      .=.+2 */
3655
3656 int errflg;
3657
3658 /* argb:        .=.+22. */
3659
3660 char argb[22];
3661
3662 #if 0
3663 /* numval:      .=.+2 */
3664
3665 int numval;
3666 #endif
3667
3668 /* maxtyp:      .=.+2 */
3669
3670 int maxtyp;
3671
3672 /* ibufp:       .=.+2 */
3673
3674 short *ibufp;
3675 char *p0ibufp;
3676
3677 /* txtp:        .=.+8. */
3678 /*      .=.+1024. */
3679
3680 struct stream txtp;
3681
3682 /* relp:        .=.+8. */
3683 /* outbuf: */
3684 /*      .=.+1024. */
3685
3686 struct stream relp;
3687
3688 /* swapf:       .=.+2 */
3689
3690 int swapf;
3691
3692 /* rlimit:      .=.+2 */
3693
3694 int rlimit;
3695
3696 /* endtable:.=.+2 */
3697
3698 struct symbol **endtable;
3699
3700 /* totalsz:                     / string table length */
3701 /*      .=.+4 */
3702 /*      .text */
3703
3704 off_t totalsz;
3705