Initial commit, PDP-11 assembler from 2.11BSD, translated to C, with list/xlat
authorNick Downing <nick@ndcode.org>
Thu, 11 Aug 2022 02:26:02 +0000 (12:26 +1000)
committerNick Downing <nick@ndcode.org>
Thu, 11 Aug 2022 02:26:02 +0000 (12:26 +1000)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
as0.c [new file with mode: 0644]
as0.h [new file with mode: 0644]
as2.c [new file with mode: 0644]
as2.h [new file with mode: 0644]
krcompat.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..fd9e3ca
--- /dev/null
@@ -0,0 +1,4 @@
+*.o
+/as
+/aslist
+/asxlat
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..8aac95a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
+LD=ld
+INSTALL=install
+#
+# makefile for as
+#
+
+#AS=   /bin/as
+#SEPFLAG= -i -X
+#SEPFLAG=-i
+CFLAGS=-m32 -g
+
+all: as aslist asxlat
+
+as: as0.o as2.o
+#      ${LD} ${SEPFLAG} -o $@ ${STAGEDIR}/lib/crt0.o as0.o as2.o -lc
+#      ${CC} ${SEPFLAG} -o $@ as0.o as2.o
+       ${CC} ${CFLAGS} -o $@ as0.o as2.o
+
+as0.o: as0.c as0.h as2.h
+as2.o: as2.c as0.h as2.h
+
+aslist: aslist0.o aslist2.o
+       ${CC} ${CFLAGS} -o $@ aslist0.o aslist2.o
+
+aslist0.o: as0.c as0.h as2.h
+       ${CC} ${CFLAGS} -DLISTING -o $@ -c $<
+
+aslist2.o: as2.c as0.h as2.h
+       ${CC} ${CFLAGS} -DLISTING -o $@ -c $<
+
+asxlat: asxlat0.o asxlat2.o
+       ${CC} ${CFLAGS} -o $@ asxlat0.o asxlat2.o
+
+asxlat0.o: as0.c as0.h as2.h
+       ${CC} ${CFLAGS} -DTRANSLATE -o $@ -c $<
+
+asxlat2.o: as2.c as0.h as2.h
+       ${CC} ${CFLAGS} -DTRANSLATE -o $@ -c $<
+
+install: all
+       ${INSTALL} -s as aslist asxlat ${DESTDIR}/bin
+
+clean:
+       rm -f *.o a.out as aslist asxlat core errs
diff --git a/as0.c b/as0.c
new file mode 100644 (file)
index 0000000..2938e27
--- /dev/null
+++ b/as0.c
@@ -0,0 +1,4099 @@
+/* as0.c */
+
+#include <stdio.h> /* temp */
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#ifdef pdp11
+typedef int intptr_t;
+#endif
+#include "as0.h"
+#include "as2.h"
+
+/*     .globl  _main, _write, _close, _execl, __exit, _brk */
+/*     .globl  _read, _signal, _stat, _open, _mkstemp, _calloc, _realloc */
+
+/*     .globl  error, errore, errora, checkeos, pass1, aexit, argb */
+/*     .globl  overlaid, defund, a.outp, errflg, passno, filerr, outmod */
+/*     .globl  wrterr, argb, hshsiz, dot, dotdot, savdot, ch, outbuf */
+/*     .globl  line, savop, inbuf, fbptr, fbtbl, symnum, hshtab, symblk */
+/*     .globl  symleft, dotrel, symtab, fin, fout, curfb, nxtfb, ibufp */
+/*     .globl  ibufc, a.tmp1, usymtab, SYMENTSZ, SYMBLKSZ, PSTENTSZ */
+/*     .globl  obufp, Newsym, symbol,csv */
+
+/* This assembler supports _both_ the old style object files (with */
+/* fixed 8 character symbols) and the new style (with a strings table). */
+/* The variable 'Newsym' defined below specifies which format will be */
+/* emitted, if the value is '0' the old style is output, if non-zero */
+/* then the new 'string table' format is output. */
+
+/* The old style on disc symbol table entries looked like this: */
+/*   struct symbol */
+/*     { */
+/*     char name[8]; */
+/*     short type; */
+/*     short value; */
+/*     }; */
+
+/* The new style of on disc symbol table entry looks like: */
+/*   struct symbol */
+/*     { */
+/*     off_t offset_in_string_table; */
+/*     short type; */
+/*     short value; */
+/*     }; */
+
+/*     .data */
+/* Newsym:     1 */
+/*     .text */
+
+char Newsym = 1;
+
+struct symbol *pdot = symtab;
+struct symbol *pdotdot = symtab + 1;
+intptr_t numbertoken; /* r0 */
+int numbervalue; /* r0 */
+int endflag; /* r1 */
+int indirect; /* r0 */
+int optoken; /* (sp) */
+int rightflags; /* r0 */
+int rightvalue; /* r1 */
+int leftvalue; /* r2 */
+int leftflags; /* r3 */
+intptr_t token; /* r4 */
+
+#ifdef TRANSLATE
+static char xbuf[0x1000];
+static char *xbufp = xbuf, *xwhitep, *xstartp;
+static char *xstartpsave, *xbufpsave;
+static size_t xsavestartn, xsavebufn;
+static char xsave[0x1000];
+static size_t xrestn;
+static char xrest[0x1000];
+static int xlab, xlabnext;
+static int xlabb[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+static int xlabf[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+#endif
+
+/* PDP-11 assembler */
+/* _main: */
+/*     jsr     r5,csv */
+
+int main(argc, argv) int argc; char **argv; {
+       sig_t oldsig;
+       char *p;
+       struct symbol *psymbol;
+       int hash, c;
+       struct symbol **ppsymbol;
+
+/*     mov     $1,-(sp)                / signal(SIGINT, SIG_IGN) */
+/*     mov     $2,-(sp) */
+/*     jsr     pc,_signal */
+/*     cmp     (sp)+,(sp)+ */
+/*     ror     r0 */
+/*     bcs     1f */
+
+/*     mov     $aexit,-(sp)            / signal(SIGINT, aexit) */
+/*     mov     $2,-(sp) */
+/*     jsr     pc,_signal */
+/*     cmp     (sp)+,(sp)+ */
+
+       oldsig = signal(SIGINT, SIG_IGN);
+       if (oldsig != SIG_IGN) /*((int)oldsig & 1) == 0)*/
+               signal(SIGINT, (sig_t)aexit);
+
+/* 1: */
+/*     mov     4(r5),r0                / argc */
+/*     mov     6(r5),curarg            / argv */
+
+       curarg = argv;
+       nargs = argc;
+       while (nargs) {
+
+/* 9: */
+/*     dec     r0                      / argc-- */
+/*     add     $2,curarg               / argv++ */
+
+               curarg++;
+               nargs--;
+               if (nargs == 0)
+                       break;
+
+/* 1: */
+/*     mov     *curarg,r1 */
+
+               p = *curarg;
+
+/*     cmpb    (r1)+,$'- */
+/*     bne     1f */
+
+               if (*p++ != '-')
+                       break;
+
+/*     cmpb    (r1),$'-                / is this "--"? */
+/*     bne     8f                      / no - br */
+/*     tstb    1(r1)                   / check for null terminator */
+/*     beq     1f                      / got it, the "--" means read 'stdin' */
+
+               if (*p == '-' && p[1] == 0)
+                       break;
+
+/* 8: */
+/*     add     $2,curarg               / argv++ */
+/*     dec     r0                      / argc-- */
+/*     cmpb    (r1),$'u */
+/*     beq     3f */
+/*     cmpb    (r1), $'V */
+/*     bne     2f */
+/*     inc     overlaid */
+/*     br      1b */
+/* 2: */
+
+               if (*p == 'V') {
+                       overlaid = 1;
+                       continue;
+               }
+
+/*     tstb    (r1) */
+/*     bne     2f */
+/* 3: */
+/*     mov     $40,defund */
+/*     br      1b */
+/* 2: */
+
+               if (*p == 'u' || *p == 0) {
+                       defund = FGLOBAL;
+                       continue;
+               }
+
+/*     cmpb    (r1),$'o */
+/*     bne     1f */
+/*     mov     *curarg,a.outp */
+/*     br      9b */
+/* 1: */
+
+               if (*p == 'o') {
+                       curarg++;
+                       a_outp = *curarg;
+                       nargs--;
+                       continue;
+               }
+               break;
+       }
+
+/* The new object file format puts a ceiling of 32 characters on symbols. */
+/* If it is desired to raise this limit all that need be done is increase */
+/* the same ceiling in the C compiler and linker (ld). */
+
+/*     tst     Newsym */
+/*     beq     1f */
+/*     movb    $32.,Ncps */
+/* 1: */
+
+       if (Newsym)
+               Ncps = 32;
+
+/*     mov     r0,nargs                / # of remaining args */
+/*     bne     8f                      / br if any left */
+/*     inc     nargs                   / fake at least one arg */
+/*     mov     $dash, curarg           / of '-' so we read stdin */
+/* 8: */
+
+       if (nargs == 0) {
+               nargs = 1;
+               curarg = &dash;
+       }
+
+/*     mov     $a.tmp1,-(sp) */
+/*     jsr     pc,_mkstemp             / fout = mkstemp(a.tmp1); */
+/*     tst     (sp)+ */
+/*     mov     r0,fout */
+/*     bmi     oops */
+
+       fout = mkstemp(a_tmp1);
+       if (fout < 0)
+               oops();
+
+/* the symbol table is a single linked list of dynamically allocated */
+/* 'SYMBLKSZ' byte blocks.  Allocate the first one now. */
+/*     mov     $SYMBLKSZ+2,-(sp)       / symblk = calloc(1, SYMBLKSZ+2) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_calloc */
+/*     cmp     (sp)+,(sp)+ */
+/*     mov     r0,symblk */
+/*     mov     r0,usymtab              / pointer to first block */
+/*     tst     (r0)+                   / skip link word */
+/*     mov     r0,symend               / current end in block */
+/*     mov     $SYMBLKSZ,symleft       / number of bytes left in block */
+
+       symblk = (struct symblk *)calloc(1, sizeof(struct symblk));
+       if (symblk == NULL)
+               nomem(); /* don't use oops(), want to delete temp file */
+       usymtab = symblk;
+       symend = symblk->data;
+       symleft = SYMBLKSZ;
+
+/* The string portion of symbol table entries is now allocated dynamically. */
+/* We allocate the strings in 1kb chunks to cut down the number of times */
+/* the string table needs to be extended (besides, long variable names are */
+/* coming real soon now). */
+
+/* NOTE: the string blocks are linked together for debugging purposes only, */
+/* nothing depends on the link. */
+
+/*     mov     $STRBLKSZ+2,-(sp) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_calloc              / strblk = calloc(1, STRBLKSZ+2) */
+/*     / check for failure??? */
+/*     cmp     (sp)+,(sp)+ */
+/*     mov     r0,strblk               / save pointer to string block */
+/*     tst     (r0)+                   / skip link word */
+/*     mov     r0,strend               / set available string pointer */
+/*     mov     $STRBLKSZ,strleft       / set amount left in block */
+
+       strblk = (struct strblk *)calloc(1, sizeof(struct strblk));
+       if (strblk == NULL)
+               nomem(); /* don't use oops(), want to delete temp file */
+       strend = strblk->data;
+       strleft = STRBLKSZ;
+
+/* the hash table is now dynamically allocated so that it can be */
+/* reused in pass 2 and re-alloced if necessary. */
+/*     mov     $2,-(sp)                / hshtab = calloc($hshsiz, sizeof(int)) */
+/*     mov     $hshsiz,-(sp) */
+/*     jsr     pc,_calloc */
+/*     cmp     (sp)+,(sp)+ */
+/*     mov     r0, hshtab */
+
+       hshtab = (struct symbol **)calloc(hshsiz, sizeof(struct symbol *));
+       if (hshtab == NULL)
+               nomem(); /* don't use oops(), want to delete temp file */
+
+/*     mov     $symtab,r1 */
+
+       psymbol = symtab;
+       do {
+
+/* 1: */
+/*     clr     r3 */
+/*     mov     (r1),r2                 / pointer to PST symbol's string */
+
+               hash = 0;
+               p = psymbol->name;
+
+/* 2: */
+/*     movb    (r2)+,r4 */
+/*     beq     2f */
+/*     add     r4,r3 */
+/*     swab    r3 */
+/*     br      2b */
+/* 2: */
+
+               while (1) {
+                       c = *p++;
+                       if (c == 0)
+                               break;
+                       hash += c;
+                       hash = ((hash >> 8) & 0377) | ((hash & 0377) << 8);
+               }
+
+/*     clr     r2 */
+/*     div     $hshsiz,r2 */
+/*     ashc    $1,r2 */
+/*     add     hshtab,r3 */
+
+               ppsymbol = hshtab + (hash % hshsiz);
+               hash /= hshsiz;
+
+/* 4: */
+/*     sub     r2,r3 */
+/*     cmp     r3,hshtab */
+/*     bhi     3f */
+/*     add     $2*hshsiz,r3 */
+/* 3: */
+/*     tst     -(r3) */
+/*     bne     4b */
+/*     mov     r1,(r3) */
+/*     add     $PSTENTSZ,r1 */
+/*     cmp     r1,$ebsymtab */
+/*     blo     1b */
+
+               do {
+                       ppsymbol -= hash;
+                       if (ppsymbol <= hshtab)
+                               ppsymbol += hshsiz;
+               } while (*--ppsymbol);
+               *ppsymbol = psymbol++;
+       } while (psymbol < symtab + ebsymtab);
+
+/* perform pass 0 processing */
+/*     jsr     pc,pass0 */
+
+#ifdef LISTING
+       printf("pass 0\n");
+#endif
+       pass0();
+#ifdef TRANSLATE
+ write(1, xbuf, xbufp - xbuf);
+#endif
+
+/* flush the intermediate object file */
+/*     mov     $1024.,-(sp)            / write(fout, outbuf, 1024) */
+/*     mov     $outbuf,-(sp) */
+/*     mov     fout,-(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+
+       write(fout, outbuf, 512 * sizeof(short));
+
+/*     tst     errflg                  / any errors? */
+/*     beq     1f                      / yes - br */
+/*     jsr     pc,aexit */
+/* not reached */
+/* 1: */
+
+       if (errflg)
+               aexit();
+
+/*     inc     passno                  / go from -1 to 0 */
+/*     clr     line                    / reset line number */
+/*     jmp     pass1                   / pass1 does both passes 1, 2, exit */
+
+#ifdef LISTING
+       printf("pass 1\n");
+#endif
+       passno++;
+       line = 0;
+       pass1();
+}
+
+/* oops: */
+/*     mov     $9f-8f,-(sp)            / write(fileno(stderr),8f,strlen()) */
+/*     mov     $8f,-(sp) */
+/*     mov     $2,-(sp) */
+/*     jsr     pc,_write */
+/*     mov     $2,(sp) */
+/*     jsr     pc,__exit */
+/*     .data */
+/* 8: */
+/*     <as: can't create tmpfile\n> */
+/* 9: */
+/*     .even */
+/*     .text */
+
+int oops() {
+       write(2, "as: can't create tmpfile\n", 25);
+       exit(2);
+}
+
+void nomem() {
+       write(2, "as: out of memory\n", 18);
+       aexit();
+}
+
+/* error: */
+
+void error(code) int code; {
+       int i, j;
+       static char report[] = "f xxxx\n";
+
+/*     tst     passno                  / on pass1,2 ? */
+/*     bpl     errorp2 */
+
+/* putchar('\n'); */
+ fflush(stdout);
+       if (passno < 0) {
+
+/*     inc     errflg */
+
+               errflg = 1;
+
+/*     mov     r0,-(sp) */
+/*     mov     r1,-(sp) */
+/*     mov     r5,r0 */
+/*     tst     *curarg */
+/*     beq     1f */
+/*     mov     r0,-(sp) */
+/*     mov     *curarg,-(sp) */
+/*     clr     *curarg */
+/*     jsr     pc,filerr */
+/*     tst     (sp)+ */
+/*     mov     (sp)+,r0 */
+/* 1: */
+
+               if (*curarg) {
+                       filerr(*curarg);
+                       *curarg = NULL;
+               }
+
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+/*     jsr     pc,errcmn */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+/*     mov     (sp)+,r1 */
+/*     mov     (sp)+,r0 */
+/*     rts     pc */
+
+       }
+       else {
+
+/* errorp2: */
+/*     mov     pc,errflg */
+/*     mov     $666,outmod             / make nonexecutable */
+
+               errflg = 2;
+               outmod = 0666;
+
+/*     mov     r3,-(sp) */
+/*     mov     r2,-(sp) */
+/*     mov     r1,-(sp) */
+/*     mov     r0,-(sp) */
+/*     tst     -(sp)                   / write(1, argb, strlen(argb)) */
+/*     mov     $argb,-(sp) */
+/*     mov     $1,-(sp) */
+/*     mov     $argb,r1 */
+/*     clr     r0 */
+/* 1: */
+/*     tstb    (r1)+ */
+/*     beq     2f */
+/*     inc     r0 */
+/*     br      1b */
+/* 2: */
+/*     mov     r0,4(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+
+               if (*argb) {
+                       write(1, argb, strlen(argb));
+                       *argb = 0; /* a nick innovation */
+               }
+
+/*     movb    12(sp),r0 */
+/*     jsr     pc,errcmn */
+/*     mov     (sp)+,r0 */
+/*     mov     (sp)+,r1 */
+/*     mov     (sp)+,r2 */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,(sp) */
+/*     rts     pc */
+
+       }
+
+/* errcmn: */
+/*     mov     line,r3 */
+/*     movb    r0,9f */
+
+       j = line;
+       *report = code;
+
+/*     mov     $9f+6,r0 */
+/*     mov     $4,r1 */
+/* 2: */
+/*     clr     r2 */
+/*     div     $10.,r2 */
+/*     add     $'0,r3 */
+/*     movb    r3,-(r0) */
+/*     mov     r2,r3 */
+/*     sob     r1,2b */
+
+       for (i = 0; i < 4; i++) {
+               report[5 - i] = (j % 10) + '0';
+               j /= 10;
+       }
+
+/*     mov     $7,-(sp)                / write(1, 9f, 7) */
+/*     mov     $9f,-(sp) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+
+       write (1, report, 7);
+
+/*     rts     pc */
+
+}
+
+/*     .data */
+/* 9:  <f xxxx\n> */
+/*     .even */
+/*     .text */
+
+/* p0putw: */
+
+void p0putw(word) int word; {
+
+/*     tst     ifflg */
+/*     beq     1f */
+/*     cmp     r4,$'\n */
+/*     bne     2f */
+/* 1: */
+
+/* printf("p0putw(0%o)\n", word); */
+       if (ifflg == 0 || word == TNEWLINE)
+               {
+
+/*     mov     r4,*obufp */
+/*     add     $2,obufp */
+/*     cmp     obufp,$outbuf+1024. */
+/*     blo     2f */
+/*     mov     $outbuf,obufp */
+
+               *obufp++ = word;
+               if (obufp >= outbuf + 512) {
+                       obufp = outbuf;
+
+/*     mov     r1,-(sp)                / protect r1 from library */
+/*     mov     $1024.,-(sp)            / write(fout, outbuf, 1024) */
+/*     mov     $outbuf,-(sp) */
+/*     mov     fout,-(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+/*     mov     (sp)+,r1 */
+/*     tst     r0 */
+/*     bpl     2f */
+/*     jmp     wrterr */
+
+                       if (write(fout, outbuf, 512 * sizeof(short)) < 0)
+                               wrterr();
+               }
+       }
+
+/* 2: */
+/*     rts     pc */
+
+}
+
+/* Pass 0. */
+
+/* pass0: */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,checkeos */
+/*             br 7f */
+
+void pass0() {
+       intptr_t tokensave;
+       struct symbol *psymbol;
+       int label;
+
+       while (1) {
+               p0readop();
+               if (checkeos())
+                       goto ealoop;
+
+/*     tst     ifflg */
+/*     beq     3f */
+/*     cmp     r4,$200 */
+/*     blos    pass0 */
+/*     cmpb    (r4),$21                /if */
+/*     bne     2f */
+/*     inc     ifflg */
+/* 2: */
+/*     cmpb    (r4),$22                /endif */
+/*     bne     pass0 */
+/*     dec     ifflg */
+/*     br      pass0 */
+/* 3: */
+
+               if (ifflg) {
+                       if (token < 0 || token >= TASCII) {
+                               psymbol = (struct symbol *)token;
+                               switch (psymbol->flags) {
+                               case FDOTIF:
+                                       ifflg++;
+                                       break;
+                               case FDOTENDIF:
+                                       ifflg--;
+                                       break;
+                               }
+                       }
+                       continue;
+               }
+
+/*     mov     r4,-(sp) */
+/*     jsr     pc,p0readop */
+/*     cmp     r4,$'= */
+/*     beq     4f */
+/*     cmp     r4,$': */
+/*     beq     1f */
+/*     mov     r4,savop */
+/*     mov     (sp)+,r4 */
+/*     jsr     pc,opline */
+/*     br      ealoop */
+
+               tokensave = token;
+#ifdef TRANSLATE
+ xstartpsave = xstartp;
+ xbufpsave = xbufp;
+#endif
+               p0readop();
+               if (token == TEQUAL)
+                       goto equal;
+               if (token == TCOLON)
+                       goto colon;
+               savop = token;
+#ifdef TRANSLATE
+ xsavestartn = xstartp - xbufpsave;
+ xsavebufn = xbufp - xbufpsave;
+ memcpy(xsave, xbufpsave, xsavebufn);
+#endif
+               token = tokensave;
+#ifdef TRANSLATE
+ xstartp = xstartpsave;
+ xbufp = xbufpsave;
+#endif
+               p0opline();
+               goto ealoop;
+
+/* 1: */
+/*     mov     (sp)+,r4 */
+/*     cmp     r4,$200 */
+/*     bhis    1f */
+/*     cmp     r4,$1                   / digit */
+/*     beq     3f */
+/*     mov     $'x,r5 */
+/*     jsr     pc,error */
+/*     br      pass0 */
+/* 1: */
+
+       colon:
+               if (tokensave >= 0 && tokensave < TASCII) {
+                       if (tokensave != TABS) {
+                               error('x');
+                               continue;
+                       }
+                       goto digit;
+               }
+
+/*     bitb    $37,(r4) */
+/*     beq     1f */
+/*     mov     $'m,r5 */
+/*     jsr     pc,error */
+/* 1: */
+
+               psymbol = (struct symbol *)tokensave;
+               if (psymbol->flags & 037)
+                       error('m');
+
+/*     bisb    dot-2,(r4) */
+/*     mov     dot,2(r4) */
+/*     br      pass0 */
+
+               psymbol->flags |= pdot->flags;
+               psymbol->value = pdot->value;
+               continue;
+
+/* 3: */
+/*     mov     numval,r0 */
+/*     jsr     pc,fbcheck */
+/*     movb    dotrel,curfbr(r0) */
+/*     asl     r0 */
+/*     movb    dotrel,nxtfb */
+/*     mov     dot,nxtfb+2 */
+/*     movb    r0,nxtfb+1 */
+/*     mov     dot,curfb(r0) */
+
+       digit:
+               label = fbcheck(numval);
+               curfbr[label] = pdot->flags;
+               curfb[label] = pdot->value;
+#ifdef TRANSLATE
+ if (xlabf[label] == -1)
+  xlab = xlabnext++;
+ else {
+  xlab = xlabf[label];
+  xlabf[label] = -1;
+ }
+ xlabb[label] = xlab;
+ if (xstartp >= xbuf + 0xff0)
+  abort();
+ xbufp = xstartpsave + sprintf(xstartpsave, "_%d:", xlab);
+#endif
+
+/*     cmp     fbfree,$4               / room for another fb entry? */
+/*     bge     5f                      / yes - br */
+/*     jsr     pc,growfb               / no - grow the table */
+/* 5: */
+               if (fbfree == 0)
+                       growfb();
+
+/*     sub     $4,fbfree               / four bytes less available */
+/*     mov     nxtfb,*fbptr            / store first word */
+/*     add     $2,fbptr                / advance to next */
+/*     mov     nxtfb+2,*fbptr          / store second word */
+/*     add     $2,fbptr                / point to next entry */
+/*     br      pass0 */
+
+               fbfree--;
+               fbptr->name = NULL;
+               fbptr->flags = pdot->flags;
+               fbptr->value = pdot->value;
+               fbptr->number = label;
+               fbptr++;
+               continue;
+
+/* 4: */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     mov     (sp)+,r1 */
+/*     cmp     r1,$200 */
+/*     bhis    1f */
+/*     mov     $'x,r5 */
+/*     jsr     pc,error */
+/* 7: */
+/*     br      ealoop */
+
+       equal:
+               p0readop();
+               p0expres();
+               if (tokensave >= 0 && tokensave < TASCII) {
+                       error('x');
+                       goto ealoop;
+               }
+
+/* 1: */
+/*     cmp     r1,$dotrel */
+/*     bne     2f */
+/*     bic     $40,r3 */
+/*     cmp     r3,dotrel */
+/*     bne     1f */
+/* 2: */
+
+               psymbol = (struct symbol *)tokensave;
+               if (psymbol == pdot) {
+                       leftflags &= ~FGLOBAL;
+/* printf("leftflags 0%o pdot->flags 0%o\n", leftflags, pdot->flags); */
+                       if (leftflags != pdot->flags)
+                               goto doterr;
+#ifdef TRANSLATE
+ xrestn = xbufp - xwhitep;
+ memcpy(xrest, xwhitep, xrestn);
+ if (xstartpsave + xrestn >= xbuf + 0xff0)
+  abort();
+ xbufp = xstartpsave + sprintf(xstartpsave, ".ds\t%d", leftvalue);
+ memcpy(xbufp, xrest, xrestn);
+ xbufp += xrestn;
+#endif
+               }
+
+/*     bicb    $37,(r1) */
+/*     bic     $!37,r3 */
+/*     bne     2f */
+/*     clr     r2 */
+/* 2: */
+
+               psymbol->flags &= ~037;
+               leftflags &= 037;
+               if (leftflags == 0)
+                       leftvalue = 0;
+
+/*     bisb    r3,(r1) */
+/*     mov     r2,2(r1) */
+/*     br      ealoop */
+
+               psymbol->flags |= leftflags;
+               psymbol->value = leftvalue;
+               goto ealoop;
+
+/* 1: */
+/*     mov     $'.,r5 */
+/*     jsr     pc,error */
+/*     movb    $2,dotrel */
+
+       doterr:
+               error('.');
+               pdot->flags = FTEXT;
+
+/* ealoop: */
+/*     cmp     r4,$'; */
+/*     beq     9f */
+/*     cmp     r4,$'\n */
+/*     bne     1f */
+/*     inc     line */
+/*     br      9f */
+/* 1: */
+
+       ealoop:
+/* printf("ealoop token = 0x%08x\n", token); */
+               if (token == TSEMICOLON)
+                       continue;
+               if (token == TNEWLINE) {
+                       line++;
+                       continue;
+               }
+
+/*     cmp     r4,$'\e */
+/*     bne     2f */
+/*     tst     ifflg */
+/*     beq     1f */
+/*     mov     $'x,r5 */
+/*     jsr     pc,error */
+/* 1: */
+/*     rts     pc */
+/* 2: */
+/*     mov     $'x,r5 */
+/*     jsr     pc,error */
+
+               if (token == TENDFILE) {
+                       if (ifflg)
+                               error('x');
+                       break;
+               }
+               error('x');
+
+/* 2: */
+/*     jsr     pc,checkeos */
+/*             br 9f */
+/*     jsr     pc,p0readop */
+/*     br      2b */
+/* 9: */
+/*     jmp     pass0 */
+
+               while (checkeos() == 0)
+                       p0readop();
+       }
+}
+
+/* fbcheck: */
+/*     cmp     r0,$9. */
+/*     bhi     1f */
+/*     rts     pc */
+/* 1: */
+/*     mov     $'f,r5 */
+/*     jsr     pc,error */
+/*     clr     r0 */
+/*     rts     pc */
+
+int fbcheck(label) int label; {
+       if (label < 10)
+               return label;
+       error('f');
+       return 0;
+}
+
+/* the 'fb' table never grows to be large.  In fact all of the assemblies */
+/* of C compiler generated code which were processed by 'c2' never */
+/* produced a table larger than 0 bytes.  So we 'realloc' because */
+/* this is not done enough to matter. */
+
+/* growfb: */
+/*     mov     r1,-(sp)                / save r1 from library */
+/*     add     $256.,fbtblsz           / new size of fb table */
+/*     mov     $256.,fbfree            / number available now */
+
+void growfb() {
+       fbtblsz += 64;
+       fbfree = 64;
+
+/*     mov     fbtblsz,-(sp)           / fbtbl = realloc(fbtbl, fbtblsz); */
+/*     mov     fbtbl,-(sp) */
+/*     bne     1f                      / extending table - br */
+/*     mov     $1,(sp)                 / r0 = calloc(1, fbtblsz); */
+/*     jsr     pc,_calloc */
+/*     br      2f */
+/* 1: */
+/*     jsr     pc,_realloc */
+/* 2: */
+/*     cmp     (sp)+,(sp)+ */
+/*     mov     r0,fbtbl */
+
+       if (fbtbl == NULL)
+               fbtbl = (struct symbol *)calloc(fbtblsz, sizeof(struct symbol));
+       else
+               fbtbl = (struct symbol *)realloc(fbtbl, fbtblsz * sizeof(struct symbol));
+
+/*     bne     1f */
+/*     iot                             / Can never happen (I hope) */
+/* 1: */
+
+       if (fbtbl == NULL)
+               nomem();
+
+/*     add     fbtblsz,r0              / fbptr starts 256 bytes from */
+/*     sub     $256.,r0                / end of new region */
+/*     mov     r0,fbptr */
+/*     mov     (sp)+,r1                / restore register */
+/*     rts     pc */
+
+       fbptr = fbtbl + fbtblsz - 64;
+}
+
+/* Symbol table lookup and hashtable maintenance. */
+
+/* rname: */
+/*     mov     r1,-(sp) */
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+
+void rname() {
+       int count;
+       char *p;
+       int local;
+       int hash, c;
+       int timesaround;
+       struct symbol *psymbol;
+       struct symbol **ppsymbol;
+       int len;
+
+/*     movb    Ncps,r5                 / Max num of chars to accept */
+/*     mov     $symbol,r2 */
+/*     clr     (r2) */
+
+/* printf("rname()\n"); */
+       count = Ncps;
+       p = symbol;
+       *p = 0;
+
+/*     clr     -(sp) */
+/*     clr     -(sp) */
+
+       local = 0;
+       hash = 0;
+
+/*     cmp     r0,$'~                  / symbol not for hash table? */
+/*     bne     1f                      / no - br */
+/*     inc     2(sp) */
+/*     clr     ch */
+
+       if (ch == '~') {
+               local = 1;
+               ch = 0;
+#ifdef TRANSLATE
+ // in C compiler output, local symbols are debugging information
+ // and are only defined not referenced, comment the definitions
+ if (xbufp >= xbuf + 0x1000)
+  abort();
+ *xbufp++ = ';';
+#endif
+       }
+
+/* 1: */
+/*     jsr     pc,rch */
+/*     movb    chartab(r0),r3 */
+/*     ble     1f */
+/*     add     r3,(sp) */
+/*     swab    (sp) */
+/*     dec     r5 */
+/*     blt     1b */
+/*     movb    r3,(r2)+ */
+/*     br      1b */
+/* 1: */
+
+       while (1) {
+               c = rch();
+               if (chartab[c] <= 0)
+                       break;
+               hash += c;
+               hash = ((hash >> 8) & 0377) | ((hash & 0377) << 8);
+               if (count) {
+                       count--;
+                       *p++ = c;
+               }
+ /* bug!! should stop accumulating hash when count == 0 */
+       }
+
+/*     clrb    (r2)+                   / null terminate string */
+/*     movb    r0,ch */
+
+       *p++ = 0;
+/* printf("symbol = \"%s\"\n", symbol); */
+       ch = c;
+#ifdef TRANSLATE
+ if (xbufp <= xbuf)
+  abort();
+ --xbufp;
+#endif
+/* if (ch) printf("a push 0x%02x\n", ch); */
+
+/*     mov     (sp)+,r1 */
+/*     clr     r0 */
+/*     tst     (sp)+ */
+/*     beq     1f */
+/*     mov     symend,r4 */
+/*     br      4f                      / go insert into symtable (!hashtbl) */
+/* 1: */
+
+       if (local) {
+               psymbol = isroom(symend); /* symend; */
+               goto insert;
+       }
+
+/*     div     $hshsiz,r0 */
+/*     ashc    $1,r0 */
+/*     add     hshtab,r1 */
+/*     clr     timesaround */
+
+       ppsymbol = hshtab + (hash % hshsiz);
+       hash /= hshsiz;
+       timesaround = 0;
+
+/* 1: */
+/*     sub     r0,r1 */
+/*     cmp     r1,hshtab */
+/*     bhi     2f */
+/*     add     $2*hshsiz,r1 */
+
+       while (1) {
+               ppsymbol -= hash;
+               if (ppsymbol <= hshtab) {
+                       ppsymbol += hshsiz;
+
+/*     tst     timesaround */
+/*     beq     3f */
+/*     mov     $8f-9f,-(sp)            / write(fileno(stdout),9f,8f-9f); */
+/*     mov     $9f,-(sp) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+/*     jsr     pc,aexit */
+/* not reached */
+
+                       if (timesaround) {
+                               write(2, "as: symbol table overflow\n", 26);
+                               aexit();
+                       }
+
+/*     .data */
+/* timesaround: 0 */
+/* 9: */
+/*     <as: symbol table overflow\n> */
+/* 8: */
+/*     .even */
+/*     .text */
+/* 3: */
+/*     inc     timesaround */
+
+                       timesaround = 1;
+               }
+
+/* 2: */
+/*     mov     $symbol,r2 */
+/*     mov     -(r1),r4 */
+/*     beq     3f */
+/*     mov     (r4)+,r3                / ptr to symbol's name */
+/* 9: */
+/*     cmpb    (r2),(r3)+ */
+/*     bne     1b                      / not the right symbol - br */
+/*     tstb    (r2)+                   / at end of symbol? */
+/*     bne     9b                      / nope - keep looking */
+/*     br      1f                      / yep - br */
+
+               psymbol = *--ppsymbol;
+               if (psymbol == NULL)
+                       break;
+               if (!strcmp(symbol, psymbol->name))
+                       goto found;
+       }
+
+/* 3: */
+/*     mov     symend,r4 */
+/*     jsr     pc,isroom               / make sure there's room in block */
+/*     mov     r4,(r1) */
+/* 4: */
+/*     jsr     pc,isroom               / check for room in current block */
+
+       psymbol = isroom(symend);
+       *ppsymbol = psymbol;
+insert:
+       /* isroom(psymbol); */
+
+/*     mov     $symbol,r2              / length of string (including null) */
+/* 8 : */
+/*     tstb    (r2)+ */
+/*     bne     8b */
+/*     sub     $symbol,r2 */
+/*     jsr     pc,astring              / allocate string space */
+/*     mov     r0,(r4)+                / save string pointer in symtab entry */
+/*     mov     $symbol,r1 */
+/* 9: */
+/*     movb    (r1)+,(r0)+             / copy symbol name to string block */
+/*     bne     9b */
+/*     sub     $SYMENTSZ,symleft */
+
+       len = strlen(symbol) + 1;
+       p = astring(len);
+       psymbol->name = p;
+       memcpy(p, symbol, len);
+       symleft--;
+
+/* each new symbol is assigned a unique one up number.  This is done because */
+/* the user symbol table is no longer contiguous - the symbol number can */
+/* not be calculated by subtracting a base address and dividing by the */
+/* size of a symbol. */
+
+/*     clr     (r4)+                   / flags word */
+/*     clr     (r4)+                   / value word */
+/*     mov     symnum,(r4)+ */
+/*     inc     symnum */
+/*     mov     r4,symend */
+/*     sub     $6,r4                   / point to flags word */
+
+       psymbol->flags = 0; /* redundant */
+       psymbol->value = 0; /* redundant */
+       psymbol->number = symnum++;
+       symend = psymbol + 1;
+
+/* 1: */
+/*     mov     r4,-(sp) */
+/*     mov     r4,r3 */
+/*     tst     -(r3)                   / back to beginning of entry */
+/*     cmp     r3,$ebsymtab            / Permanent Symbol Table(opcode, etc)? */
+/*     blo     1f                      / yes - br */
+/*     mov     6(r3),r4                / get symbol number */
+/*     add     $4000,r4                / user symbol flag */
+/*     br      2f */
+/* 1: */
+
+/* PST entries are PSTENTSZ bytes each because they do not have a 'symnum' */
+/* entry associated with them. */
+
+/*     sub     $symtab,r3 */
+/*     clr     r2 */
+/*     div     $PSTENTSZ,r2 */
+/*     mov     r2,r4 */
+/*     add     $1000,r4                / builtin symbol */
+
+/* 2: */
+/*     jsr     pc,p0putw */
+
+found:
+       if (psymbol >= symtab + ebsymtab)
+               p0putw(04000 + psymbol->number);
+       else
+               p0putw(01000 + (psymbol - symtab));
+
+/*     mov     (sp)+,r4 */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+/*     mov     (sp)+,r1 */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+       token = (intptr_t)psymbol;
+}
+
+/* isroom: */
+/*     cmp     symleft,$SYMENTSZ       / room for another symbol? */
+/*     bge     1f                      / yes - br */
+
+struct symbol *isroom(psymbol) struct symbol *psymbol; {
+       struct symblk *psymblk;
+
+/* printf("isroom(0x%08x) symleft = %d\n", psymbol, symleft); */
+       if (symleft == 0) {
+
+/*     mov     r1,-(sp)                / save from library */
+/*     mov     $SYMBLKSZ+2,-(sp)       / size of sym block plus link word */
+/*     mov     $1,-(sp)                / number of blocks to allocate */
+/*     jsr     pc,_calloc              / calloc(1, SYMBLKSZ+2); */
+/*     cmp     (sp)+,(sp)+ */
+/*     / check for failure? */
+
+               psymblk = (struct symblk *)calloc(1, sizeof(struct symblk));
+               if (psymblk == NULL)
+                       nomem();
+
+/*     mov     r0,*symblk              / link new block to old */
+/*     mov     r0,symblk               / this is now the current block */
+/*     tst     (r0)+                   / skip link word */
+/*     mov     $SYMBLKSZ,symleft       / number of bytes available */
+/*     mov     r0,r4                   / put where it's expected */
+
+               symblk->next = psymblk;
+               symblk = psymblk;
+               symleft = SYMBLKSZ;
+               return psymblk->data;
+
+/*     mov     (sp)+,r1                / restore saved register */
+/* 1: */
+/*     rts     pc                      / return */
+
+       }
+       return psymbol;
+}
+
+/* allocate room for a string, the length is in R2 and includes room for */
+/* a terminating null byte. */
+
+/* astring: */
+/*     cmp     r2,strleft              / room in current block? */
+/*     ble     1f                      / yes - go carve out a chunk */
+
+char *astring(len) int len; {
+       struct strblk *pstrblk;
+       char *p;
+
+/* printf("astring(%d) strleft = %d\n", len, strleft); */
+       if (len > strleft) {
+
+/*     mov     $STRBLKSZ+2,-(sp) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_calloc              / symblk = calloc(1,STRBLKSZ+2) */
+/*     / check for failure? */
+/*     cmp     (sp)+,(sp)+ */
+
+               pstrblk = (struct strblk *)calloc(1, sizeof(struct strblk));
+               if (pstrblk == NULL)
+                       nomem();
+
+/*     mov     r0,*strblk              / update forward link between blocks */
+/*     mov     r0,strblk               / update current string block pointer */
+/*     tst     (r0)+                   / skip link word */
+/*     mov     r0,strend               / current data pointer */
+/*     mov     $STRBLKSZ,strleft       / amount of space left */
+
+               strblk->next = pstrblk;
+               strblk = pstrblk;
+               strleft = STRBLKSZ;
+               strend = strblk->data;
+
+/* 1: */
+/*     mov     strend,r0               / string address */
+/*     add     r2,strend               / update current end point */
+/*     sub     r2,strleft              / update amount of space left */
+/*     rts     pc */
+
+       }
+       p = strend;
+       strend += len;
+       strleft -= len;
+       return p;
+}
+
+/* number: */
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+/*     mov     r5,-(sp) */
+/*     clr     r1 */
+/*     clr     r5 */
+
+int number() {
+       int octal;
+       int decimal;
+       int c;
+
+       octal = 0;
+       decimal = 0;
+
+/* 1: */
+/*     jsr     pc,rch */
+/*     cmp     r0,$'0 */
+/*     blt     1f */
+/*     cmp     r0,$'9 */
+/*     bgt     1f */
+/*     sub     $'0,r0 */
+/*     mul     $10.,r5 */
+/*     add     r0,r5 */
+/*     ash     $3,r1 */
+/*     add     r0,r1 */
+/*     br      1b */
+
+       while (1) {
+               c = rch();
+               if (c < '0' || c > '9')
+                       break;
+               c -= '0';
+               decimal = decimal * 10 + c;
+               octal = octal * 8 + c;
+       }
+
+/* 1: */
+/*     cmp     r0,$'b */
+/*     beq     1f */
+/*     cmp     r0,$'f */
+/*     beq     1f */
+/*     cmp     r0,$'. */
+/*     bne     2f */
+/*     mov     r5,r1 */
+/*     clr     r0 */
+/* 2: */
+
+       if (c == 'b' || c == 'f')
+               goto label;
+       if (c == '.') {
+               octal = decimal;
+               c = 0;
+       }
+
+/*     movb    r0,ch */
+/*     mov     r1,r0 */
+
+       ch = c;
+#ifdef TRANSLATE
+ if (xbufp <= xbuf)
+  abort();
+ --xbufp;
+#endif
+/* if (ch) printf("b push 0x%02x\n", ch); */
+       numbervalue = octal;
+
+/*     mov     (sp)+,r5 */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+/*     rts     pc */
+
+       return 1;
+
+/* 1: */
+/*     mov     r0,r3 */
+/*     mov     r5,r0 */
+/*     jsr     pc,fbcheck */
+/*     add     $141,r0 */
+/*     cmp     r3,$'b */
+/*     beq     1f */
+/*     add     $10.,r0 */
+/* 1: */
+
+label:
+       numbertoken = fbcheck(decimal) + TLABEL;
+       if (c != 'b')
+               numbertoken += 10;
+
+/*     mov     r0,r4 */
+/*     mov     (sp)+,r5 */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+/*     add     $2,(sp) */
+/*     rts     pc */
+
+       return 0;
+}
+
+/* rch: */
+/*     movb    ch,r0 */
+/*     beq     1f */
+/*     clrb    ch */
+/*     rts     pc */
+
+int rch() {
+       int c;
+       char *p;
+
+/* printf("rch() ch = 0x%02x\n", ch); */
+       if (ch) {
+               c = ch;
+               ch = 0;
+#ifdef TRANSLATE
+ //if (xbufp > xbuf && xbufp[-1] == '\n') {
+ // write(1, xbuf, xbufp - xbuf);
+ // xbufp = xbuf;
+ //}
+ //else
+ if (xbufp >= xbuf + 0x1000)
+  abort();
+ *xbufp++ = c;
+#endif
+               return c;
+       }
+
+/* 1: */
+/*     dec     ibufc */
+/*     blt     2f */
+/*     movb    *ibufp,r0 */
+/*     inc     ibufp */
+/*     bic     $!177,r0 */
+/*     beq     1b */
+/*     rts     pc */
+
+       while (1) {
+               ibufc--;
+               if (ibufc < 0)
+                       goto refill;
+               c = *p0ibufp++ & 0177;
+/* putchar(c); */
+               if (c == 0)
+                       continue;
+#ifdef TRANSLATE
+ //if (xbufp > xbuf && xbufp[-1] == '\n') {
+ // write(1, xbuf, xbufp - xbuf);
+ // xbufp = xbuf;
+ //}
+ //else
+ if (xbufp >= xbuf + 0x1000)
+  abort();
+ *xbufp++ = c;
+#endif
+               return c;
+
+/* 2: */
+/*     mov     fin,r0 */
+/*     bmi     3f */
+
+       refill:
+               if (fin >= 0) {
+
+/*     mov     r1,-(sp)                / protect r1 from library */
+/*     mov     $1024.,-(sp)            / read(fin, inbuf, 1024) */
+/*     mov     $inbuf,-(sp) */
+/*     mov     r0,-(sp) */
+/*     jsr     pc,_read */
+/*     add     $6,sp */
+/*     mov     (sp)+,r1 */
+
+                       ibufc = read(fin, inbuf, 1024);
+
+/*     tst     r0 */
+/*     ble     2f */
+/*     mov     r0,ibufc */
+/*     mov     $inbuf,ibufp */
+/*     br      1b */
+/* 2: */
+
+                       if (ibufc > 0) {
+                               p0ibufp = inbuf;
+                               continue;
+                       }
+
+/*     mov     r1,-(sp)                / protect r1 from library */
+/*     mov     fin,-(sp)               / close(r0) */
+/*     jsr     pc,_close */
+/*     tst     (sp)+ */
+/*     mov     $-1,fin */
+/*     mov     (sp)+,r1 */
+
+                       close(fin);
+                       fin = -1;
+               }
+
+/* 3: */
+/*     dec     nargs */
+/*     bge     2f */
+/*     mov     $'\e,r0 */
+/*     rts     pc */
+/* 2: */
+
+               if (nargs == 0)
+                       return 004;
+               nargs--;
+
+/*     tst     ifflg */
+/*     beq     2f */
+/*     mov     $'i,r5 */
+/*     jsr     pc,error */
+/*     jsr     pc,aexit */
+/* not reached */
+/* 2: */
+
+               if (ifflg) {
+                       error('i');
+                       aexit();
+               }
+
+/* check for the filename arguments of "-" or "--", these mean to read 'stdin'. */
+/* Additional filenames are permitted and will be processed when EOF */
+/* is detected on stdin. */
+/*     mov     *curarg,r0 */
+/*     cmpb    (r0)+,$'- */
+/*     bne     5f                      / not the special case - br */
+/*     tstb    (r0)                    / must be '-' by itself */
+/*     beq     4f */
+/*     cmpb    (r0)+,$'-               / check for "--" */
+/*     bne     5f                      / not a double -, must be a filename */
+/*     tstb    (r0)                    / null terminated? */
+/*     bne     5f                      / no - must be a filename */
+/* 4: */
+/*     clr     fin                     / file descriptor is 0 for stdin */
+/*     br      2f */
+/* 5: */
+
+               p = *curarg;
+               if (*p++ == '-' && (*p == 0 || (*p++ == '-' && *p == 0))) {
+                       fin = 0;
+                       goto reset;
+               }
+
+/*     mov     r1,-(sp)                / protect r1 from library */
+/*     clr     -(sp)                   / open((r0), O_RDONLY, 0) */
+/*     clr     -(sp) */
+/*     mov     *curarg,-(sp) */
+/*     jsr     pc,_open */
+/*     add     $6,sp */
+/*     mov     (sp)+,r1 */
+
+               fin = open(*curarg, O_RDONLY);
+
+/*     mov     r0,fin */
+/*     bpl     2f */
+/*     mov     *curarg,-(sp) */
+/*     jsr     pc,filerr */
+/*     tst     (sp)+ */
+/*     jsr     pc,aexit */
+/*not reached */
+
+               if (fin < 0) {
+                       filerr(*curarg);
+                       aexit();
+               }
+
+/* 2: */
+/*     mov     $1,line */
+/*     mov     r4,-(sp) */
+/*     mov     r1,-(sp) */
+/*     mov     $5,r4 */
+/*     jsr     pc,p0putw */
+
+       reset:
+               line = 1;
+               token = TNEWFILE;
+               p0putw(token);
+
+/*     mov     *curarg,r1 */
+/* 2: */
+/*     movb    (r1)+,r4 */
+/*     beq     2f */
+/*     jsr     pc,p0putw */
+/*     br      2b */
+/* 2: */
+/*     add     $2,curarg */
+/*     mov     $-1,r4 */
+/*     jsr     pc,p0putw */
+
+               p = *curarg++;
+               while (1) {
+                       c = *p++;
+                       if (c == 0)
+                               break;
+                       p0putw(c);
+               }
+               p0putw(-1);
+
+/*     mov     (sp)+,r1 */
+/*     mov     (sp)+,r4 */
+/*     br      1b */
+
+       }
+}
+
+/* p0readop: */
+/*     mov     savop,r4 */
+/*     beq     1f */
+/*     clr     savop */
+/*     rts     pc */
+/* 1: */
+/*     jsr     pc,8f */
+/*     jsr     pc,p0putw */
+/*     rts     pc */
+
+void p0readop() {
+       int c;
+
+/* printf("p0readop() savop = 0x%08x\n", savop); */
+#ifdef TRANSLATE
+ xwhitep = xbufp;
+#endif
+       if (savop) {
+               token = savop;
+               savop = 0;
+#ifdef TRANSLATE
+ if (xbufp + xsavebufn >= xbuf + 0x1000)
+  abort();
+ memcpy(xbufp, xsave, xsavebufn);
+ xstartp = xbufp + xsavestartn;
+ xbufp = xbufp + xsavebufn;
+#endif
+               return;
+       }
+
+/* 8: */
+/*     jsr     pc,rch */
+/*     mov     r0,r4 */
+/*     movb    chartab(r0),r1 */
+/*     bgt     rdname */
+/*     jmp     *1f-2(r1) */
+
+       while (1) {
+#ifdef TRANSLATE
+ xstartp = xbufp;
+#endif
+               c = rch();
+               switch (chartab[c]) {
+               default:
+                       rdname(c);
+                       return;
+
+
+/*     .data */
+/*     fixor */
+
+               case -026:
+#if 1 /* modifications for dec syntax */
+                       if (c == '#')
+                               retread(TDOLL);
+                       else if (c == '@')
+                               retread(TSTAR);
+                       else
+#endif
+                       fixor();
+                       return;
+
+/*     escp */
+
+               case -024:
+                       escp();
+                       return;
+
+/*     8b */
+
+               case -022:
+                       break;
+
+/*     retread */
+
+               case -020:
+                       retread(c);
+                       return;
+
+/*     dquote */
+
+               case -016:
+                       dquote();
+                       return;
+
+/*     garb */
+
+               case -014:
+                       garb();
+                       break;
+
+/*     squote */
+
+               case -012:
+                       squote();
+                       return;
+
+/*     rdname */
+
+               case -010:
+                       rdname(c);
+                       return;
+
+/*     skip */
+
+               case -006:
+#ifdef TRANSLATE
+ xbufp[-1] = ';';
+#endif
+                       skip();
+                       return;
+
+/*     rdnum */
+
+               case -004: /* can never get here */
+                       rdnum();
+                       return;
+
+/*     retread */
+
+               case -002:
+                       retread(c);
+                       return;
+
+/*     string */
+
+               case -000:
+                       string();
+                       return;
+
+/* 1: */
+/*     .text */
+
+               }
+       }
+}
+
+/* escp: */
+/*     jsr     pc,rch */
+/*     mov     $esctab,r1 */
+/* 1: */
+/*     cmpb    r0,(r1)+ */
+/*     beq     1f */
+/*     tstb    (r1)+ */
+/*     bne     1b */
+/*     rts     pc */
+/* 1: */
+/*     movb    (r1),r4 */
+/*     rts     pc */
+
+void escp() {
+       int c;
+
+       c = rch();
+       switch (c) {
+
+/*     .data */
+/* esctab: */
+/*     .byte '/, '/ */
+/*     .byte '\<, 035 */
+
+       case '<':
+               retread(TLSH);
+               return;
+
+/*     .byte '>, 036 */
+
+       case '>':
+               retread(TRSH);
+               return;
+
+/*     .byte '%, 037 */
+
+       case '%':
+               retread(TOR);
+               return;
+
+/*     .byte 0, 0 */
+/*     .text */
+
+       }
+       retread(c);
+}
+
+/* fixor: */
+/*     mov     $037,r4 */
+/* retread: */
+/*     rts     pc */
+
+void fixor() {
+       retread(TOR);
+}
+
+void retread(c) int c; {
+       token = c;
+       p0putw(token);
+}
+
+/* rdname: */
+/*     movb    r0,ch */
+/*     cmp     r1,$'0 */
+/*     blo     1f */
+/*     cmp     r1,$'9 */
+/*     blos    rdnum */
+/* 1: */
+/*     jmp     rname */
+
+void rdname(c) int c; {
+       ch = c;
+#ifdef TRANSLATE
+ if (xbufp <= xbuf)
+  abort();
+ --xbufp;
+#endif
+/* if (ch) printf("c push 0x%02x\n", ch); */
+       if (c >= '0' && c <= '9')
+               rdnum();
+       else
+               rname();
+}
+
+/* rdnum: */
+/*     jsr     pc,number */
+/*             br 1f */
+/*     rts     pc */
+
+void rdnum() {
+       if (number())
+               retnum(numbervalue);
+       else
+               retread(numbertoken);
+}
+
+/* squote: */
+/*     jsr     pc,rsch */
+/*     br      1f */
+
+void squote() {
+       retnum(rsch());
+}
+
+/* dquote: */
+/*     jsr     pc,rsch */
+/*     mov     r0,-(sp) */
+/*     jsr     pc,rsch */
+/*     swab    r0 */
+/*     bis     (sp)+,r0 */
+
+void dquote() {
+       int c;
+
+       c = rsch();
+       retnum(rsch() | (c << 8));
+}
+
+/* 1: */
+/*     mov     r0,numval */
+/*     mov     $1,r4 */
+/*     jsr     pc,p0putw */
+/*     mov     numval,r4 */
+/*     jsr     pc,p0putw */
+/*     mov     $1,r4 */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void retnum(value) int value; {
+       numval = value;
+       token = TABS;
+       p0putw(token);
+       p0putw(numval);
+}
+
+/* skip: */
+/*     jsr     pc,rch */
+/*     mov     r0,r4 */
+/*     cmp     r0,$'\e */
+/*     beq     1f */
+/*     cmp     r0,$'\n */
+/*     bne     skip */
+/* 1: */
+/*     rts     pc */
+
+void skip() {
+       int c;
+
+       do {
+               c = rch();
+               if (c == '\e') {
+                       retread(TENDFILE);
+                       return;
+               }
+       } while (c != '\n');
+       retread(TNEWLINE);
+}
+
+/* garb: */
+/*     mov     $'g,r5 */
+/*     jsr     pc,error */
+/*     br      8b */
+
+void garb() {
+       error('g');
+}
+
+/* string: */
+/*     mov     $'<,r4 */
+/*     jsr     pc,p0putw */
+
+void string() {
+       int c;
+
+       token = TSTRING;
+       p0putw(token);
+
+/*     clr     numval */
+/* 1: */
+/*     jsr     pc,rsch */
+/*     tst     r1 */
+/*     bne     1f */
+/*     mov     r0,r4 */
+/*     bis     $400,r4 */
+/*     jsr     pc,p0putw */
+/*     inc     numval */
+/*     br      1b */
+/* 1: */
+
+       numval = 0;
+       while (1) {
+               c = rsch();
+               if (endflag)
+                       break;
+               p0putw(0400 | c);
+               numval++;
+       }
+
+/*     mov     $-1,r4 */
+/*     jsr     pc,p0putw */
+/*     mov     $'<,r4 */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+       p0putw(-1);
+}
+
+/* rsch: */
+/*     jsr     pc,rch */
+
+int rsch() {
+       int c;
+
+       c = rch();
+
+/*     cmp     r0,$'\e */
+/*     beq     4f */
+/*     cmp     r0,$'\n */
+/*     beq     4f */
+
+       endflag = 0;
+       if (c != 004 && c != '\n') {
+
+/*     clr     r1 */
+/*     cmp     r0,$'\\ */
+/*     bne     3f */
+/*     jsr     pc,rch */
+
+               if (c == '\\') {
+                       c = rch();
+
+/*     mov     $schar,r2 */
+/* 1: */
+/*     cmpb    (r2)+,r0 */
+/*     beq     2f */
+/*     tstb    (r2)+ */
+/*     bpl     1b */
+/*     rts     pc */
+/* 2: */
+/*     movb    (r2)+,r0 */
+/*     clr     r1 */
+/*     rts     pc */
+
+                       switch (c) {
+                       case 'n':
+                               return 012;
+                       case 's':
+                               return 040;
+                       case 't':
+                               return 011;
+                       case 'e':
+                               return 004;
+                       case '0':
+                               return 000;
+                       case 'r':
+                               return 015;
+                       case 'a':
+                               return 006;
+                       case 'p':
+                               return 033;
+                       }
+                       return c;
+
+/* 3: */
+/*     cmp     r0,$'> */
+/*     bne     1f */
+/*     inc     r1 */
+/* 1: */
+/*     rts     pc */
+
+               }
+               if (c == '>')
+                       endflag = 1;
+               return c;
+
+/* 4: */
+/*     mov     $'<,r5 */
+/*     jsr     pc,error */
+/*     jsr     pc,aexit */
+/* not reached */
+
+       }
+       error('<');
+       aexit();
+       return 0; /* keep compiler happy */
+}
+
+/*     .data */
+/* schar: */
+/*     .byte 'n, 012 */
+/*     .byte 's, 040 */
+/*     .byte 't, 011 */
+/*     .byte 'e, 004 */
+/*     .byte '0, 000 */
+/*     .byte 'r, 015 */
+/*     .byte 'a, 006 */
+/*     .byte 'p, 033 */
+/*     .byte 0,  -1 */
+/*     .text */
+
+/* opline: */
+/*     mov     r4,r0 */
+/*     bmi     1f */
+/*     cmp     r0,$200 */
+/*     bgt     1f */
+/*     cmp     r0,$'< */
+/*     bne     xpr */
+/*     jmp     opl17 */
+/* xpr: */
+/*     jsr     pc,expres */
+/*     add     $2,dot */
+/*     rts     pc */
+/* 1: */
+
+void p0xpr() {
+       p0expres();
+       pdot->value += 2;
+}
+
+void p0opline() {
+       struct symbol *psymbol;
+       int flags;
+
+/* printf("p0opline() token 0x%08x\n", token); */
+#if 0 //def TRANSLATE
+ *xbufp = 0;
+ printf("p0opline() token 0x%08x xstartp \"%s\"\n", token, xstartp);
+ fflush(stdout);
+#endif
+
+       if (token >= 0 && token < TASCII) {
+               if (token == TSTRING)
+                       p0opl17();
+               else
+                       p0xpr();
+               return;
+       }
+
+/*     movb    (r4),r0 */
+/*     cmp     r0,$24 */
+/*     beq     xpr */
+/*     cmp     r0,$5 */
+/*     blt     xpr */
+/*     cmp     r0,$36 */
+/*     bgt     xpr */
+
+       psymbol = (struct symbol *)token;
+       flags = psymbol->flags;
+       if (flags <= FBSS || flags == FREGISTER || flags > FJCOND) {
+               p0xpr();
+               return;
+       }
+#ifdef TRANSLATE
+ if (xstartp >= xbuf + 0xff0)
+  abort();
+ switch (flags) {
+ case FDOTTEXT:
+  xbufp = xstartp + sprintf(xstartp, ".area TEXT");
+  break;
+ case FDOTDATA:
+  xbufp = xstartp + sprintf(xstartp, ".area DATA");
+  break;
+ case FDOTBSS:
+  xbufp = xstartp + sprintf(xstartp, ".area BSS");
+  break;
+ }
+#endif
+
+
+/*     mov     r0,-(sp) */
+/*     jsr     pc,p0readop */
+/*     mov     (sp)+,r0 */
+/*     asl     r0 */
+/*     jmp     *1f-12(r0) */
+
+       p0readop();
+       switch (flags) {
+
+/*     .data */
+/* 1: */
+/*     opl13                   / map fop freg,fdst to double */
+
+       case FMOVFO:
+               p0opl13();
+               return;
+
+/*     opl6 */
+
+       case FBRANCH:
+               p0opl6();
+               return;
+
+/*     opl7 */
+
+       case FJSR:
+               p0opl7();
+               return;
+
+/*     opl10 */
+
+       case FRTS:
+               p0opl10();
+               return;
+
+/*     opl11 */
+
+       case FSYSTRAP:
+               p0opl11();
+               return;
+
+/*     opl13                   / map fld/fst to double */
+/*     opl13 */
+/*     opl13                   / map fop fsrc,freg to double */
+
+       case FMOVF:
+       case FDOUBLE:
+       case FFLOP:
+               p0opl13();
+               return;
+
+/*     opl15 */
+
+       case FSINGLE:
+               p0opl15();
+               return;
+
+/*     opl16 */
+
+       case FDOTBYTE:
+               p0opl16();
+               return;
+
+#if 1 /* modifications for dec syntax */
+       case FDOTWORD:
+               p0opldotword();
+               return;
+#endif
+
+/*     opl17 */
+
+       case FSTRING:
+               p0opl17();
+               return;
+
+/*     opl20 */
+
+       case FDOTEVEN:
+               p0opl20();
+               return;
+
+/*     opl21 */
+
+       case FDOTIF:
+               p0opl21();
+               return;
+
+/*     opl22 */
+
+       case FDOTENDIF:
+               p0opl22();
+               return;
+
+/*     opl23 */
+
+       case FDOTGLOBL:
+               p0opl23();
+               return;
+
+/*     xpr */
+
+       case FREGISTER: /* can never get here */
+               p0xpr();
+               return;
+
+/*     opl25 */
+
+       case FDOTTEXT:
+               p0opl25();
+               return;
+
+/*     opl26 */
+
+       case FDOTDATA:
+               p0opl26();
+               return;
+
+/*     opl27 */
+
+       case FDOTBSS:
+               p0opl27();
+               return;
+
+/*     opl13                   / map mul s,r to double */
+
+       case FMULDIV:
+               p0opl13();
+               return;
+
+/*     opl31 */
+
+       case FSOB:
+               p0opl31();
+               return;
+
+/*     opl32 */
+
+       case FDOTCOMM:
+               p0opl32();
+               return;
+
+/*     xpr */
+/*     xpr */
+
+       case FESTTEXT:
+       case FESTDATA:
+               p0xpr();
+               return;
+
+/*     opl35 */
+
+       case FJBR:
+               p0opl35();
+               return;
+
+/*     opl36 */
+
+       case FJCOND:
+               p0opl36();
+               return;
+
+/*     .text */
+
+       }
+}
+
+/* opl35:                                      / jbr */
+/*     mov     $4,-(sp) */
+/*     br      1f */
+
+void p0opl35() {
+       relative(4);
+}
+
+/* opl36:                                      / jeq, etc */
+/*     mov     $6,-(sp) */
+
+void p0opl36() {
+       relative(6);
+}
+
+/* 1: */
+/*     jsr     pc,expres */
+/*     cmp     r3,dotrel */
+/*     bne     1f */
+/*     sub     dot,r2 */
+/*     bge     1f */
+/*     cmp     r2,$-376 */
+/*     blt     1f */
+/*     mov     $2,(sp) */
+/* 1: */
+/*     add     (sp)+,dot */
+/*     rts     pc */
+
+void relative(size) int size; {
+       p0expres();
+       if (leftflags == pdot->flags) {
+               leftvalue -= pdot->value;
+               if (leftvalue < 0 && leftvalue >= -0376)
+                       size = 2;
+       }
+       pdot->value += size;
+}
+
+/* opl13: */
+
+void p0opl13() {
+       p0opl7();
+}
+
+/* opl7:                                       /double */
+/*     jsr     pc,addres */
+
+void p0opl7() {
+       p0addres();
+
+/* op2: */
+/*     cmp     r4,$', */
+/*     beq     1f */
+/*     jsr     pc,errora */
+/*     rts     pc */
+/* 1: */
+/*     jsr     pc,p0readop */
+
+       if (token != TCOMMA) {
+               error('a');
+               return;
+       }
+       p0readop();
+       p0opl15();
+}
+
+/* opl15:                              / single operand */
+/*     jsr     pc,addres */
+/*     add     $2,dot */
+/*     rts     pc */
+
+void p0opl15() {
+       p0addres();
+       pdot->value += 2;
+}
+
+/* opl31:                                      / sob */
+/*     jsr     pc,expres */
+/*     cmp     r4,$', */
+/*     beq     1f */
+/*     jsr     pc,errora */
+/* 1: */
+/*     jsr     pc,p0readop */
+
+void p0opl31() {
+       p0expres();
+       if (token != TCOMMA) {
+               error('a');
+               return;
+       }
+       p0readop();
+       p0opl11();
+}
+
+/* opl6: */
+
+void p0opl6() {
+       p0opl11();
+}
+
+/* opl10: */
+
+void p0opl10() {
+       p0opl11();
+}
+
+/* opl11:                                      /branch */
+/*     jsr     pc,expres */
+/*     add     $2,dot */
+/*     rts     pc */
+
+void p0opl11() {
+       p0expres();
+       pdot->value += 2;
+}
+
+/* opl16:                                      / .byte */
+/*     jsr     pc,expres */
+/*     inc     dot */
+/*     cmp     r4,$', */
+/*     bne     1f */
+/*     jsr     pc,p0readop */
+/*     br      opl16 */
+/* 1: */
+/*     rts     pc */
+
+void p0opl16() {
+       while (1) {
+               p0expres();
+               pdot->value++;
+               if (token != TCOMMA)
+                       break;
+               p0readop();
+       }
+}
+
+#if 1 /* modifications for dec syntax */
+void p0opldotword() {
+       while (1) {
+               p0expres();
+               pdot->value += 2;
+               if (token != TCOMMA)
+                       break;
+               p0readop();
+       }
+}
+#endif
+
+/* opl17:                                      / < (.ascii) */
+/*     add     numval,dot */
+/*     jsr     pc,p0readop */
+/*     rts     pc */
+
+void p0opl17() {
+       pdot->value += numval;
+       p0readop();
+}
+
+/* opl20:                                      /.even */
+/*     inc     dot */
+/*     bic     $1,dot */
+/*     rts     pc */
+
+void p0opl20() {
+       pdot->value = (pdot->value + 1) & ~1;
+}
+
+/* opl21:                                      /.if */
+/*     jsr     pc,expres */
+/*     tst     r3 */
+/*     bne     1f */
+/*     mov     $'U,r5 */
+/*     jsr     pc,error */
+/* 1: */
+/*     tst     r2 */
+/*     bne     opl22 */
+/*     inc     ifflg */
+/* opl22:                                      /endif */
+/*     rts     pc */
+
+void p0opl21() {
+       p0expres();
+       if (leftflags == 0)
+               error('U');
+       if (leftvalue == 0)
+               ifflg++;
+}
+
+void p0opl22() {
+}
+
+/* opl23:                                      /.globl */
+/*     cmp     r4,$200 */
+/*     blo     1f */
+/*     bisb    $40,(r4) */
+/*     jsr     pc,p0readop */
+/*     cmp     r4,$', */
+/*     bne     1f */
+/*     jsr     pc,p0readop */
+/*     br      opl23 */
+/* 1: */
+/*     rts     pc */
+
+void p0opl23() {
+       struct symbol *psymbol;
+
+       while (1) {
+               if (token >= 0 && token < TASCII)
+                       break;
+               psymbol = (struct symbol *)token;
+               psymbol->flags |= FGLOBAL;
+               p0readop();
+               if (token != TCOMMA)
+                       break;
+               p0readop();
+       }
+}
+
+/* opl25: */
+/* opl26: */
+/* opl27: */
+/*     mov     dotrel,r1 */
+/*     asl     r1 */
+/*     mov     dot,savdot-4(r1) */
+/*     mov     savdot-[2*25](r0),dot */
+/*     asr     r0 */
+/*     sub     $25-2,r0 */
+/*     mov     r0,dotrel */
+/*     rts     pc */
+
+void p0opl25() {
+       savdot[pdot->flags - FTEXT] = pdot->value;
+       pdot->value = savdot[0];
+       pdot->flags = FTEXT;
+}
+
+void p0opl26() {
+       savdot[pdot->flags - FTEXT] = pdot->value;
+       pdot->value = savdot[1];
+       pdot->flags = FDATA;
+}
+
+void p0opl27() {
+       savdot[pdot->flags - FTEXT] = pdot->value;
+       pdot->value = savdot[2];
+       pdot->flags = FBSS;
+}
+
+/* opl32:                                      / .common */
+/*     cmp     r4,$200 */
+/*     blo     1f */
+/*     bis     $40,(r4) */
+/*     jsr     pc,p0readop */
+/*     cmp     r4,$', */
+/*     bne     1f */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     rts     pc */
+/* 1: */
+/*     mov     $'x,r5 */
+/*     jsr     pc,error */
+/*     rts     pc */
+
+void p0opl32() {
+       struct symbol *psymbol;
+
+       if (token >= 0 && token < TASCII) {
+               error('x');
+               return;
+       }
+       psymbol = (struct symbol *)token;
+       psymbol->flags |= FGLOBAL;
+       p0readop();
+       if (token != TCOMMA) {
+               error('x');
+               return;
+       }
+       p0readop();
+       p0expres();
+}
+
+/* addres: */
+/*     cmp     r4,$'( */
+/*     beq     alp */
+/*     cmp     r4,$'- */
+/*     beq     amin */
+/*     cmp     r4,$'$ */
+/*     beq     adoll */
+/*     cmp     r4,$'* */
+/*     beq     astar */
+
+void p0addres() {
+/* printf("p0addres() token = 0x%08x\n", token); */
+       switch (token) {
+       case TLPAREN:
+               p0alp();
+               return;
+       case TMIN:
+               p0amin();
+               return;
+       case TDOLL:
+#ifdef TRANSLATE
+ xbufp[-1] = '#';
+#endif
+               p0adoll();
+               return;
+       case TSTAR:
+               p0astar();
+               return;
+       }
+       p0getx();
+}
+
+/* getx: */
+/*     jsr     pc,expres */
+/*     cmp     r4,$'( */
+/*     bne     2f */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkreg */
+/*     jsr     pc,checkrp */
+/* 1: */
+/*     add     $2,dot */
+/*     clr     r0 */
+/*     rts     pc */
+/* 2: */
+/*     cmp     r3,$24                  / register type */
+/*     bne     1b */
+/*     jsr     pc,checkreg */
+/*     clr     r0 */
+/*     rts     pc */
+
+void p0getx() {
+       p0expres();
+       if (token == TLPAREN) {
+               p0readop();
+               p0expres();
+               p0checkreg();
+               p0checkrp();
+               pdot->value += 2;
+       }
+       else if (leftflags == FREGISTER)
+               p0checkreg();
+       else
+               pdot->value += 2;
+       indirect = 0;
+}
+
+/* alp: */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkrp */
+/*     jsr     pc,checkreg */
+/*     cmp     r4,$'+ */
+/*     bne     1f */
+/*     jsr     pc,p0readop */
+/*     clr     r0 */
+/*     rts     pc */
+/* 1: */
+/*     mov     $2,r0 */
+/*     rts     pc */
+
+void p0alp() {
+       p0readop();
+       p0expres();
+       p0checkrp();
+       p0checkreg();
+       if (token == TPLUS) {
+               p0readop();
+               indirect = 0;
+       }
+       else
+               indirect = 2;
+}
+
+/* amin: */
+/*     jsr     pc,p0readop */
+/*     cmp     r4,$'( */
+/*     beq     1f */
+/*     mov     r4,savop */
+/*     mov     $'-,r4 */
+/*     br      getx */
+/* 1: */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkrp */
+/*     jsr     pc,checkreg */
+/*     clr     r0 */
+/*     rts     pc */
+
+void p0amin() {
+#ifdef TRANSLATE
+ xstartpsave = xstartp;
+ xbufpsave = xbufp;
+#endif
+       p0readop();
+       if (token != TLPAREN) {
+               savop = token;
+#ifdef TRANSLATE
+ xsavestartn = xstartp - xbufpsave;
+ xsavebufn = xbufp - xbufpsave;
+ memcpy(xsave, xbufpsave, xsavebufn);
+#endif
+               token = TMIN;
+#ifdef TRANSLATE
+ xstartp = xstartpsave;
+ xbufp = xbufpsave;
+#endif
+               p0getx();
+       }
+       else {
+               p0readop();
+               p0expres();
+               p0checkrp();
+               p0checkreg();
+               indirect = 0;
+       }
+}
+
+/* adoll: */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     add     $2,dot */
+/*     clr     r0 */
+/*     rts     pc */
+
+void p0adoll() {
+       p0readop();
+       p0expres();
+       pdot->value += 2;
+       indirect = 0;
+}
+
+/* astar: */
+/*     jsr     pc,p0readop */
+/*     cmp     r4,$'* */
+/*     bne     1f */
+/*     mov     $'*,r5 */
+/*     jsr     pc,error */
+/* 1: */
+/*     jsr     pc,addres */
+/*     add     r0,dot */
+/*     rts     pc */
+
+void p0astar() {
+       p0readop();
+       if (token == TSTAR)
+               error('*');
+       p0addres();
+       pdot->value += indirect;
+}
+
+/* errora: */
+/*     mov     $'a,r5 */
+/*     jsr     pc,error */
+/*     rts     pc */
+
+void errora() {
+       error('a');
+}
+
+/* checkreg: */
+/*     cmp     r2,$7 */
+/*     bhi     1f */
+/*     cmp     r3,$1 */
+/*     beq     2f */
+/*     cmp     r3,$4 */
+/*     bhi     2f */
+/* 1: */
+/*     jsr     pc,errora */
+/* 2: */
+/*     rts     pc */
+
+void p0checkreg() {
+       if (leftvalue > 7 || (leftflags != FABS && leftflags <= FBSS))
+               errora();
+}
+
+/* errore: */
+/*     mov     $'e,r5 */
+/*     jsr     pc,error */
+/*     rts     pc */
+
+void errore() {
+       error('e');
+}
+
+/* checkrp: */
+/*     cmp     r4,$') */
+/*     beq     1f */
+/*     mov     $'),r5 */
+/*     jsr     pc,error */
+/*     rts     pc */
+/* 1: */
+/*     jsr     pc,p0readop */
+/*     rts     pc */
+
+void p0checkrp() {
+       if (token != TRPAREN)
+               error(')');
+       else
+               p0readop();
+}
+
+/* expres: */
+/*     mov     r5,-(sp) */
+/*     mov     $'+,-(sp) */
+/*     clr     opfound */
+/*     clr     r2 */
+/*     mov     $1,r3 */
+/*     br      1f */
+
+void p0expres() {
+       struct symbol *psymbol;
+
+/* printf("p0expres()\n"); */
+       optoken = TPLUS;
+       opfound = 0;
+       leftvalue = 0;
+       leftflags = FABS;
+       goto entry;
+
+/* advanc: */
+/*     jsr     pc,p0readop */
+/* 1: */
+/*     mov     r4,r0 */
+/*     tst     r0 */
+/*     blt     6f */
+/*     cmp     r0,$177 */
+/*     ble     7f */
+/* 6: */
+/*     movb    (r4),r0 */
+/*     mov     2(r4),r1 */
+/*     br      oprand */
+/* 7: */
+
+       while (1) {
+               p0readop();
+       entry:
+               rightflags = token;
+               if (token < 0 || token >= TASCII) {
+                       psymbol = (struct symbol *)token;
+                       rightflags = psymbol->flags;
+                       rightvalue = psymbol->value;
+                       p0oprand();
+                       continue;
+               }
+
+/*     cmp     r4,$141 */
+/*     blo     1f */
+/*     cmp     r4,$141+10. */
+/*     bhis    2f */
+/*     movb    curfbr-141(r4),r0 */
+/*     asl     r4 */
+/*     mov     curfb-[2*141](r4),r2 */
+/*     cmp     r2,$-1 */
+/*     bne     oprand */
+/*     mov     $'f,r5 */
+/*     jsr     pc,error */
+/*     br      oprand */
+/* 2: */
+/*     clr     r3 */
+/*     clr     r2 */
+/*     br      oprand */
+/* 1: */
+
+               if (token >= TLABEL) {
+                       if (token < TLABEL + 10) {
+#ifdef TRANSLATE
+ if (xstartp >= xbuf + 0xff0)
+  abort();
+ xbufp = xstartp + sprintf(xstartp, "_%d", xlabb[token - TLABEL]);
+#endif
+                               rightflags = curfbr[token - TLABEL];
+ /* bug!! should be rightvalue / rightflags below: */
+                               leftvalue = curfb[token - TLABEL];
+                               if (leftvalue == -1)
+                                       error('f');
+                       }
+                       else {
+#ifdef TRANSLATE
+ xlab = token - (TLABEL + 10);
+ if (xlab < 10) {
+  if (xlabf[xlab] == -1)
+   xlabf[xlab] = xlabnext++;
+  if (xstartp >= xbuf + 0xff0)
+   abort();
+  xbufp = xstartp + sprintf(xstartp, "_%d", xlabf[xlab]);
+ }
+#endif
+                               leftflags = 0;
+                               leftvalue = 0;
+                       }
+                       p0oprand();
+                       continue;
+               }
+
+/*     mov     $esw1,r1 */
+/* 1: */
+/*     cmp     (r1)+,r4 */
+/*     beq     1f */
+/*     tst     (r1)+ */
+/*     bne     1b */
+/*     tst     opfound */
+/*     bne     2f */
+/*     jsr     pc,errore */
+/* 2: */
+/*     tst     (sp)+ */
+/*     mov     (sp)+,r5 */
+/*     rts     pc */
+/* 1: */
+/*     jmp     *(r1) */
+
+               switch (token) {
+               default:
+                       if (opfound == 0)
+                               error('e');
+                       return;
+
+/*     .data */
+/* esw1: */
+/*     '+;     binop */
+/*     '-;     binop */
+/*     '*;     binop */
+/*     '/;     binop */
+/*     '&;     binop */
+/*     037;    binop */
+/*     035;    binop */
+/*     036;    binop */
+/*     '%;     binop */
+
+               case TPLUS:
+               case TMIN:
+               case TSTAR:
+               case TSLASH:
+               case TAND:
+               case TOR:
+               case TLSH:
+               case TRSH:
+               case TMOD:
+                       p0binop();
+                       break;
+
+/*     '[;     brack */
+
+               case TLBRACK:
+                       p0brack();
+                       break;
+
+/*     '^;     binop */
+
+               case TCARET:
+                       p0binop();
+                       break;
+
+/*     1;      exnum */
+
+               case TABS:
+                       p0exnum();
+                       break;
+
+/*     '!;     binop */
+
+               case TNOT:
+                       p0binop();
+                       break;
+
+/*     0;      0 */
+/*     .text */
+
+               }
+       }
+}
+
+/* binop: */
+/*     cmpb    (sp),$'+ */
+/*     beq     1f */
+/*     jsr     pc,errore */
+/* 1: */
+/*     movb    r4,(sp) */
+/*     br      advanc */
+
+void p0binop() {
+       if (optoken != TPLUS)
+               error('e');
+       optoken = token;
+}
+
+/* exnum: */
+/*     mov     numval,r1 */
+/*     mov     $1,r0 */
+/*     br      oprand */
+
+void p0exnum() {
+/* printf("p0exnum() numval = 0%o\n", numval); */
+       rightvalue = numval;
+       rightflags = FABS;
+       p0oprand();
+}
+
+/* brack: */
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+/*     jsr     pc,p0readop */
+/*     jsr     pc,expres */
+/*     cmp     r4,$'] */
+/*     beq     1f */
+/*     mov     $'],r5 */
+/*     jsr     pc,error */
+/* 1: */
+/*     mov     r3,r0 */
+/*     mov     r2,r1 */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+
+void p0brack() {
+       int tempvalue;
+       int tempflags;
+       int temptoken;
+
+       tempvalue = leftvalue;
+       tempflags = leftflags;
+       temptoken = optoken;
+       p0readop();
+       p0expres();
+       if (token != TRBRACK)
+               error(']');
+       rightflags = leftflags;
+       rightvalue = leftvalue;
+       leftflags = tempflags;
+       leftvalue = tempvalue;
+       optoken = temptoken;
+       p0oprand();
+}
+
+/* oprand: */
+/*     inc     opfound */
+/*     mov     $exsw2,r5 */
+/* 1: */
+/*     cmp     (sp),(r5)+ */
+/*     beq     1f */
+/*     tst     (r5)+ */
+/*     bne     1b */
+/*     br      eoprnd */
+/* 1: */
+/*     jmp     *(r5) */
+
+void p0oprand() {
+       opfound = 1;
+       switch (optoken) {
+       default:
+               p0eoprnd();
+               return;
+
+/*     .data */
+/* exsw2: */
+/*     '+; exadd */
+
+       case TPLUS:
+               p0exadd();
+               return;
+
+/*     '-; exsub */
+
+       case TMIN:
+               p0exsub();
+               return;
+
+/*     '*; exmul */
+
+       case TSTAR:
+               p0exmul();
+               return;
+
+/*     '/; exdiv */
+
+       case TSLASH:
+               p0exdiv();
+               return;
+
+/*     037; exor */
+
+       case TOR:
+               p0exor();
+               return;
+
+/*     '&; exand */
+
+       case TAND:
+               p0exand();
+               return;
+
+/*     035;exlsh */
+
+       case TLSH:
+               p0exlsh();
+               return;
+
+/*     036;exrsh */
+
+       case TRSH:
+               p0exrsh();
+               return;
+
+/*     '%; exmod */
+
+       case TMOD:
+               p0exmod();
+               return;
+
+/*     '!; exnot */
+
+       case TNOT:
+               p0exnot();
+               return;
+
+/*     '^; excmbin */
+
+       case TCARET:
+               p0excmbin();
+               return;
+
+/*     0;  0 */
+/*     .text */
+
+       }
+}
+
+/* excmbin: */
+/*     mov     r0,r3                   / give left flag of right */
+/*     br      eoprnd */
+
+void p0excmbin() {
+       leftflags = rightflags;
+       p0eoprnd();
+}
+
+/* exrsh: */
+/*     neg     r1 */
+/*     beq     exlsh */
+/*     inc     r1 */
+/*     clc */
+/*     ror     r2 */
+/* exlsh: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     ash     r1,r2 */
+/*     br      eoprnd */
+
+void p0exrsh() {
+       p0combin(0);
+       leftvalue = ((unsigned int)leftvalue & 0177777) >> rightvalue;
+       p0eoprnd();
+}
+
+void p0exlsh() {
+       p0combin(0);
+       leftvalue <<= rightvalue;
+       p0eoprnd();
+}
+
+/* exmod: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     mov     r1,-(sp) */
+/*     mov     r2,r1 */
+/*     clr     r0 */
+/*     div     (sp)+,r0 */
+/*     mov     r1,r2 */
+/*     br      eoprnd */
+
+void p0exmod() {
+       int temp;
+
+       p0combin(0);
+       temp = rightvalue & 0177777;
+       if (temp)
+               leftvalue = (leftvalue & 0177777) % temp;
+       else {
+               error('0'); /* a nick innovation */
+               leftvalue = 0;
+       }
+       p0eoprnd();
+}
+
+/* exadd: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     add     r1,r2 */
+/*     br      eoprnd */
+
+void p0exadd() {
+       p0combin(0);
+       leftvalue += rightvalue;
+       p0eoprnd();
+}
+
+/* exsub: */
+/*     mov     $1,r5 */
+/*     jsr     pc,combin */
+/*     sub     r1,r2 */
+/*     br      eoprnd */
+
+void p0exsub() {
+       p0combin(1);
+       leftvalue -= rightvalue;
+       p0eoprnd();
+}
+
+/* exand: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     com     r1 */
+/*     bic     r1,r2 */
+/*     br      eoprnd */
+
+void p0exand() {
+       p0combin(0);
+       leftvalue &= rightvalue;
+       p0eoprnd();
+}
+
+/* exor: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     bis     r1,r2 */
+/*     br      eoprnd */
+
+void p0exor() {
+       p0combin(0);
+       leftvalue |= rightvalue;
+       p0eoprnd();
+}
+
+/* exmul: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     mul     r2,r1 */
+/*     mov     r1,r2 */
+/*     br      eoprnd */
+
+void p0exmul() {
+       p0combin(0);
+       leftvalue *= rightvalue;
+       p0eoprnd();
+}
+
+/* exdiv: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     mov     r1,-(sp) */
+/*     mov     r2,r1 */
+/*     clr     r0 */
+/*     div     (sp)+,r0 */
+/*     mov     r0,r2 */
+/*     br      eoprnd */
+
+void p0exdiv() {
+       int temp;
+
+       p0combin(0);
+       temp = rightvalue & 0177777;
+       if (temp)
+               leftvalue = (leftvalue & 0177777) / temp;
+       else {
+               error('0'); /* a nick innovation */
+               leftvalue = 0;
+       }
+       p0eoprnd();
+}
+
+/* exnot: */
+/*     clr     r5 */
+/*     jsr     pc,combin */
+/*     com     r1 */
+/*     add     r1,r2 */
+/*     br      eoprnd */
+
+void p0exnot() {
+       p0combin(0);
+       leftvalue += ~rightvalue;
+       p0eoprnd();
+}
+
+/* eoprnd: */
+/*     mov     $'+,(sp) */
+/*     jmp     advanc */
+
+void p0eoprnd() {
+       optoken = TPLUS;
+}
+
+/* combin: */
+/*     mov     r0,-(sp) */
+/*     bis     r3,(sp) */
+/*     bic     $!40,(sp) */
+/*     bic     $!37,r0 */
+/*     bic     $!37,r3 */
+/*     cmp     r0,r3 */
+/*     ble     1f */
+/*     mov     r0,-(sp) */
+/*     mov     r3,r0 */
+/*     mov     (sp)+,r3 */
+/* 1: */
+
+void p0combin(minflag) int minflag; {
+       int global;
+       int flags;
+
+       global = (rightflags | leftflags) & FGLOBAL;
+       rightflags &= 037;
+       leftflags &= 037;
+       if (rightflags > leftflags) {
+               flags = rightflags;
+               rightflags = leftflags;
+               leftflags = flags;
+       }
+
+/*     tst     r0 */
+/*     beq     1f */
+/*     tst     r5 */
+/*     beq     2f */
+/*     cmp     r0,r3 */
+/*     bne     2f */
+/*     mov     $1,r3 */
+/*     br      2f */
+/* 1: */
+/*     clr     r3 */
+/* 2: */
+/*     bis     (sp)+,r3 */
+/*     rts     pc */
+
+       if (rightflags) {
+               if (minflag && rightflags == leftflags)
+                       leftflags = TABS;
+       }
+       else {
+               leftflags = 0;
+       }
+       leftflags |= global;
+}
+
+/*     .data */
+/* chartab: */
+/*     .byte -14,-14,-14,-14,-02,-14,-14,-14 */
+/*     .byte -14,-22, -2,-14,-14,-22,-14,-14 */
+/*     .byte -14,-14,-14,-14,-14,-14,-14,-14 */
+/*     .byte -14,-14,-14,-14,-14,-14,-14,-14 */
+/*     .byte -22,-20,-16,-14,-20,-20,-20,-12 */
+/*     .byte -20,-20,-20,-20,-20,-20,056,-06 */
+/*     .byte 060,061,062,063,064,065,066,067 */
+/*     .byte 070,071,-20,-02,-00,-20,-14,-14 */
+/*     .byte -14,101,102,103,104,105,106,107 */
+/*     .byte 110,111,112,113,114,115,116,117 */
+/*     .byte 120,121,122,123,124,125,126,127 */
+/*     .byte 130,131,132,-20,-24,-20,-20,137 */
+/*     .byte -14,141,142,143,144,145,146,147 */
+/*     .byte 150,151,152,153,154,155,156,157 */
+/*     .byte 160,161,162,163,164,165,166,167 */
+/*     .byte 170,171,172,-14,-26,-14,176,-14 */
+
+char chartab[TASCII] = {
+       -014,-014,-014,-014,-002,-014,-014,-014,
+       -014,-022,0 -2,-014,-014,-022,-014,-014,
+       -014,-014,-014,-014,-014,-014,-014,-014,
+       -014,-014,-014,-014,-014,-014,-014,-014,
+#if 1 /* modifications for dec syntax */
+       -022,-020,-016,-026,-020,-020,-020,-012,
+#else
+       -022,-020,-016,-014,-020,-020,-020,-012,
+#endif
+       -020,-020,-020,-020,-020,-020,0056,-006,
+       0060,0061,0062,0063,0064,0065,0066,0067,
+       0070,0071,-020,-002,-000,-020,-014,-014,
+#if 1 /* modifications for dec syntax */
+       -026,0101,0102,0103,0104,0105,0106,0107,
+#else
+       -014,0101,0102,0103,0104,0105,0106,0107,
+#endif
+       0110,0111,0112,0113,0114,0115,0116,0117,
+       0120,0121,0122,0123,0124,0125,0126,0127,
+       0130,0131,0132,-020,-024,-020,-020,0137,
+       -014,0141,0142,0143,0144,0145,0146,0147,
+       0150,0151,0152,0153,0154,0155,0156,0157,
+       0160,0161,0162,0163,0164,0165,0166,0167,
+       0170,0171,0172,-014,-026,-014,0176,-014
+};
+
+/* a.tmp1:     </tmp/atm1XX\0> */
+
+#ifdef pdp11
+char a_tmp1[] = "/tmp/atm1XX";
+#else
+char a_tmp1[] = "/tmp/atm1XXXXXX"; /* linux requires 6 X's */
+#endif
+
+/* Ncps:       .byte 8. */
+
+char Ncps = 8;
+
+/* 1:  <-\0> */
+/*     .even */
+/* dash:       1b */
+
+char *dash = "-";
+
+/* fin:        -1 */
+
+int fin = -1;
+
+/* fout:       -1 */
+
+int fout = -1;
+
+/* The next two _must_ be adjacent!  Not sure why, but then this whole */
+/* assembler is weird beyond belief. */
+/* curfb:      -1;-1;-1;-1;-1;-1;-1;-1;-1;-1 */
+
+/* THEY HAD TO BE ADJACENT BECAUSE PASS 2 p0expres() READS curfb[token - 0141] */
+/* THIS HAS BEEN SPLIT INTO curfb[token - 0141], nxtfb[token - (0141 + 10)] */
+/* BY THE WAY, THE ASSEMBLER IS NOT REALLY WEIRD, IT'S KIND OF ELEGANT !!! */
+intptr_t curfb[10] = {
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+/* nxtfb:      .=.+20.                 / first 4 used by pass0, all 20. by pass1+2 */
+
+/* FIRST 4 AREN'T USED BY PASS 0 ANYMORE, IT WAS ONLY TEMPORARY SCRATCH !!!! */
+intptr_t nxtfb[10];
+
+/*     .bss */
+/* curfbr:     .=.+10. */
+
+int curfbr[10];
+
+/* savdot:     .=.+6 */
+
+int savdot[3];
+
+/* hshtab:     .=.+2                   / dynamically allocated */
+
+struct symbol **hshtab;
+
+/* ch: .=.+2 */
+
+int ch;
+
+/* symnum:     .=.+2                   / symbol number */
+
+int symnum;
+
+/* symbol:     .=.+32.                 / XXX */
+/*     .=.+2                   / paranoia to make sure a null is present */
+
+char symbol[33];
+
+/* inbuf:  .=.+1024. */
+
+char inbuf[1024];
+
+/* line:       .=.+2 */
+
+int line;
+
+/* ifflg:      .=.+2 */
+
+int ifflg;
+
+/* nargs:      .=.+2 */
+
+int nargs;
+
+/* curarg:     .=.+2 */
+
+char **curarg;
+
+/* opfound:.=.+2 */
+
+int opfound;
+
+/* savop:      .=.+2 */
+
+int savop;
+
+/* numval:     .=.+2 */
+
+int numval;
+
+/* fbtblsz:.=.+2 */
+
+int fbtblsz;
+
+/* fbfree: .=.+2 */
+
+int fbfree;
+
+/* fbptr:  .=.+2 */
+
+struct symbol *fbptr;
+
+/* fbtbl:  .=.+2 */
+
+struct symbol *fbtbl;
+
+/* usymtab:.=.+2                       / ptr to first block of symbols */
+
+struct symblk *usymtab;
+
+/* symleft:.=.+2                       / bytes left in current symbol block */
+
+int symleft;
+
+/* symend: .=.+2                       / ptr to next symbol space in block */
+
+struct symbol *symend;
+
+/* symblk: .=.+2                       / ptr to beginning of current sym block */
+
+struct symblk *symblk;
+
+/* strleft:.=.+2                       / amount left in string block */
+
+int strleft;
+
+/* strend:     .=.+2                   / ptr to next available string byte */
+
+char *strend;
+
+/* strblk:     .=.+2                   / ptr to current string block link word */
+
+struct strblk *strblk;
+
+/* key to types */
+
+/*     0       undefined */
+/*     1       absolute (nop, reset, bpt, ...) */
+/*     2       text */
+/*     3       data */
+/*     4       bss */
+/*     5       flop freg,dst (movfo, = stcfd) */
+/*     6       branch */
+/*     7       jsr */
+/*     10      rts */
+/*     11      sys, trap */
+/*     12      movf (=ldf,stf) */
+/*     13      double operand (mov) */
+/*     14      flop fsrc,freg (addf) */
+/*     15      single operand (clr) */
+/*     16      .byte */
+/*     17      string (.ascii, "<") */
+/*     20      .even */
+/*     21      .if */
+/*     22      .endif */
+/*     23      .globl */
+/*     24      register */
+/*     25      .text */
+/*     26      .data */
+/*     27      .bss */
+/*     30      mul,div, etc */
+/*     31      sob */
+/*     32      .comm */
+/*     33      estimated text */
+/*     34      estimated data */
+/*     35      jbr */
+/*     36      jeq, jne, etc */
+
+/*     .data */
+/* the format of PST entries was changed.  rather than fixed 8 byte strings */
+/* (often with many trailing nulls) a pointer to a null terminated string */
+/* is now used.  This saves quite a bit of space since most PST entries are */
+/* only 3 or 4 characters long.  we had to do this the hard way since there */
+/* is no macro capability in the assembler and i'd chuck out the SDI [Span */
+/* Dependent Instruction] stuff and use my own assembler before trying to */
+/* add macros to this one.  Symbols beginning with 'L' are used since the */
+/* linker can be told to discard those. */
+
+/* symtab: */
+/* special symbols */
+
+/* L1; dotrel: 02;    dot: 0000000 */
+/* L2;     01; dotdot: 0000000 */
+
+/* register */
+
+/* L3; 24;     000000 */
+/* L4; 24;     000001 */
+/* L5; 24;     000002 */
+/* L6; 24;     000003 */
+/* L7; 24;     000004 */
+/* L8; 24;     000005 */
+/* L9; 24;     000006 */
+/* L10;        24;     000007 */
+
+/* double operand */
+
+/* L11;        13;     0010000 */
+/* L12;        13;     0110000 */
+/* L13;        13;     0020000 */
+/* L14;        13;     0120000 */
+/* L15;        13;     0030000 */
+/* L16;        13;     0130000 */
+/* L17;        13;     0040000 */
+/* L18;        13;     0140000 */
+/* L19;        13;     0050000 */
+/* L20;        13;     0150000 */
+/* L21;        13;     0060000 */
+/* L22;        13;     0160000 */
+
+/* branch */
+
+/* L23;        06;     0000400 */
+/* L24;        06;     0001000 */
+/* L25;        06;     0001400 */
+/* L26;        06;     0002000 */
+/* L27;        06;     0002400 */
+/* L28;        06;     0003000 */
+/* L29;        06;     0003400 */
+/* L30;        06;     0100000 */
+/* L31;        06;     0100400 */
+/* L32;        06;     0101000 */
+/* L33;        06;     0101400 */
+/* L34;        06;     0102000 */
+/* L35;        06;     0102400 */
+/* L36;        06;     0103000 */
+/* L37;        06;     0103000 */
+/* L38;        06;     0103000 */
+/* L39;        06;     0103400 */
+/* L40;        06;     0103400 */
+/* L41;        06;     0103400 */
+
+/* jump/branch type */
+
+/* L42;        35;     0000400 */
+/* L43;        36;     0001000 */
+/* L44;        36;     0001400 */
+/* L45;        36;     0002000 */
+/* L46;        36;     0002400 */
+/* L47;        36;     0003000 */
+/* L48;        36;     0003400 */
+/* L49;        36;     0100000 */
+/* L50;        36;     0100400 */
+/* L51;        36;     0101000 */
+/* L52;        36;     0101400 */
+/* L53;        36;     0102000 */
+/* L54;        36;     0102400 */
+/* L55;        36;     0103000 */
+/* L56;        36;     0103000 */
+/* L57;        36;     0103000 */
+/* L58;        36;     0103400 */
+/* L59;        36;     0103400 */
+/* L60;        36;     0103400 */
+
+/* single operand */
+
+/* L61;        15;     0005000 */
+/* L62;        15;     0105000 */
+/* L63;        15;     0005100 */
+/* L64;        15;     0105100 */
+/* L65;        15;     0005200 */
+/* L66;        15;     0105200 */
+/* L67;        15;     0005300 */
+/* L68;        15;     0105300 */
+/* L69;        15;     0005400 */
+/* L70;        15;     0105400 */
+/* L71;        15;     0005500 */
+/* L72;        15;     0105500 */
+/* L73;        15;     0005600 */
+/* L74;        15;     0105600 */
+/* L75;        15;     0005700 */
+/* L76;        15;     0105700 */
+/* L77;        15;     0006000 */
+/* L78;        15;     0106000 */
+/* L79;        15;     0006100 */
+/* L80;        15;     0106100 */
+/* L81;        15;     0006200 */
+/* L82;        15;     0106200 */
+/* L83;        15;     0006300 */
+/* L84;        15;     0106300 */
+/* L85;        15;     0000100 */
+/* L86;        15;     0000300 */
+/* L87;        15;     0006500 */
+/* L88;        15;     0006600 */
+/* L89;        15;     0106500 */
+/* L90;        15;     0106600 */
+/* L91;        15;     0170300 */
+/* L92;        15;     0106700 */
+/* L93;        15;     0106400 */
+/* L94;        15;     0007000 */
+/* L95;        15;     0007200 */
+/* L96;        15;     0007300 */
+
+/* jsr */
+
+/* L97;        07;     0004000 */
+
+/* rts */
+
+/* L98;        010;    000200 */
+
+/* simple operand */
+
+/* L99;        011;    104400 */
+/* L102;       011;    000230 */
+
+/* flag-setting */
+
+/* L103;       01;     0000240 */
+/* L104;       01;     0000241 */
+/* L105;       01;     0000242 */
+/* L106;       01;     0000244 */
+/* L107;       01;     0000250 */
+/* L108;       01;     0000257 */
+/* L109;       01;     0000261 */
+/* L110;       01;     0000262 */
+/* L111;       01;     0000264 */
+/* L112;       01;     0000270 */
+/* L113;       01;     0000277 */
+/* L114;       01;     0000000 */
+/* L115;       01;     0000001 */
+/* L116;       01;     0000002 */
+/* L117;       01;     0000003 */
+/* L118;       01;     0000004 */
+/* L119;       01;     0000005 */
+/* L120;       01;     0000006 */
+/* L121;       01;     0000007 */
+
+/* floating point ops */
+
+/* L122;       01;     170000 */
+/* L123;       01;     170001 */
+/* L124;       01;     170011 */
+/* L125;       01;     170002 */
+/* L126;       01;     170012 */
+/* L127;       15;     170400 */
+/* L128;       15;     170700 */
+/* L129;       15;     170600 */
+/* L130;       15;     170500 */
+/* L131;       12;     172400 */
+/* L132;       14;     177000 */
+/* L133;       05;     175400 */
+/* L134;       14;     177400 */
+/* L135;       05;     176000 */
+/* L136;       14;     172000 */
+/* L137;       14;     173000 */
+/* L138;       14;     171000 */
+/* L139;       14;     174400 */
+/* L140;       14;     173400 */
+/* L141;       14;     171400 */
+/* L142;       14;     176400 */
+/* L143;       05;     175000 */
+/* L144;       15;     170100 */
+/* L145;       15;     170200 */
+/* L146;       24;     000000 */
+/* L147;       24;     000001 */
+/* L148;       24;     000002 */
+/* L149;       24;     000003 */
+/* L150;       24;     000004 */
+/* L151;       24;     000005 */
+
+/* L152;       30;     070000 */
+/* L153;       30;     071000 */
+/* L154;       30;     072000 */
+/* L155;       30;     073000 */
+/* L156;       07;     074000 */
+/* L157;       15;     006700 */
+/* L158;       11;     006400 */
+/* L159;       31;     077000 */
+
+/* pseudo ops */
+
+/* L160;       16;     000000 */
+/* L161;       20;     000000 */
+/* L162;       21;     000000 */
+/* L163;       22;     000000 */
+/* L164;       23;     000000 */
+/* L165;       25;     000000 */
+/* L166;       26;     000000 */
+/* L167;       27;     000000 */
+/* L168;       32;     000000 */
+
+/* ebsymtab: */
+
+/* L1: <.\0> */
+/* L2: <..\0> */
+/* L3: <r0\0> */
+/* L4: <r1\0> */
+/* L5: <r2\0> */
+/* L6: <r3\0> */
+/* L7: <r4\0> */
+/* L8: <r5\0> */
+/* L9: <sp\0> */
+/* L10:        <pc\0> */
+/* L11:        <mov\0> */
+/* L12:        <movb\0> */
+/* L13:        <cmp\0> */
+/* L14:        <cmpb\0> */
+/* L15:        <bit\0> */
+/* L16:        <bitb\0> */
+/* L17:        <bic\0> */
+/* L18:        <bicb\0> */
+/* L19:        <bis\0> */
+/* L20:        <bisb\0> */
+/* L21:        <add\0> */
+/* L22:        <sub\0> */
+/* L23:        <br\0> */
+/* L24:        <bne\0> */
+/* L25:        <beq\0> */
+/* L26:        <bge\0> */
+/* L27:        <blt\0> */
+/* L28:        <bgt\0> */
+/* L29:        <ble\0> */
+/* L30:        <bpl\0> */
+/* L31:        <bmi\0> */
+/* L32:        <bhi\0> */
+/* L33:        <blos\0> */
+/* L34:        <bvc\0> */
+/* L35:        <bvs\0> */
+/* L36:        <bhis\0> */
+/* L37:        <bec\0> */
+/* L38:        <bcc\0> */
+/* L39:        <blo\0> */
+/* L40:        <bcs\0> */
+/* L41:        <bes\0> */
+/* L42:        <jbr\0> */
+/* L43:        <jne\0> */
+/* L44:        <jeq\0> */
+/* L45:        <jge\0> */
+/* L46:        <jlt\0> */
+/* L47:        <jgt\0> */
+/* L48:        <jle\0> */
+/* L49:        <jpl\0> */
+/* L50:        <jmi\0> */
+/* L51:        <jhi\0> */
+/* L52:        <jlos\0> */
+/* L53:        <jvc\0> */
+/* L54:        <jvs\0> */
+/* L55:        <jhis\0> */
+/* L56:        <jec\0> */
+/* L57:        <jcc\0> */
+/* L58:        <jlo\0> */
+/* L59:        <jcs\0> */
+/* L60:        <jes\0> */
+/* L61:        <clr\0> */
+/* L62:        <clrb\0> */
+/* L63:        <com\0> */
+/* L64:        <comb\0> */
+/* L65:        <inc\0> */
+/* L66:        <incb\0> */
+/* L67:        <dec\0> */
+/* L68:        <decb\0> */
+/* L69:        <neg\0> */
+/* L70:        <negb\0> */
+/* L71:        <adc\0> */
+/* L72:        <adcb\0> */
+/* L73:        <sbc\0> */
+/* L74:        <sbcb\0> */
+/* L75:        <tst\0> */
+/* L76:        <tstb\0> */
+/* L77:        <ror\0> */
+/* L78:        <rorb\0> */
+/* L79:        <rol\0> */
+/* L80:        <rolb\0> */
+/* L81:        <asr\0> */
+/* L82:        <asrb\0> */
+/* L83:        <asl\0> */
+/* L84:        <aslb\0> */
+/* L85:        <jmp\0> */
+/* L86:        <swab\0> */
+/* L87:        <mfpi\0> */
+/* L88:        <mtpi\0> */
+/* L89:        <mfpd\0> */
+/* L90:        <mtpd\0> */
+/* L91:        <stst\0> */
+/* L92:        <mfps\0> */
+/* L93:        <mtps\0> */
+/* L94:        <csm\0> */
+/* L95:        <tstset\0> */
+/* L96:        <wrtlck\0> */
+/* L97:        <jsr\0> */
+/* L98:        <rts\0> */
+/* L99:        <sys\0> */
+/* L102:       <spl\0> */
+/* L103:       <nop\0> */
+/* L104:       <clc\0> */
+/* L105:       <clv\0> */
+/* L106:       <clz\0> */
+/* L107:       <cln\0> */
+/* L108:       <ccc\0> */
+/* L109:       <sec\0> */
+/* L110:       <sev\0> */
+/* L111:       <sez\0> */
+/* L112:       <sen\0> */
+/* L113:       <scc\0> */
+/* L114:       <halt\0> */
+/* L115:       <wait\0> */
+/* L116:       <rti\0> */
+/* L117:       <bpt\0> */
+/* L118:       <iot\0> */
+/* L119:       <reset\0> */
+/* L120:       <rtt\0> */
+/* L121:       <mfpt\0> */
+/* L122:       <cfcc\0> */
+/* L123:       <setf\0> */
+/* L124:       <setd\0> */
+/* L125:       <seti\0> */
+/* L126:       <setl\0> */
+/* L127:       <clrf\0> */
+/* L128:       <negf\0> */
+/* L129:       <absf\0> */
+/* L130:       <tstf\0> */
+/* L131:       <movf\0> */
+/* L132:       <movif\0> */
+/* L133:       <movfi\0> */
+/* L134:       <movof\0> */
+/* L135:       <movfo\0> */
+/* L136:       <addf\0> */
+/* L137:       <subf\0> */
+/* L138:       <mulf\0> */
+/* L139:       <divf\0> */
+/* L140:       <cmpf\0> */
+/* L141:       <modf\0> */
+/* L142:       <movie\0> */
+/* L143:       <movei\0> */
+/* L144:       <ldfps\0> */
+/* L145:       <stfps\0> */
+/* L146:       <fr0\0> */
+/* L147:       <fr1\0> */
+/* L148:       <fr2\0> */
+/* L149:       <fr3\0> */
+/* L150:       <fr4\0> */
+/* L151:       <fr5\0> */
+/* L152:       <mul\0> */
+/* L153:       <div\0> */
+/* L154:       <ash\0> */
+/* L155:       <ashc\0> */
+/* L156:       <xor\0> */
+/* L157:       <sxt\0> */
+/* L158:       <mark\0> */
+/* L159:       <sob\0> */
+/* L160:       <.byte\0> */
+/* L161:       <.even\0> */
+/* L162:       <.if\0> */
+/* L163:       <.endif\0> */
+/* L164:       <.globl\0> */
+/* L165:       <.text\0> */
+/* L166:       <.data\0> */
+/* L167:       <.bss\0> */
+/* L168:       <.comm\0> */
+/*     .text */
+
+struct symbol symtab[] = {
+       { ".",          FTEXT,          0000000,        0 },
+       { "..",         FABS,           0000000,        0 },
+
+/* register */
+
+       { "r0",         FREGISTER,      0000000,        0 },
+       { "r1",         FREGISTER,      0000001,        0 },
+       { "r2",         FREGISTER,      0000002,        0 },
+       { "r3",         FREGISTER,      0000003,        0 },
+       { "r4",         FREGISTER,      0000004,        0 },
+       { "r5",         FREGISTER,      0000005,        0 },
+       { "sp",         FREGISTER,      0000006,        0 },
+       { "pc",         FREGISTER,      0000007,        0 },
+
+/* double operand */
+
+       { "mov",        FDOUBLE,        0010000,        0 },
+       { "movb",       FDOUBLE,        0110000,        0 },
+       { "cmp",        FDOUBLE,        0020000,        0 },
+       { "cmpb",       FDOUBLE,        0120000,        0 },
+       { "bit",        FDOUBLE,        0030000,        0 },
+       { "bitb",       FDOUBLE,        0130000,        0 },
+       { "bic",        FDOUBLE,        0040000,        0 },
+       { "bicb",       FDOUBLE,        0140000,        0 },
+       { "bis",        FDOUBLE,        0050000,        0 },
+       { "bisb",       FDOUBLE,        0150000,        0 },
+       { "add",        FDOUBLE,        0060000,        0 },
+       { "sub",        FDOUBLE,        0160000,        0 },
+
+/* branch */
+
+       { "br",         FBRANCH,        0000400,        0 },
+       { "bne",        FBRANCH,        0001000,        0 },
+       { "beq",        FBRANCH,        0001400,        0 },
+       { "bge",        FBRANCH,        0002000,        0 },
+       { "blt",        FBRANCH,        0002400,        0 },
+       { "bgt",        FBRANCH,        0003000,        0 },
+       { "ble",        FBRANCH,        0003400,        0 },
+       { "bpl",        FBRANCH,        0100000,        0 },
+       { "bmi",        FBRANCH,        0100400,        0 },
+       { "bhi",        FBRANCH,        0101000,        0 },
+       { "blos",       FBRANCH,        0101400,        0 },
+       { "bvc",        FBRANCH,        0102000,        0 },
+       { "bvs",        FBRANCH,        0102400,        0 },
+       { "bhis",       FBRANCH,        0103000,        0 },
+       { "bec",        FBRANCH,        0103000,        0 },
+       { "bcc",        FBRANCH,        0103000,        0 },
+       { "blo",        FBRANCH,        0103400,        0 },
+       { "bcs",        FBRANCH,        0103400,        0 },
+       { "bes",        FBRANCH,        0103400,        0 },
+
+/* jump/branch type */
+
+       { "jbr",        FJBR,           0000400,        0 },
+       { "jne",        FJCOND,         0001000,        0 },
+       { "jeq",        FJCOND,         0001400,        0 },
+       { "jge",        FJCOND,         0002000,        0 },
+       { "jlt",        FJCOND,         0002400,        0 },
+       { "jgt",        FJCOND,         0003000,        0 },
+       { "jle",        FJCOND,         0003400,        0 },
+       { "jpl",        FJCOND,         0100000,        0 },
+       { "jmi",        FJCOND,         0100400,        0 },
+       { "jhi",        FJCOND,         0101000,        0 },
+       { "jlos",       FJCOND,         0101400,        0 },
+       { "jvc",        FJCOND,         0102000,        0 },
+       { "jvs",        FJCOND,         0102400,        0 },
+       { "jhis",       FJCOND,         0103000,        0 },
+       { "jec",        FJCOND,         0103000,        0 },
+       { "jcc",        FJCOND,         0103000,        0 },
+       { "jlo",        FJCOND,         0103400,        0 },
+       { "jcs",        FJCOND,         0103400,        0 },
+       { "jes",        FJCOND,         0103400,        0 },
+
+/* single operand */
+
+       { "clr",        FSINGLE,        0005000,        0 },
+       { "clrb",       FSINGLE,        0105000,        0 },
+       { "com",        FSINGLE,        0005100,        0 },
+       { "comb",       FSINGLE,        0105100,        0 },
+       { "inc",        FSINGLE,        0005200,        0 },
+       { "incb",       FSINGLE,        0105200,        0 },
+       { "dec",        FSINGLE,        0005300,        0 },
+       { "decb",       FSINGLE,        0105300,        0 },
+       { "neg",        FSINGLE,        0005400,        0 },
+       { "negb",       FSINGLE,        0105400,        0 },
+       { "adc",        FSINGLE,        0005500,        0 },
+       { "adcb",       FSINGLE,        0105500,        0 },
+       { "sbc",        FSINGLE,        0005600,        0 },
+       { "sbcb",       FSINGLE,        0105600,        0 },
+       { "tst",        FSINGLE,        0005700,        0 },
+       { "tstb",       FSINGLE,        0105700,        0 },
+       { "ror",        FSINGLE,        0006000,        0 },
+       { "rorb",       FSINGLE,        0106000,        0 },
+       { "rol",        FSINGLE,        0006100,        0 },
+       { "rolb",       FSINGLE,        0106100,        0 },
+       { "asr",        FSINGLE,        0006200,        0 },
+       { "asrb",       FSINGLE,        0106200,        0 },
+       { "asl",        FSINGLE,        0006300,        0 },
+       { "aslb",       FSINGLE,        0106300,        0 },
+       { "jmp",        FSINGLE,        0000100,        0 },
+       { "swab",       FSINGLE,        0000300,        0 },
+       { "mfpi",       FSINGLE,        0006500,        0 },
+       { "mtpi",       FSINGLE,        0006600,        0 },
+       { "mfpd",       FSINGLE,        0106500,        0 },
+       { "mtpd",       FSINGLE,        0106600,        0 },
+       { "stst",       FSINGLE,        0170300,        0 },
+       { "mfps",       FSINGLE,        0106700,        0 },
+       { "mtps",       FSINGLE,        0106400,        0 },
+       { "csm",        FSINGLE,        0007000,        0 },
+       { "tstset",     FSINGLE,        0007200,        0 },
+       { "wrtlck",     FSINGLE,        0007300,        0 },
+
+/* jsr */
+
+       { "jsr",        FJSR,           0004000,        0 },
+
+/* rts */
+
+       { "rts",        FRTS,           0000200,        0 },
+
+/* simple operand */
+
+       { "sys",        FSYSTRAP,       0104400,        0 },
+       { "spl",        FSYSTRAP,       0000230,        0 },
+
+/* flag-setting */
+
+       { "nop",        FABS,           0000240,        0 },
+       { "clc",        FABS,           0000241,        0 },
+       { "clv",        FABS,           0000242,        0 },
+       { "clz",        FABS,           0000244,        0 },
+       { "cln",        FABS,           0000250,        0 },
+       { "ccc",        FABS,           0000257,        0 },
+       { "sec",        FABS,           0000261,        0 },
+       { "sev",        FABS,           0000262,        0 },
+       { "sez",        FABS,           0000264,        0 },
+       { "sen",        FABS,           0000270,        0 },
+       { "scc",        FABS,           0000277,        0 },
+       { "halt",       FABS,           0000000,        0 },
+       { "wait",       FABS,           0000001,        0 },
+       { "rti",        FABS,           0000002,        0 },
+       { "bpt",        FABS,           0000003,        0 },
+       { "iot",        FABS,           0000004,        0 },
+       { "reset",      FABS,           0000005,        0 },
+       { "rtt",        FABS,           0000006,        0 },
+       { "mfpt",       FABS,           0000007,        0 },
+
+/* floating point ops */
+
+       { "cfcc",       FABS,           0170000,        0 },
+       { "setf",       FABS,           0170001,        0 },
+       { "setd",       FABS,           0170011,        0 },
+       { "seti",       FABS,           0170002,        0 },
+       { "setl",       FABS,           0170012,        0 },
+       { "clrf",       FSINGLE,        0170400,        0 },
+       { "negf",       FSINGLE,        0170700,        0 },
+       { "absf",       FSINGLE,        0170600,        0 },
+       { "tstf",       FSINGLE,        0170500,        0 },
+       { "movf",       FMOVF,          0172400,        0 },
+       { "movif",      FFLOP,          0177000,        0 },
+       { "movfi",      FMOVFO,         0175400,        0 },
+       { "movof",      FFLOP,          0177400,        0 },
+       { "movfo",      FMOVFO,         0176000,        0 },
+       { "addf",       FFLOP,          0172000,        0 },
+       { "subf",       FFLOP,          0173000,        0 },
+       { "mulf",       FFLOP,          0171000,        0 },
+       { "divf",       FFLOP,          0174400,        0 },
+       { "cmpf",       FFLOP,          0173400,        0 },
+       { "modf",       FFLOP,          0171400,        0 },
+       { "movie",      FFLOP,          0176400,        0 },
+       { "movei",      FMOVFO,         0175000,        0 },
+       { "ldfps",      FSINGLE,        0170100,        0 },
+       { "stfps",      FSINGLE,        0170200,        0 },
+       { "fr0",        FREGISTER,      0000000,        0 },
+       { "fr1",        FREGISTER,      0000001,        0 },
+       { "fr2",        FREGISTER,      0000002,        0 },
+       { "fr3",        FREGISTER,      0000003,        0 },
+       { "fr4",        FREGISTER,      0000004,        0 },
+       { "fr5",        FREGISTER,      0000005,        0 },
+
+       { "mul",        FMULDIV,        0070000,        0 },
+       { "div",        FMULDIV,        0071000,        0 },
+       { "ash",        FMULDIV,        0072000,        0 },
+       { "ashc",       FMULDIV,        0073000,        0 },
+       { "xor",        FJSR,           0074000,        0 },
+       { "sxt",        FSINGLE,        0006700,        0 },
+       { "mark",       FSYSTRAP,       0006400,        0 },
+       { "sob",        FSOB,           0077000,        0 },
+
+/* pseudo ops */
+
+       { ".byte",      FDOTBYTE,       0000000,        0 },
+#if 1 /* modifications for dec syntax */
+       { ".word",      FDOTWORD,       0000000,        0 },
+#endif
+       { ".even",      FDOTEVEN,       0000000,        0 },
+       { ".if",        FDOTIF,         0000000,        0 },
+       { ".endif",     FDOTENDIF,      0000000,        0 },
+       { ".globl",     FDOTGLOBL,      0000000,        0 },
+       { ".text",      FDOTTEXT,       0000000,        0 },
+       { ".data",      FDOTDATA,       0000000,        0 },
+       { ".bss",       FDOTBSS,        0000000,        0 },
+       { ".comm",      FDOTCOMM,       0000000,        0 }
+};
+
+int ebsymtab = sizeof(symtab) / sizeof(struct symbol);
+
diff --git a/as0.h b/as0.h
new file mode 100644 (file)
index 0000000..85fe820
--- /dev/null
+++ b/as0.h
@@ -0,0 +1,244 @@
+#ifndef _AS0_H
+#define _AS0_H 1
+
+#include "krcompat.h"
+
+/* PSTENTSZ = 6. */
+/* SYMENTSZ = 8. */
+
+struct symbol {
+       char    *name;
+       int     flags;
+       int     value;
+       int     number;
+};
+
+/* User symbols and Permanent Symbol Table entries used to have the */
+/* same 12 byte format.  Merging the two phases of the assembler, moving */
+/* the symbol name characters to an externally allocated heap and */
+/* using a non-contiguous user symbol table meant that the symbol number */
+/* could no longer be calculated by subtracting the base of the symbol */
+/* table and dividing by the size of an entry.  What was done was to */
+/* expand the symbol table entry by another word and keep the symbol number */
+/* in that.  The new internal symbol structure is: */
+
+/*     char    *name; */
+/*     u_short flags; */
+/*     u_short value; */
+/*     u_short number; */
+
+/* SYMBLKSZ = 512. */
+
+#define SYMBLKSZ (512 / sizeof(struct symbol))
+
+struct symblk {
+       struct symblk *next;
+       struct symbol data[SYMBLKSZ];
+};
+
+/* STRBLKSZ = 1024. */
+
+#define STRBLKSZ 1024
+
+struct strblk {
+       struct strblk *next;
+       char data[STRBLKSZ];
+};
+
+/* hshsiz = 3001. */
+
+#define hshsiz 3001
+
+#define TABS 1
+#define TABS2 2
+#define TENDFILE 4
+#define TNEWFILE 5
+#define TNEWLINE '\n'
+#define TEQUAL '='
+#define TCOLON ':'
+#define FGLOBAL 040
+#define TSEMICOLON ';'
+#define TLABEL 0141
+#define TLSH 035
+#define TRSH 036
+#define TOR 037
+#define TSTRING '<'
+#define TCOMMA ','
+#define TLPAREN '('
+#define TMIN '-'
+#define TDOLL '$'
+#define TSTAR '*'
+#define TPLUS '+'
+#define TRPAREN ')'
+#define TSLASH '/'
+#define TAND '&'
+#define TMOD '%'
+#define TLBRACK '['
+#define TCARET '^'
+#define TNOT '!'
+#define TRBRACK ']'
+#define TASCII 0200
+
+#define FABS 1
+#define FTEXT 2
+#define FDATA 3
+#define FBSS 4
+#define FMOVFO 5
+#define FBRANCH 6
+#define FJSR 7
+#define FRTS 010
+#define FSYSTRAP 011
+#define FMOVF 012
+#define FDOUBLE 013
+#define FFLOP 014
+#define FSINGLE 015
+#define FDOTBYTE 016
+#define FSTRING 017
+#define FDOTEVEN 020
+#define FDOTIF 021
+#define FDOTENDIF 022
+#define FDOTGLOBL 023
+#define FREGISTER 024
+#define FDOTTEXT 025
+#define FDOTDATA 026
+#define FDOTBSS 027
+#define FMULDIV 030
+#define FSOB 031
+#define FDOTCOMM 032
+#define FESTTEXT 033
+#define FESTDATA 034
+#define FJBR 035
+#define FJCOND 036
+#if 1 /* modifications for dec syntax */
+#define FDOTWORD 037
+#endif
+
+extern char Newsym;
+extern struct symbol *pdot;
+extern struct symbol *pdotdot;
+extern intptr_t numbertoken;
+extern int numbervalue;
+extern int indirect;
+extern int optoken; /* (sp) */
+extern int rightflags; /* r0 */
+extern int rightvalue; /* r1 */
+extern int leftvalue; /* r2 */
+extern int leftflags; /* r3 */
+extern intptr_t token; /* r4 */
+extern char chartab[TASCII];
+extern char a_tmp1[];
+extern char Ncps;
+extern char *dash;
+extern int fin;
+extern int fout;
+extern intptr_t curfb[10];
+extern intptr_t nxtfb[10];
+extern int curfbr[10];
+extern int savdot[3];
+extern struct symbol **hshtab;
+extern int ch;
+extern int symnum;
+extern char symbol[33];
+extern char inbuf[1024];
+extern int line;
+extern int ifflg;
+extern int nargs;
+extern char **curarg;
+extern int opfound;
+extern int savop;
+extern int numval;
+extern int fbtblsz;
+extern int fbfree;
+extern struct symbol *fbptr;
+extern struct symbol *fbtbl;
+extern struct symblk *usymtab;
+extern int symleft;
+extern struct symbol *symend;
+extern struct symblk *symblk;
+extern int strleft;
+extern char *strend;
+extern struct strblk *strblk;
+extern struct symbol symtab[];
+extern int ebsymtab;
+
+int main PARAMS((int argc, char **argv));
+int oops PARAMS((void));
+void nomem PARAMS((void));
+void error PARAMS((int code));
+void p0putw PARAMS((int word));
+void pass0 PARAMS((void));
+int fbcheck PARAMS((int label));
+void growfb PARAMS((void));
+void rname PARAMS((void));
+struct symbol *isroom PARAMS((struct symbol *psymbol));
+char *astring PARAMS((int len));
+int number PARAMS((void));
+int rch PARAMS((void));
+void p0readop PARAMS((void));
+void escp PARAMS((void));
+void fixor PARAMS((void));
+void retread PARAMS((int c));
+void rdname PARAMS((int c));
+void rdnum PARAMS((void));
+void squote PARAMS((void));
+void dquote PARAMS((void));
+void retnum PARAMS((int value));
+void skip PARAMS((void));
+void garb PARAMS((void));
+void string PARAMS((void));
+int rsch PARAMS((void));
+void p0xpr PARAMS((void));
+void p0opline PARAMS((void));
+void p0opl35 PARAMS((void));
+void p0opl36 PARAMS((void));
+void relative PARAMS((int size));
+void p0opl13 PARAMS((void));
+void p0opl7 PARAMS((void));
+void p0opl15 PARAMS((void));
+void p0opl31 PARAMS((void));
+void p0opl6 PARAMS((void));
+void p0opl10 PARAMS((void));
+void p0opl11 PARAMS((void));
+void p0opl16 PARAMS((void));
+#if 1 /* modifications for dec syntax */
+void p0opldotword PARAMS((void));
+#endif
+void p0opl17 PARAMS((void));
+void p0opl20 PARAMS((void));
+void p0opl21 PARAMS((void));
+void p0opl22 PARAMS((void));
+void p0opl23 PARAMS((void));
+void p0opl25 PARAMS((void));
+void p0opl26 PARAMS((void));
+void p0opl27 PARAMS((void));
+void p0opl32 PARAMS((void));
+void p0addres PARAMS((void));
+void p0getx PARAMS((void));
+void p0alp PARAMS((void));
+void p0amin PARAMS((void));
+void p0adoll PARAMS((void));
+void p0astar PARAMS((void));
+void errora PARAMS((void));
+void p0checkreg PARAMS((void));
+void errore PARAMS((void));
+void p0checkrp PARAMS((void));
+void p0expres PARAMS((void));
+void p0binop PARAMS((void));
+void p0exnum PARAMS((void));
+void p0brack PARAMS((void));
+void p0oprand PARAMS((void));
+void p0excmbin PARAMS((void));
+void p0exrsh PARAMS((void));
+void p0exlsh PARAMS((void));
+void p0exmod PARAMS((void));
+void p0exadd PARAMS((void));
+void p0exsub PARAMS((void));
+void p0exand PARAMS((void));
+void p0exor PARAMS((void));
+void p0exmul PARAMS((void));
+void p0exdiv PARAMS((void));
+void p0exnot PARAMS((void));
+void p0eoprnd PARAMS((void));
+void p0combin PARAMS((int minflag));
+
+#endif
diff --git a/as2.c b/as2.c
new file mode 100644 (file)
index 0000000..1facb21
--- /dev/null
+++ b/as2.c
@@ -0,0 +1,3705 @@
+/* as2.c */
+
+#include <stdio.h> /* temp */
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#ifdef pdp11
+typedef int intptr_t;
+#include <sys/file.h>
+#define SEEK_SET L_SET
+#endif
+#include "as0.h"
+#include "as2.h"
+
+/* Sept 10, 1997 - fix coredump caused by using wrong error reporting */
+/*     calling convention in three places. */
+
+/*     .globl  _signal, _close, _lseek, _unlink, _umask, _chmod, __exit */
+/*     .globl  _write, _read, _brk, _end, _open, _realloc, _fchmod */
+/*     .globl  pass1, hshsiz, outmod, dot, dotdot, error */
+/*     .globl  checkeos, curfb, savdot, ch, line, savop, inbuf, errflg */
+/*     .globl  fbptr, fbtbl, symnum, hshtab, symblk, symleft, dotrel */
+/*     .globl  symtab, aexit, overlaid, defund, a.outp, passno, filerr */
+/*     .globl  wrterr, argb, curfb, nxtfb, usymtab */
+/*     .globl  fin, fout, a.tmp1, ibufc, ibufp, obufp, outbuf, symbol */
+/*     .globl  PSTENTSZ, SYMENTSZ, SYMBLKSZ, Newsym */
+
+intptr_t *adrptr; /* r5 */
+int opcode; /* (sp) or 2(sp) if rvalue is present */
+int rvalue; /* (sp) */
+#ifdef LISTING
+FILE *argfp;
+#endif
+
+/* pass1: */
+/*     mov     fout,fin                / tmp file is now input file */
+/*     mov     $666,-(sp)              / mode */
+/*     mov     $3001 ,-(sp)            / O_WRONLY|O_CREAT|O_TRUNC */
+/*     mov     a.outp,-(sp)            / filename */
+/*     jsr     pc,_open */
+/*     add     $6,sp */
+/*     mov     r0,fout                 / file descriptor any good? */
+/*     bpl     1f                      / yes - br */
+/*     mov     a.outp,-(sp) */
+/*     jsr     pc,filerr */
+/* 1: */
+
+void pass1() {
+       int symtot;
+       struct symbol *psymbol;
+       struct symbol **ppsymbol;
+       int flags;
+
+       fin = fout;
+       fout = open(a_outp, O_WRONLY|O_CREAT|O_TRUNC, 0666);
+       if (fout < 0)
+               filerr(a_outp);
+
+/* 'symnum' has number of symbols.  The hashtable from pass 0 is no */
+/* longer needed - we can reuse it directly for 'usymtab' if there are less  */
+/* than 'hshsiz' symbols.  If there are more than 'hshsiz' (currently */
+/* 1500) symbols we have to realloc. */
+
+/* The 'fb' table (usually 0 long) is appended to the 'usymtab' (4 byte */
+/* entries per symbol). */
+
+/*     mov     fbptr,r0 */
+/*     sub     fbtbl,r0                / # bytes in 'fb' table */
+/*     asr     r0                      / convert to number of words */
+/*     add     symnum,r0               / add in number of symbols twice */
+/*     add     symnum,r0               / because we need 2 words per symbol */
+/*     inc     r0                      / one more for terminator word */
+
+       symtot = (fbptr - fbtbl) + symnum + 1;
+
+/*     cmp     r0,$hshsiz              / is hashtable big enough already? */
+/*     blo     1f                      / yes -br */
+/*     asl     r0                      / convert to bytes */
+/*     mov     r0,-(sp) */
+/*     mov     hshtab,-(sp) */
+/*     jsr     pc,_realloc             / hshtab = realloc(hshtab, r0) */
+/*     mov     r0,hshtab */
+/*     bne     1f */
+/*     iot                             / should never happen */
+/* 1: */
+
+       if (symtot > hshsiz) {
+               hshtab = (struct symbol **)realloc(hshtab, symtot * sizeof(struct symbol *));
+               if (hshtab == NULL)
+                       nomem();
+       }
+
+/*     mov     hshtab,r1 */
+/*     mov     usymtab,r2 */
+/* 9: */
+/*     mov     r2,symblk               / save ptr to start of block */
+/*     tst     (r2)+                   / skip link word */
+/*     mov     $SYMBLKSZ,symleft       / init amount left in block */
+
+       ppsymbol = hshtab;
+       symblk = usymtab;
+       do {
+               psymbol = symblk->data;
+               symleft = SYMBLKSZ;
+
+/* 1: */
+/*     tst     (r2)                    / end of symbol table block */
+/*     beq     4f                      / yes - br */
+/*     add     $8.,symsiz              / size of symbol table */
+/*     tst     Newsym                  / are we doing new style? */
+/*     bne     8f                      / yes - br */
+/*     add     $4,symsiz               / no, symbol table entries are bigger */
+/* 8: */
+
+               do {
+                       if (psymbol->name == NULL)
+                               break;
+/* printf("%s\n", psymbol->name); */
+                       siz[3] += Newsym ? 8 : 12;
+
+/*     mov     2(r2),r0                / flags word */
+/*     bic     $!37,r0 */
+/*     cmp     r0,$2                   /text */
+/*     blo     2f */
+/*     cmp     r0,$3                   /data */
+/*     bhi     2f */
+/*     add     $31,r0                  /mark "estimated" */
+/*     mov     r0,(r1)+                / store flags word */
+/*     mov     4(r2),(r1)+             / copy value word */
+/*     br      3f */
+/* 2: */
+/*     clr     (r1)+ */
+/*     clr     (r1)+ */
+/* 3: */
+
+                       flags = psymbol->flags & 037;
+                       if (flags == FTEXT || flags == FDATA)
+                               psymbol->flags = flags + FESTTEXT - FTEXT;
+                       else {
+                               psymbol->flags = 0;
+                               psymbol->value = 0;
+                       }
+
+/*     add     $SYMENTSZ,r2            / skip to next symbol entry */
+/*     sub     $SYMENTSZ,symleft       / one symbol less in block */
+/*     cmp     symleft,$SYMENTSZ       / room for another symbol? */
+/*     bge     1b                      / yes - br */
+
+/* printf("0x%08x 0x%08x\n", (ppsymbol - hshtab), psymbol->number); */
+                       *ppsymbol++ = psymbol++;
+                       symleft--;
+               } while (symleft);
+
+/* 4: */
+/*     mov     *symblk,r2              / follow link to next block */
+/*     bne     9b                      / if not at end */
+/* 1: */
+
+               symblk = symblk->next;
+       } while (symblk);
+
+/* The 'fb' table needs to be appended to the 'usymtab' table now */
+
+/*     mov     fbtbl,r0 */
+/*     mov     r1,fbbufp               / save start of 'fb' table */
+/* 1: */
+/*     cmp     r0,fbptr                / at end of table? */
+/*     bhis    2f                      / yes - br */
+/*     mov     (r0)+,r4 */
+/*     add     $31,r4                  / "estimated" */
+/*     mov     r4,(r1)+ */
+/*     mov     (r0)+,(r1)+ */
+/*     br      1b */
+/* 2: */
+
+       psymbol = fbtbl;
+       fbbufp = ppsymbol;
+       while (psymbol < fbptr) {
+               psymbol->flags += FESTTEXT - FTEXT; /* FESTBSS ??? */
+               *ppsymbol++ = psymbol++;
+       }
+
+/*     mov     r1,endtable */
+/*     mov     $100000,(r1)+ */
+
+       endtable = ppsymbol;
+       *ppsymbol++ = NULL;
+
+/*     mov     $savdot,r0              / reset the 'psect' (text,data,bss) */
+/*     clr     (r0)+                   / counters for the next pass */
+/*     clr     (r0)+ */
+/*     clr     (r0)+ */
+/*     jsr     pc,setup                / init fb stuff */
+
+       savdot[0] = 0;
+       savdot[1] = 0;
+       savdot[2] = 0;
+       setup();
+
+/*     jsr     pc,pass1_2              / do pass 1 */
+
+       pass1_2();
+
+/* prepare for pass 2 */
+/*     inc     passno */
+/*     cmp     outmod,$777 */
+/*     beq     1f */
+/*     jsr     pc,aexit */
+/* not reached */
+/* 1: */
+
+#ifdef LISTING
+       printf("pass 2\n");
+#endif
+       passno++;
+       if (outmod != 0777)
+               aexit();
+
+/*     jsr     pc,setup */
+/*     inc     bsssiz */
+/*     bic     $1,bsssiz */
+/*     mov     txtsiz,r1 */
+/*     inc     r1 */
+/*     bic     $1,r1 */
+/*     mov     r1,txtsiz */
+/*     mov     datsiz,r2 */
+/*     inc     r2 */
+/*     bic     $1,r2 */
+/*     mov     r2,datsiz */
+
+       setup();
+       siz[0] = (siz[0] + 1) & ~1;
+       siz[1] = (siz[1] + 1) & ~1;
+       siz[2] = (siz[2] + 1) & ~1;
+
+/*     mov     r1,r3 */
+/*     mov     r3,datbase              / txtsiz */
+/*     mov     r3,savdot+2 */
+/*     add     r2,r3 */
+/*     mov     r3,bssbase              / txtsiz+datsiz */
+/*     mov     r3,savdot+4 */
+
+       base[1] = siz[0];
+       savdot[1] = base[1];
+       base[2] = base[1] + siz[1];
+       savdot[2] = base[2];
+
+/*     clr     r0 */
+/*     asl     r3 */
+/*     adc     r0 */
+/*     add     $20,r3 */
+/*     adc     r0 */
+/*     mov     r3,symseek+2            / 2*txtsiz+2*datsiz+20 */
+/*     mov     r0,symseek */
+
+       seek[6] = (off_t)base[2] * 2 + 020;
+
+/*     sub     r2,r3 */
+/*     sbc     r0 */
+/*     mov     r3,drelseek+2           / 2*txtsiz+datsiz */
+/*     mov     r0,drelseek */
+
+       seek[4] = seek[6] - siz[1];
+
+/*     sub     r1,r3 */
+/*     sbc     r0 */
+/*     mov     r3,trelseek+2           / txtsiz+datsiz+20 */
+/*     mov     r0,trelseek */
+
+       seek[3] = seek[4] - siz[0];
+
+/*     sub     r2,r3 */
+/*     sbc     r0 */
+/*     mov     r0,datseek */
+/*     mov     r3,datseek+2            / txtsiz+20 */
+
+       seek[1] = seek[3] - siz[1];
+       seek[0] = 020;
+
+/*     mov     hshtab,r1 */
+/* 1: */
+/*     jsr     pc,doreloc */
+/*     add     $4,r1 */
+/*     cmp     r1,endtable */
+/*     blo     1b */
+
+       for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++)
+               doreloc(*ppsymbol);
+
+/*     clr     r0 */
+/*     clr     r1 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,oset */
+/*     mov     trelseek,r0 */
+/*     mov     trelseek+2,r1 */
+/*     mov     $relp,-(sp) */
+/*     jsr     pc,oset */
+
+       oset(&txtp, 0L);
+       oset(&relp, seek[3]);
+
+/*     mov     $8.,r2 */
+/*     mov     $txtmagic,r1 */
+/* 1: */
+/*     mov     (r1)+,r0 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+/*     sob     r2,1b */
+
+       p1putw(&txtp, 0407);
+       p1putw(&txtp, siz[0]);
+       p1putw(&txtp, siz[1]);
+       p1putw(&txtp, siz[2]);
+       p1putw(&txtp, siz[3]);
+       p1putw(&txtp, 0);
+       p1putw(&txtp, 0);
+       p1putw(&txtp, 0);
+
+/*     jsr     pc,pass1_2                      / do pass 2 */
+
+       pass1_2();
+#ifdef LISTING
+       if (argfp)
+               fclose(argfp);
+#endif
+
+/*polish off text and relocation */
+
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,flush */
+/*     mov     $relp,-(sp) */
+/*     jsr     pc,flush */
+
+       flush(&txtp);
+       flush(&relp);
+
+/* append full symbol table */
+/*     mov     symseek,r0 */
+/*     mov     symseek+2,r1 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,oset */
+
+       oset(&txtp, seek[6]);
+
+/*     mov     usymtab,r2              / pointer to first symbol block */
+/*     mov     hshtab,r1               / 'type' and 'value' array */
+/*     tst     Newsym */
+/*     beq     8f */
+/*     jsr     pc,nsymout */
+/*     br      9f */
+/* 8: */
+/*     jsr     pc,osymout */
+/* 9: */
+
+       if (Newsym)
+               nsymout();
+       else
+               osymout();
+
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,flush */
+/*     jsr     pc,aexit */
+/* not reached */
+
+       flush(&txtp);
+       aexit();
+}
+
+/* saexit: */
+/*     mov     pc,errflg */
+
+void saexit() {
+       errflg = 3;
+       aexit();
+}
+
+/* aexit: */
+/*     mov     $a.tmp1,-(sp)           / unlink(a.tmp1) */
+/*     jsr     pc,_unlink */
+
+int aexit() {
+#if 1
+       unlink(a_tmp1);
+#endif
+
+/*     tst     errflg */
+/*     bne     2f */
+
+       if (errflg == 0) {
+
+/*     clr     (sp) */
+/*     jsr     pc,_umask */
+
+/*     bic     r0,outmod               / fchmod(fout, outmod&umask(0)) */
+/*     mov     outmod,(sp) */
+/*     mov     fout,-(sp) */
+/*     jsr     pc,_fchmod */
+/*     tst     (sp)+ */
+/*     clr     (sp) */
+/*     br      1f */
+
+               fchmod(fout, outmod & ~umask(0));
+               exit(0);
+       }
+
+/* 2: */
+/*     mov     $2,(sp) */
+/* 1: */
+/*     jsr     pc,__exit               / _exit(errflg ? 2 : 0) */
+
+       exit(2);
+}
+
+/* filerr: */
+/*     mov     2(sp),r0                / filename string.  no need to clean */
+/*     tst     -(sp)                   / stack, this routine goes to saexit. */
+/*     mov     r0,-(sp) */
+/*     mov     $1,-(sp) */
+/* 1: */
+/*     tstb    (r0)+ */
+/*     bne     1b */
+/*     sub     2(sp),r0 */
+/*     dec     r0 */
+/*     mov     r0,4(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+
+void filerr(p) char *p; {
+       write(1, p, strlen(p));
+
+/*     mov     $2,-(sp)                / write(1, "?\n", 2) */
+/*     mov     $qnl,-(sp) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+/*     tst     passno */
+/*     bpl     saexit */
+/*     rts     pc */
+
+       write(1, "?\n", 2);
+       if (passno >= 0)
+               saexit();
+}
+
+/* osymout: */
+/* 9: */
+/*     mov     r2,symblk               / save ptr to current sym block */
+/*     tst     (r2)+                   / skip link word */
+/*     mov     $SYMBLKSZ,symleft       / space left in symbol block */
+/* 1: */
+/*     mov     (r2),r4                 / pointer to symbol name */
+/*     beq     4f                      / end of block - br */
+
+void osymout() {
+       struct symbol **ppsymbol;
+       struct symbol *psymbol;
+       char *p;
+
+       for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++) {
+               psymbol = *ppsymbol;
+               p = psymbol->name;
+               if (p == NULL)
+                       break; /* reached the start of the fbtab */
+
+/*     mov     $8.,r5                  / max number to copy */
+/*     mov     $symbol,r0              / destination buffer */
+/* 2: */
+/*     movb    (r4),(r0)+              / copy a byte */
+/*     beq     6f */
+/*     inc     r4                      / non null - bump source ptr */
+/* 6: */
+/*     sob     r5,2b */
+
+               strncpy(symbol, p, 8);
+
+/* Now put four words of symbol name to the object file */
+/*     mov     $4,r5                   / number of words to do */
+/*     mov     $symbol,r4 */
+/* 6: */
+/*     mov     (r4)+,r0                / word (2 chars) of symbol name */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+/*     sob     r5,6b */
+
+               p1putw(&txtp, (symbol[0] & 0377) | ((symbol[1] & 0377) << 8));
+               p1putw(&txtp, (symbol[2] & 0377) | ((symbol[3] & 0377) << 8));
+               p1putw(&txtp, (symbol[4] & 0377) | ((symbol[5] & 0377) << 8));
+               p1putw(&txtp, (symbol[6] & 0377) | ((symbol[7] & 0377) << 8));
+
+/* values from 'hshtab' (parallel array to symbol table) are retrieved now, */
+/* they take the place of the flags and value entries of the symbol table. */
+/*     mov     (r1)+,r0 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+/*     mov     (r1)+,r0 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+
+               p1putw(&txtp, psymbol->flags);
+               p1putw(&txtp, psymbol->value);
+
+/*     add     $SYMENTSZ,r2            / skip to next symbol */
+/*     sub     $SYMENTSZ,symleft       / one less symbol in block */
+/*     cmp     symleft,$SYMENTSZ       / room for another? */
+/*     bge     1b                      / yes - br */
+/* 4: */
+/*     mov     *symblk,r2              / no, follow link to next block */
+/*     bne     9b                      / unless it's end of list */
+/*     rts     pc */
+
+       }
+}
+
+/* nsymout: */
+/*     clr     totalsz */
+/*     mov     $4,totalsz+2            / string table min size is 4 */
+
+void nsymout() {
+       struct symbol **ppsymbol;
+       struct symbol *psymbol;
+       char *p;
+
+       totalsz = 4;
+
+/* 9: */
+/*     mov     r2,symblk               / save ptr to current symbol block */
+/*     tst     (r2)+                   / skip link word */
+/*     mov     $SYMBLKSZ,symleft       / amount of space left in block */
+/* 1: */
+/*     mov     (r2),r4                 / pointer to symbol's string */
+/*     beq     4f                      / end of block - br */
+
+       for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++) {
+               psymbol = *ppsymbol;
+               p = psymbol->name;
+               if (p == NULL)
+                       break; /* reached the start of the fbtab */
+
+/*     mov     totalsz,r0              / now output the... */
+/*     mov     $txtp,-(sp)             / high order of the string index... */
+/*     jsr     pc,putw                 / to the object file */
+/*     mov     totalsz+2,r0 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw                 / and the low order word */
+/* 2: */
+/*     tstb    (r4)+                   / find the end of the string */
+/*     bne     2b */
+/*     sub     (r2),r4                 / compute length including the null */
+/*     add     r4,totalsz+2            / offset of next string */
+/*     adc     totalsz */
+
+               p1putw(&txtp, (int)(totalsz >> 16) & 0177777);
+               p1putw(&txtp, (int)totalsz & 0177777);
+               totalsz += strlen(p) + 1;
+
+/*     mov     (r1)+,r0                / 'type' word of symbol */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+/*     mov     (r1)+,r0                / 'value' word of symbol */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+
+               p1putw(&txtp, psymbol->flags);
+               p1putw(&txtp, psymbol->value);
+
+/*     add     $SYMENTSZ,r2            / advance to next symbol */
+/*     sub     $SYMENTSZ,symleft       / adjust amount left in symbol block */
+/*     cmp     symleft,$SYMENTSZ       / is there enough for another symbol? */
+/*     bge     1b                      / yes - br */
+/* 4: */
+/*     mov     *symblk,r2              / follow link to next symbol block */
+/*     bne     9b                      / more - br */
+
+       }
+
+/*     mov     totalsz,r0              / now output the string table length */
+/*     mov     $txtp,-(sp)             / high order word first */
+/*     jsr     pc,putw */
+/*     mov     totalsz+2,r0            / followed by the low order */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+
+       p1putw(&txtp, (int)(totalsz >> 16) & 0177777);
+       p1putw(&txtp, (int)totalsz & 0177777);
+
+/* Now write the strings out */
+
+/*     mov     usymtab,r2              / start at beginning of symbols */
+/* 9: */
+/*     mov     r2,symblk               / save pointer to current block */
+/*     tst     (r2)+                   / skip link word */
+/*     mov     $SYMBLKSZ,symleft       / amount left in block */
+/* 1: */
+/*     mov     (r2),r4                 / pointer to symbol's string */
+/*     beq     4f                      / at end of block - br */
+
+       for (ppsymbol = hshtab; ppsymbol < endtable; ppsymbol++) {
+               psymbol = *ppsymbol;
+               p = psymbol->name;
+               if (p == NULL)
+                       break; /* reached the start of the fbtab */
+
+/*     jsr     pc,putstring            / write out the string */
+
+               putstring(p);
+
+/*     add     $SYMENTSZ,r2            / advance to next symbol */
+/*     sub     $SYMENTSZ,symleft       / adjust amount left in block */
+/*     cmp     symleft,$SYMENTSZ       / enough for another symbol? */
+/*     bge     1b                      / yes - br */
+/* 4: */
+/*     mov     *symblk,r2              / move to next block of symbols */
+/*     bne     9b                      / any left - br */
+
+       }
+
+/* probably not necessary but let us leave the file size on an even */
+/* byte boundary. */
+
+/*     bit     $1,totalsz+2            / odd number of bytes in string table? */
+/*     beq     5f                      / no - br */
+/*     mov     symblk,r4               / we know 'symblk' points to a null */
+/*     jsr     pc,putstring            / output a single null */
+/* 5: */
+/*     rts     pc */
+
+       if (totalsz & 1) {
+               putstring("");
+       }
+}
+
+/* R4 has the address of a null terminated string to write to the output */
+/* file.  The terminating null is included in the output.  This routine */
+/* "inlines" the 'txtp seek structure' manipulation because the 'putw' */
+/* routine was 1) not suitable to byte output and 2) symbol strings are */
+/* only written using the 'txtp' (as opposed to 'relp' - relocation info) */
+/* structure. */
+
+/* putstring: */
+
+void putstring(p) char *p; {
+       while (1) {
+
+/*     cmp     txtp,txtp+2             / room for another byte? */
+/*     bhis    1f                      / no - br */
+/* 3: */
+/*     movb    (r4),*txtp              / put byte in buffer */
+/*     inc     txtp                    / advance output position */
+/*     tstb    (r4)+                   / did we just do the null? */
+/*     bne     putstring               / no - go again */
+/*     rts     pc                      / yes - we're done, return */
+
+               while (txtp.append < txtp.limit) {
+                       *txtp.append++ = *p;
+                       if (*p++ == 0)
+                               return;
+               }
+
+/* 1: */
+/*     mov     r2,-(sp)                / save r2 from being destroyed */
+/*     mov     $txtp,-(sp)             / flush buffered output and... */
+/*     jsr     pc,flush                / reset the pointers */
+/*     mov     (sp)+,r2                / restore symbol pointer */
+/*     br      3b                      / go output a byte */
+
+               flush(&txtp);
+       }
+}
+
+/* doreloc: */
+/*     movb    (r1),r0 */
+/*     bne     1f */
+/*     bisb    defund,(r1) */
+/* 1: */
+
+void doreloc(psymbol) struct symbol *psymbol; {
+       int flags;
+
+       flags = psymbol->flags;
+       if (flags == 0)
+               psymbol->flags = defund;
+
+/*     bic     $!37,r0 */
+/*     cmp     r0,$5 */
+/*     bhis    1f */
+/*     cmp     r0,$3 */
+/*     blo     1f */
+/*     beq     2f */
+
+       flags &= 037;
+       switch (flags) {
+
+/*     add     bssbase,2(r1) */
+/*     rts     pc */
+
+       case FBSS:
+               psymbol->value += base[2];
+               break;
+
+/* 2: */
+/*     add     datbase,2(r1) */
+/* 1: */
+/*     rts     pc */
+
+       case FDATA:
+               psymbol->value += base[1];
+               break;
+       }
+}
+
+/* setup: */
+/*     clr     dot */
+/*     mov     $2,dotrel */
+/*     mov     $..,dotdot */
+/*     clr     brtabp */
+
+void setup() {
+       int label;
+
+       pdot->value = 0;
+       pdot->flags = FTEXT;
+       pdotdot->value = 0;
+       brtabp = 0;
+
+/*     mov     $curfb,r4 */
+/* 1: */
+/*     clr     (r4)+ */
+/*     cmp     r4,$curfb+40. */
+/*     blo     1b */
+
+       memset(curfb, 0, 10 * sizeof(intptr_t));
+       memset(nxtfb, 0, 10 * sizeof(intptr_t));
+
+/*     clr     r4 */
+/* 1: */
+/*     jsr     pc,fbadv */
+/*     inc     r4 */
+/*     cmp     r4,$10. */
+/*     blt     1b */
+
+       for (label = 0; label < 10; label++)
+               fbadv(label);
+
+/* just rewind /tmp/atm1xx rather than close and re-open */
+/*     clr     -(sp) */
+/*     clr     -(sp) */
+/*     clr     -(sp) */
+/*     mov     fin,-(sp) */
+/*     jsr     pc,_lseek               / lseek(fin, 0L, 0) */
+/*     add     $8.,sp */
+
+       lseek(fin, 0L, SEEK_SET);
+
+/*     clr     ibufc */
+/*     rts     pc */
+
+       ibufc = 0;
+}
+
+/* outw: */
+/*     cmp     dot-2,$4 */
+/*     beq     9f */
+
+void outw(value, flags) int value; int flags; {
+       int relocate;
+
+#ifdef LISTING
+       if (passno)
+               printf("%04x: %04x (%04x)\n", pdot->value, value & 0177777,
+                               flags);
+#endif
+       if (pdot->flags != FBSS) {
+
+/*     bit     $1,dot */
+/*     bne     1f */
+
+               if ((pdot->value & 1) == 0) {
+
+/*     add     $2,dot */
+/*     tst     passno */
+/*     beq     8f */
+
+                       pdot->value += 2;
+                       if (passno == 0)
+                               return;
+
+/*     clr     -(sp) */
+/*     rol     r3 */
+/*     adc     (sp) */
+/*     asr     r3                      / get relative pc bit */
+/*     cmp     r3,$40 */
+/*     bne     2f */
+
+                       relocate = (flags >> 15) & 1;
+                       flags &= 077777;
+                       if (flags == FGLOBAL) {
+
+/* external references */
+/*     mov     $666,outmod             / make nonexecutable */
+/*     mov     xsymbol,r3 */
+/*     sub     hshtab,r3 */
+/*     asl     r3 */
+/*     bis     $4,r3                   / external relocation */
+/*     br      3f */
+/* 2: */
+
+                               outmod = 0666;
+                               flags = (xsymbol->number << 3) | 4;
+                       }
+
+/*     bic     $40,r3                  / clear any ext bits */
+/*     cmp     r3,$5 */
+/*     blo     4f */
+/*     cmp     r3,$33                  / est. text, data */
+/*     beq     6f */
+/*     cmp     r3,$34 */
+/*     bne     7f */
+/* 6: */
+/*     mov     $'r,-(sp) */
+/*     jsr     pc,error */
+/* 7: */
+/*     mov     $1,r3                   / make absolute */
+/* 4: */
+
+                       else {
+                               flags &= ~FGLOBAL;
+                               if (flags > FBSS) {
+                                       if (flags == FESTTEXT ||
+                                                       flags == FESTDATA)
+                                               error('r');
+                                       flags = FABS;
+                               }
+
+/*     cmp     r3,$2 */
+/*     blo     5f */
+/*     cmp     r3,$4 */
+/*     bhi     5f */
+/*     tst     (sp) */
+/*     bne     4f */
+/*     add     dotdot,r2 */
+/*     br      4f */
+/* 5: */
+
+                               if (flags >= FTEXT && flags <= FBSS) {
+                                       if (!relocate)
+                                               value += pdotdot->value;
+                               }
+
+/*     tst     (sp) */
+/*     beq     4f */
+/*     sub     dotdot,r2 */
+/* 4: */
+
+                               else {
+                                       if (relocate)
+                                               value -= pdotdot->value;
+                               }
+
+/*     dec     r3 */
+/*     bpl     3f */
+/*     clr     r3 */
+
+                               if (flags)
+                                       flags--;
+                       }
+
+/* 3: */
+/*     asl     r3 */
+/*     bis     (sp)+,r3 */
+
+                       flags = (flags << 1) | relocate;
+
+/*     mov     r2,r0 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+/*     mov     tseekp,r0 */
+/*     add     $2,2(r0) */
+/*     adc     (r0) */
+
+                       p1putw(&txtp, value);
+                       *tseekp += 2;
+
+/*     mov     r3,r0 */
+/*     mov     $relp,-(sp) */
+/*     jsr     pc,putw */
+/*     mov     rseekp,r0 */
+/*     add     $2,2(r0) */
+/*     adc     (r0) */
+
+                       p1putw(&relp, flags);
+                       *rseekp += 2;
+
+/* 8: */
+/*     rts     pc */
+
+               }
+
+/* 1: */
+/*     mov     $'o,-(sp) */
+/*     jsr     pc,error */
+/*     clr     r3 */
+/*     jsr     pc,outb */
+/*     rts     pc */
+
+               else {
+                       error('o');
+                       outb(value, 0);
+               }
+
+/* 9: */
+/*     mov     $'x,-(sp) */
+/*     jsr     pc,error */
+/*     rts     pc */
+
+       }
+       else
+               error('x');
+}
+
+/* outb: */
+/*     cmp     dot-2,$4                / test bss mode */
+/*     beq     9b */
+
+void outb(value, flags) int value; int flags; {
+#ifdef LISTING
+       if (passno)
+               printf("%04x:   %02x (%04x)\n", pdot->value, value & 0377,
+                               flags);
+#endif
+       if (pdot->flags == FBSS) {
+               error('x');
+               return;
+ /* bug!! didn't increment dot's value */
+       }
+
+/*     cmp     r3,$1 */
+/*     blos    1f */
+/*     mov     $'r,-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+
+       if (flags > FABS)
+               error('r');
+
+/*     tst     passno */
+/*     beq     2f */
+
+       if (passno) {
+
+/*     mov     r2,r0 */
+/*     bit     $1,dot */
+/*     bne     1f */
+
+               if ((pdot->value & 1) == 0) {
+
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,putw */
+/*     clr     r0 */
+/*     mov     $relp,-(sp) */
+/*     jsr     pc,putw */
+
+                       p1putw(&txtp, value);
+                       p1putw(&relp, 0);
+
+/*     mov     tseekp,r0 */
+/*     add     $2,2(r0) */
+/*     adc     (r0) */
+/*     mov     rseekp,r0 */
+/*     add     $2,2(r0) */
+/*     adc     (r0) */
+/*     br      2f */
+
+                       *tseekp += 2;
+                       *rseekp += 2;
+               }
+
+/* 1: */
+/*     mov     txtp,r0 */
+/*     movb    r2,-1(r0) */
+
+               else
+                       *(txtp.append - 1) = (char)value;
+       }
+
+/* 2: */
+/*     inc     dot */
+/*     rts     pc */
+
+       pdot->value++;
+}
+
+/* pass 1 and 2 common code */
+
+/* pass1_2: */
+/*     jsr     pc,readop */
+/*     cmp     r4,$5 */
+/*     beq     2f */
+/*     cmp     r4,$'< */
+/*     beq     2f */
+/*     jsr     pc,checkeos */
+/*             br eal1 */
+
+void pass1_2() {
+       intptr_t tokensave;
+       int flags;
+       struct symbol *psymbol;
+       int label;
+#ifdef LISTING
+       int argch;
+#endif
+
+       while (1) {
+               readop();
+               if (token != TNEWFILE && token != TSTRING) {
+                       if (checkeos())
+                               goto eal1;
+
+/*     mov     r4,-(sp) */
+/*     cmp     (sp),$1 */
+/*     bne     1f */
+/*     mov     $2,(sp) */
+/*     jsr     pc,getw */
+/*     mov     r4,numval */
+/* 1: */
+
+                       tokensave = token;
+                       if (token == TABS) {
+                               tokensave = TABS2;
+                               p1getw();
+                               numval = token;
+                       }
+
+/*     jsr     pc,readop */
+/*     cmp     r4,$'= */
+/*     beq     4f */
+/*     cmp     r4,$': */
+/*     beq     1f */
+/*     mov     r4,savop */
+/*     mov     (sp)+,r4 */
+/* 2: */
+/*     jsr     pc,opline */
+
+                       readop();
+                       if (token == TEQUAL)
+                               goto equal;
+                       if (token == TCOLON)
+                               goto colon;
+                       savop = token;
+                       token = tokensave;
+               }
+               opline();
+
+/* dotmax: */
+/*     tst     passno */
+/*     bne     eal1 */
+/*     movb    dotrel,r0 */
+/*     asl     r0 */
+/*     cmp     dot,txtsiz-4(r0) */
+/*     bhi     8f */
+/*     jmp     ealoop */
+/* 8: */
+/*     mov     dot,txtsiz-4(r0) */
+/* eal1: */
+/*     jmp     ealoop */
+
+       dotmax:
+               if (passno == 0) {
+                       flags = pdot->flags - FTEXT;
+                       if (siz[flags] < pdot->value)
+                               siz[flags] = pdot->value;
+               }
+       eal1:
+               goto ealoop;
+
+/* 1: */
+/*     mov     (sp)+,r4 */
+/*     cmp     r4,$200 */
+/*     bhis    1f */
+/*     cmp     r4,$2 */
+/*     beq     3f */
+/*     mov     $'x,-(sp) */
+/*     jsr     pc,error */
+/*     br      pass1_2 */
+/* 1: */
+
+       colon:
+               if (tokensave >= 0 && tokensave < TASCII) {
+                       if (tokensave != TABS2) {
+                               error('x');
+                               continue;
+                       }
+                       goto digit;
+               }
+
+/*     tst     passno */
+/*     bne     2f */
+/*     movb    (r4),r0 */
+/*     bic     $!37,r0 */
+/*     beq     5f */
+/*     cmp     r0,$33 */
+/*     blt     6f */
+/*     cmp     r0,$34 */
+/*     ble     5f */
+/* 6: */
+/*     mov     $'m,-(sp) */
+/*     jsr     pc,error */
+/* 5: */
+
+               psymbol = (struct symbol *)tokensave;
+               if (passno == 0) {
+                       flags = psymbol->flags & 037;
+                       if (flags && (flags < FESTTEXT || flags > FESTDATA))
+                               error('m');
+
+/*     bic     $37,(r4) */
+/*     bis     dotrel,(r4) */
+/*     mov     2(r4),brdelt */
+/*     sub     dot,brdelt */
+/*     mov     dot,2(r4) */
+/*     br      pass1_2 */
+
+                       psymbol->flags = (psymbol->flags & ~037) | pdot->flags;
+                       brdelt = psymbol->value - pdot->value;
+                       psymbol->value = pdot->value;
+                       continue;
+               }
+
+/* 2: */
+/*     cmp     dot,2(r4) */
+/*     beq     pass1_2 */
+/*     mov     $'p,-(sp) */
+/*     jsr     pc,error */
+/*     br      pass1_2 */
+
+               if (psymbol->value != pdot->value)
+                       error('p');
+#ifdef LISTING
+               printf("%04x: %s\n", psymbol->value & 0177777, psymbol->name);
+#endif
+               continue;
+
+/* 3: */
+/*     mov     numval,r4 */
+/*     jsr     pc,fbadv */
+/*     asl     r4 */
+/*     mov     curfb(r4),r0 */
+/*     movb    dotrel,(r0) */
+/*     mov     2(r0),brdelt */
+/*     sub     dot,brdelt */
+/*     mov     dot,2(r0) */
+/*     br      pass1_2 */
+
+       digit:
+               label = numval;
+               fbadv(label);
+               psymbol = *(struct symbol **)curfb[label];
+               psymbol->flags = pdot->flags;
+               brdelt = psymbol->value - pdot->value;
+               psymbol->value = pdot->value;
+#ifdef LISTING
+               if (passno)
+                       printf("%04x: %d\n", psymbol->value & 0177777, label);
+#endif
+               continue;
+
+/* 4: */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres */
+/*     mov     (sp)+,r1 */
+/*     cmp     r1,$dotrel              /test for dot */
+/*     bne     1f */
+/*     bic     $40,r3 */
+/*     cmp     r3,dotrel               / can't change relocation */
+/*     bne     2f */
+
+       equal:
+               readop();
+               expres();
+               psymbol = (struct symbol *)tokensave;
+               if (psymbol == pdot) {
+                       leftflags &= ~FGLOBAL;
+/* printf("leftflags 0%o pdot->flags 0%o\n", leftflags, pdot->flags); */
+                       if (leftflags != pdot->flags)
+                               goto doterr;
+
+/*     cmp     r3,$4                   / bss */
+/*     bne     3f */
+/*     mov     r2,dot */
+/*     br      dotmax */
+/* 3: */
+
+                       if (leftflags == FBSS) {
+                               pdot->value = leftvalue;
+#ifdef LISTING
+                       if (passno)
+                               printf("%04x: .\n", pdot->value & 0177777);
+#endif
+                               goto dotmax;
+                       }
+
+/*     sub     dot,r2 */
+/*     bmi     2f */
+/*     mov     r2,-(sp) */
+/* 3: */
+/*     dec     (sp) */
+/*     bmi     3f */
+/*     clr     r2 */
+/*     mov     $1,r3 */
+/*     jsr     pc,outb */
+/*     br      3b */
+/* 3: */
+/*     tst     (sp)+ */
+/*     br      dotmax */
+
+                       leftvalue -= pdot->value;
+                       if (leftvalue < 0)
+                               goto doterr;
+                       while (leftvalue) {
+                               leftvalue--;
+                               outb(0, FABS);
+                       }
+                       goto dotmax;
+
+/* 2: */
+/*     mov     $'.,-(sp) */
+/*     jsr     pc,error */
+/*     br      ealoop */
+/* 1: */
+
+               doterr:
+                       error('.');
+                       goto ealoop;
+               }
+
+/*     cmp     r3,$40 */
+/*     bne     1f */
+/*     mov     $'r,-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+
+               if (leftflags == FGLOBAL)
+                       error('r');
+
+/*     bic     $37,(r1) */
+/*     bic     $!37,r3 */
+/*     bne     1f */
+/*     clr     r2 */
+/* 1: */
+
+               psymbol->flags &= ~037;
+               leftflags &= 037;
+               if (leftflags == 0)
+                       leftvalue = 0;
+
+/*     bisb    r3,(r1) */
+/*     mov     r2,2(r1) */
+
+               psymbol->flags |= leftflags;
+               psymbol->value = leftvalue;
+#ifdef LISTING
+               if (passno)
+                       printf("%04x: %s\n", psymbol->value & 0177777,
+                                       psymbol->name);
+#endif
+
+/* ealoop: */
+/*     cmp     r4,$'\n */
+/*     beq     1f */
+/*     cmp     r4,$'\e */
+/*     bne     9f */
+/*     rts     pc */
+/* 1: */
+/*     inc     line */
+/* 9: */
+/*     jmp     pass1_2 */
+
+       ealoop:
+/* printf("ealoop token = 0x%08x\n", token); */
+               if (token == TNEWLINE) {
+                       line++;
+#ifdef LISTING
+                       if (argfp)
+                               while ((argch = getc(argfp)) != EOF) {
+                                       putchar(argch);
+                                       if (argch == '\n')
+                                               break;
+                               }
+#endif
+               }
+               else if (token == TENDFILE)
+                       break;
+       }
+}
+
+/* checkeos: */
+/*     cmp     r4,$'\n */
+/*     beq     1f */
+/*     cmp     r4,$'; */
+/*     beq     1f */
+/*     cmp     r4,$'\e */
+/*     beq     1f */
+/*     add     $2,(sp) */
+/* 1: */
+/*     rts     pc */
+
+int checkeos() {
+       return token == TNEWLINE || token == TSEMICOLON || token == TENDFILE;
+}
+
+/* fbadv: */
+/*     asl     r4 */
+/*     mov     nxtfb(r4),r1 */
+/*     mov     r1,curfb(r4) */
+/*     bne     1f */
+/*     mov     fbbufp,r1 */
+/*     br      2f */
+/* 1: */
+/*     add     $4,r1 */
+
+void fbadv(label) int label; {
+       struct symbol **ppsymbol;
+       struct symbol *psymbol;
+
+       ppsymbol = (struct symbol **)nxtfb[label];
+       curfb[label] = (intptr_t)ppsymbol;
+       if (ppsymbol == NULL) {
+               ppsymbol = fbbufp;
+               goto entry;
+       }
+       do {
+               ppsymbol++;
+
+/* 2: */
+/*     cmpb    1(r1),r4 */
+/*     beq     1f */
+/*     tst     (r1) */
+/*     bpl     1b */
+/* 1: */
+
+       entry:
+               psymbol = *ppsymbol;
+       } while (psymbol && psymbol->number != label);
+
+/*     mov     r1,nxtfb(r4) */
+/*     asr     r4 */
+/*     rts     pc */
+
+       nxtfb[label] = (intptr_t)ppsymbol;
+}
+
+/* oset: */
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+/*     mov     6(sp),r3 */
+/*     mov     r1,r2 */
+/*     bic     $!1777,r1 */
+/*     add     r3,r1 */
+/*     add     $8,r1 */
+/*     mov     r1,(r3)+                / next slot */
+
+void oset(pstream, offset) struct stream *pstream; off_t offset; {
+       pstream->append = pstream->data + ((int)offset & 01777);
+
+/*     mov     r3,r1 */
+/*     add     $2006,r1 */
+/*     mov     r1,(r3)+                / buf max */
+
+       pstream->limit = pstream->data + 02000;
+
+/*     mov     r0,(r3)+ */
+/*     mov     r2,(r3)+                / seek addr */
+
+       pstream->offset = offset;
+
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+/*     mov     (sp)+,(sp) */
+/*     rts     pc */
+
+}
+
+/* putw: */
+/*     mov     r1,-(sp) */
+/*     mov     r2,-(sp) */
+/*     mov     6(sp),r2 */
+/*     mov     (r2)+,r1                / slot */
+/*     cmp     r1,(r2)                 / buf max */
+/*     bhis    1f */
+/*     mov     r0,(r1)+ */
+/*     mov     r1,-(r2) */
+/*     br      2f */
+/* 1: */
+/*     tst     (r2)+ */
+/*     mov     r0,-(sp) */
+/*     jsr     pc,flush1 */
+/*     mov     (sp)+,r0 */
+/*     mov     r0,*(r2)+ */
+/*     add     $2,-(r2) */
+/* 2: */
+/*     mov     (sp)+,r2 */
+/*     mov     (sp)+,r1 */
+/*     mov     (sp)+,(sp) */
+/* ret: */
+/*     rts     pc */
+
+void p1putw(pstream, word) struct stream *pstream; int word; {
+/* printf("p1putw 0x%08x %04x\n", pstream, word); */
+       if (pstream->append >= pstream->limit)
+ /* note!! should be pstream->limit - 1, but it never makes any difference */
+               flush(pstream);
+       *pstream->append++ = (char)word;
+       *pstream->append++ = (char)(word >> 8);
+}
+
+/* flush: */
+/*     mov     2(sp),r2 */
+/*     mov     (sp)+,(sp) */
+/*     cmp     (r2)+,(r2)+ */
+/* flush1: */
+/*     clr     -(sp)                   / lseek(fout, (r2)L+, L_SET) */
+/*     mov     2(r2),-(sp) */
+/*     mov     (r2)+,-(sp) */
+/*     tst     (r2)+ */
+/*     mov     fout,-(sp) */
+/*     jsr     pc,_lseek */
+/*     add     $8.,sp */
+
+void flush(pstream) struct stream *pstream; {
+       char *start;
+       int count;
+
+       lseek(fout, pstream->offset, SEEK_SET);
+
+/*     cmp     -(sp),-(sp)             / write(fout, <buf>, <len>) */
+/*     bic     $!1777,r1 */
+/*     add     r2,r1                   / write address */
+
+       start = pstream->data + ((int)pstream->offset & 01777);
+
+/*     mov     r1,-(sp)                / { <buf> } */
+/*     mov     r2,r0 */
+/*     bis     $1777,-(r2) */
+/*     add     $1,(r2)                 / new seek addr */
+/*     adc     -(r2) */
+/*     cmp     -(r2),-(r2) */
+
+       pstream->offset = (pstream->offset | 01777) + 1;
+
+/*     sub     (r2),r1 */
+/*     neg     r1 */
+/*     mov     r1,2(sp)                / count */
+/*     mov     r0,(r2)                 / new next slot */
+
+       count = pstream->append - start;
+       pstream->append = pstream->data;
+
+/*     mov     fout,-(sp) */
+/*     mov     r1,6(sp)                / protect r1 from library */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+/*     mov     (sp)+,r1 */
+/*     tst     r0 */
+/*     bpl     ret */
+/* fall thru to wrterr */
+
+       if (write(fout, start, count) < 0)
+               wrterr();
+}
+
+/* wrterr: */
+/*     mov     $8f-9f,-(sp)            / write(1, 9f, 8f-9f) */
+/*     mov     $9f,-(sp) */
+/*     mov     $1,-(sp) */
+/*     jsr     pc,_write */
+/*     add     $6,sp */
+/*     jsr     pc,saexit */
+/* not reached */
+
+void wrterr() {
+       write(1, "as: write error\n", 16);
+       saexit();
+}
+
+/*     .data */
+/* 9: */
+/*     <as: write error\n> */
+/* 8: */
+/*     .even */
+/*     .text */
+
+/* readop: */
+/*     mov     savop,r4 */
+/*     beq     1f */
+/*     clr     savop */
+/*     rts     pc */
+/* 1: */
+
+void readop() {
+       int word;
+
+/* printf("readop() savop = 0x%08x\n", savop); */
+       if (savop) {
+               token = savop;
+               savop = 0;
+               return;
+       }
+
+/*     jsr     pc,getw1 */
+/*     cmp     r4,$200 */
+/*     blo     1f */
+/*     cmp     r4,$4000 */
+/*     blo     2f */
+/*     sub     $4000,r4 */
+/*     asl     r4 */
+/*     asl     r4 */
+/*     add     hshtab,r4 */
+/*     rts     pc */
+/* 2: */
+
+       word = getw1();
+       if (word >= 0 && word < TASCII)
+               token = word;
+       else {
+               if (word >= 04000)
+                       token = (intptr_t)hshtab[word - 04000];
+
+/* remove PST flag (1000) then multiply by PSTENTSZ.  In pass 0 the PST */
+/* symbol number was divided by PSTENTSZ(to make it fit) - we now reverse */
+/* that process. */
+/*     mov     r5,-(sp) */
+/*     mov     r4,r5 */
+/*     sub     $1000,r5 */
+/*     mul     $PSTENTSZ,r5 */
+/*     mov     r5,r4 */
+/*     mov     (sp)+,r5 */
+/*     add     $dotrel,r4              / point at dot's flag field */
+/* 1: */
+/*     rts     pc */
+
+               else
+                       token = (intptr_t)(symtab + (word - 01000));
+       }
+}
+
+/* getw: */
+/*     mov     savop,r4 */
+/*     beq     getw1 */
+/*     clr     savop */
+/*     rts     pc */
+
+void p1getw() {
+       if (savop) {
+               token = savop;
+               savop = 0;
+               return;
+       }
+       token = getw1();
+}
+
+/* getw1: */
+/*     dec     ibufc */
+/*     bgt     1f */
+
+int getw1() {
+       ibufc--;
+       if (ibufc <= 0) {
+
+/*     mov     r1,-(sp)                / protect r1 from library */
+/*     mov     $1024.,-(sp)            / read(fin, inbuf, 1024) */
+/*     mov     $inbuf,-(sp) */
+/*     mov     fin,-(sp) */
+/*     jsr     pc,_read */
+/*     add     $6,sp */
+/*     mov     (sp)+,r1 */
+
+               ibufc = read(fin, inbuf, 1024);
+               if (ibufc <= 0)
+                       return TENDFILE;
+
+/*     asr     r0 */
+/*     mov     r0,ibufc */
+/*     bgt     2f */
+/*     mov     $4,r4 */
+/*     sev */
+/*     rts     pc */
+/* 2: */
+/*     mov     $inbuf,ibufp */
+/* 1: */
+
+               ibufc /= sizeof(short);
+               ibufp = (short *)inbuf;
+ /* note!! rather silly, ibufc doesn't get decremented through this path */
+       }
+
+/*     mov     *ibufp,r4 */
+/*     add     $2,ibufp */
+/*     rts     pc */
+
+       return *ibufp++;
+}
+
+/* opline: */
+/*     mov     r4,r0 */
+/*     bmi     2f */
+/*     cmp     r0,$177 */
+/*     bgt     2f */
+/*     cmp     r4,$5 */
+/*     beq     opeof */
+/*     cmp     r4,$'< */
+/*     bne     xpr */
+/*     jmp     opl17 */
+/* xxpr: */
+/*     tst     (sp)+ */
+/* xpr: */
+/*     jsr     pc,expres */
+/*     jsr     pc,outw */
+/*     rts     pc */
+/* 2: */
+
+void xpr() {
+       expres();
+       outw(leftvalue, leftflags);
+}
+
+void opline() {
+       struct symbol *psymbol;
+       int flags;
+
+/* printf("opline() token 0x%08x\n", token); */
+       if (token >= 0 && token < TASCII) {
+               if (token == TNEWFILE)
+                       opeof();
+               else if (token == TSTRING)
+                       opl17();
+               else
+                       xpr();
+               return;
+       }
+
+/*     movb    (r4),r0 */
+/*     cmp     r0,$24                  /reg */
+/*     beq     xpr */
+/*     cmp     r0,$33                  /est text */
+/*     beq     xpr */
+/*     cmp     r0,$34                  / est data */
+/*     beq     xpr */
+/*     cmp     r0,$5 */
+/*     blt     xpr */
+/*     cmp     r0,$36 */
+/*     bgt     xpr */
+
+       psymbol = (struct symbol *)token;
+       flags = psymbol->flags;
+       if (flags <= FBSS || flags == FREGISTER || flags == FESTTEXT ||
+                       flags == FESTDATA || flags > FJCOND) {
+               xpr();
+               return;
+       }
+
+/*     mov     2(r4),-(sp) */
+/*     mov     r0,-(sp) */
+/*     jsr     pc,readop */
+/*     mov     (sp)+,r0 */
+/*     asl     r0 */
+/*     mov     $adrbuf,r5 */
+/*     clr     swapf */
+/*     mov     $-1,rlimit */
+/*     jmp     *1f-10.(r0) */
+
+       opcode = psymbol->value;
+       readop();
+       adrptr = adrbuf;
+       swapf = 0;
+       rlimit = 0177777;
+       switch (flags) {
+
+/*     .data */
+/* 1: */
+/*     opl5 */
+
+       case FMOVFO:
+               opl5();
+               return;
+
+/*     opl6 */
+
+       case FBRANCH:
+               opl6();
+               return;
+
+/*     opl7 */
+
+       case FJSR:
+               opl7();
+               return;
+
+/*     opl10 */
+
+       case FRTS:
+               opl10();
+               return;
+
+/*     opl11 */
+
+       case FSYSTRAP:
+               opl11();
+               return;
+
+/*     opl12 */
+
+       case FMOVF:
+               opl12();
+               return;
+
+/*     opl13 */
+
+       case FDOUBLE:
+               opl13();
+               return;
+
+/*     opl14 */
+
+       case FFLOP:
+               opl14();
+               return;
+
+/*     opl15 */
+
+       case FSINGLE:
+               opl15();
+               return;
+
+/*     opl16 */
+
+       case FDOTBYTE:
+               opl16();
+               return;
+
+#if 1 /* modifications for dec syntax */
+       case FDOTWORD:
+               opldotword();
+               return;
+#endif
+
+/*     opl17 */
+
+       case FSTRING:
+               opl17();
+               return;
+
+/*     opl20 */
+
+       case FDOTEVEN:
+               opl20();
+               return;
+
+/*     opl21 */
+
+       case FDOTIF:
+               opl21();
+               return;
+
+/*     opl22 */
+
+       case FDOTENDIF:
+               opl22();
+               return;
+
+/*     opl23 */
+
+       case FDOTGLOBL:
+               opl23();
+               return;
+
+/*     xxpr */
+
+       case FREGISTER: /* can never get here */
+               xpr();
+               return;
+
+/*     opl25 */
+
+       case FDOTTEXT:
+               opl25();
+               return;
+
+/*     opl26 */
+
+       case FDOTDATA:
+               opl26();
+               return;
+
+/*     opl27 */
+
+       case FDOTBSS:
+               opl27();
+               return;
+
+/*     opl30 */
+
+       case FMULDIV:
+               opl30();
+               return;
+
+/*     opl31 */
+
+       case FSOB:
+               opl31();
+               return;
+
+/*     opl32 */
+
+       case FDOTCOMM:
+               opl32();
+               return;
+
+/*     xxpr */
+/*     xxpr */
+
+       case FESTTEXT:
+       case FESTDATA:
+               xpr();
+               return;
+
+/*     opl35 */
+
+       case FJBR:
+               opl35();
+               return;
+
+/*     opl36 */
+
+       case FJCOND:
+               opl36();
+               return;
+
+/*     .text */
+
+       }
+}
+
+/* opeof: */
+/*     mov     $1,line */
+/*     mov     $20,-(sp) */
+/*     mov     $argb,r1 */
+/* 1: */
+/*     jsr     pc,getw */
+/*     tst     r4 */
+/*     bmi     1f */
+/*     movb    r4,(r1)+ */
+/*     dec     (sp) */
+/*     bgt     1b */
+/*     tstb    -(r1) */
+/*     br      1b */
+/* 1: */
+/*     movb    $'\n,(r1)+ */
+/*     clrb    (r1)+ */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opeof() {
+       int count;
+       char *p;
+#ifdef LISTING
+       int argch;
+#endif
+
+       line = 1;
+       count = 20;
+       p = argb;
+       while (1) {
+               p1getw();
+               if (token == -1)
+                       break;
+               if (count) {
+                       count--;
+                       *p++ = (char)token;
+               }
+       }
+#ifdef LISTING
+       if (passno) {
+               if (argfp)
+                       fclose(argfp);
+               *p = 0;
+               argfp = fopen(argb, "r");
+               if (argfp)
+                       while ((argch = getc(argfp)) != EOF) {
+                               putchar(argch);
+                               if (argch == '\n')
+                                       break;
+                       }
+       }
+#endif
+       *p++ = '\n';
+       *p = 0;
+}
+
+/* opl30:                                      / mul, div etc */
+/*     inc     swapf */
+/*     mov     $1000,rlimit */
+/*     br      opl13 */
+
+void opl30() {
+       swapf = 1;
+       rlimit = 01000;
+       opl13();
+}
+
+/* opl14:                                      / flop freg,fsrc */
+/*     inc     swapf */
+
+void opl14() {
+       swapf = 1;
+       opl5();
+}
+
+/* opl5:                                       / flop src,freg */
+/*     mov     $400,rlimit */
+
+void opl5() {
+       rlimit = 0400;
+       opl13();
+}
+
+/* opl13:                                      /double */
+/*     jsr     pc,addres */
+
+void opl13() {
+       addres();
+       op2a();
+}
+
+/* op2a: */
+/*     mov     r2,-(sp) */
+/*     jsr     pc,readop */
+
+void op2a() {
+       rvalue = leftvalue;
+       readop();
+       op2b();
+}
+
+/* op2b: */
+/*     jsr     pc,addres */
+/*     tst     swapf */
+/*     beq     1f */
+/*     mov     (sp),r0 */
+/*     mov     r2,(sp) */
+/*     mov     r0,r2 */
+/* 1: */
+
+void op2b() {
+       int tempvalue;
+       intptr_t *adrtmp;
+
+       addres();
+/* printf("op2b %d 0x%08x 0x%08x\n", swapf, rvalue, leftvalue); */
+       if (swapf) {
+               tempvalue = rvalue;
+               rvalue = leftvalue;
+               leftvalue = tempvalue;
+       }
+
+/*     swab    (sp) */
+/*     asr     (sp) */
+/*     asr     (sp) */
+/*     cmp     (sp),rlimit */
+/*     blo     1f */
+/*     mov     $'x,-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+
+#if 1
+ rvalue <<= 6;
+#else
+       rvalue = (rvalue & 0377) << 6; /* seems a bit stupid */
+#endif
+       if ((unsigned int)rvalue >= (unsigned int)rlimit)
+ {
+ printf("a 0x%08x 0x%08x\n", rvalue, rlimit);
+               error('x');
+ }
+
+/*     bis     (sp)+,r2 */
+/*     bis     (sp)+,r2 */
+/*     clr     r3 */
+/*     jsr     pc,outw */
+
+       outw(leftvalue | rvalue | opcode, 0);
+
+/*     mov     $adrbuf,r1 */
+/* 1: */
+/*     cmp     r1,r5 */
+/*     bhis    1f */
+/*     mov     (r1)+,r2 */
+/*     mov     (r1)+,r3 */
+/*     mov     (r1)+,xsymbol */
+/*     jsr     pc,outw */
+/*     br      1b */
+/* 1: */
+/*     rts     pc */
+
+       adrtmp = adrbuf;
+       while (adrtmp < adrptr) {
+               leftvalue = *adrtmp++;
+               leftflags = *adrtmp++;
+               xsymbol = (struct symbol *)*adrtmp++;
+               outw(leftvalue, leftflags);
+       }
+}
+
+/* opl15:                                      / single operand */
+/*     clr     -(sp) */
+/*     br      op2b */
+
+void opl15() {
+       rvalue = 0;
+       op2b();
+}
+
+/* opl12:                                      / movf */
+/*     mov     $400,rlimit */
+/*     jsr     pc,addres */
+/*     cmp     r2,$4                   / see if source is fregister */
+/*     blo     1f */
+/*     inc     swapf */
+/*     br      op2a */
+/* 1: */
+/*     mov     $174000,(sp) */
+/*     br      op2a */
+
+void opl12() {
+       rlimit = 0400;
+       addres();
+       if (leftvalue >= 4)
+               swapf = 1;
+       else
+               opcode = 0174000;
+       op2a();
+}
+
+/* opl35:                                      / jbr */
+/* opl36:                                      / jeq, jne, etc */
+/*     jsr     pc,expres */
+/*     tst     passno */
+/*     bne     1f */
+/*     mov     r2,r0 */
+/*     jsr     pc,setbr */
+/*     tst     r2 */
+/*     beq     2f */
+/*     cmp     (sp),$br */
+/*     beq     2f */
+/*     add     $2,r2 */
+/* 2: */
+/*     add     r2,dot                  / if doesn't fit */
+/*     add     $2,dot */
+/*     tst     (sp)+ */
+/*     rts     pc */
+/* 1: */
+/*     jsr     pc,getbr */
+/*     bcc     dobranch */
+/*     mov     (sp)+,r0 */
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+/*     cmp     r0,$br */
+/*     beq     2f */
+/*     mov     $402,r2 */
+/*     xor     r0,r2                   / flip cond, add ".+6" */
+/*     mov     $1,r3 */
+/*     jsr     pc,outw */
+/* 2: */
+/*     mov     $1,r3 */
+/*     mov     $jmp+37,r2 */
+/*     jsr     pc,outw */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+/*     jsr     pc,outw */
+/*     rts     pc */
+
+void opl35() {
+       expres();
+       if (passno == 0)
+               pdot->value += setbr(leftvalue) ? 4 : 2;
+       else {
+               if (getbr() == 0)
+                       dobranch();
+               else {
+                       outw(0000137, FABS); /* jmp */
+                       outw(leftvalue, leftflags);
+               }
+       }
+}
+
+void opl36() {
+       expres();
+       if (passno == 0)
+               pdot->value += setbr(leftvalue) ? 6 : 2;
+       else {
+               if (getbr() == 0)
+                       dobranch();
+               else {
+                       outw(opcode ^ 0402, FABS); /* jne, jeq, etc .+6 */
+                       outw(0000137, FABS); /* jmp */
+                       outw(leftvalue, leftflags);
+               }
+       }
+}
+
+/* opl31:                                      / sob */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkreg */
+/*     swab    r2 */
+/*     asr     r2 */
+/*     asr     r2 */
+/*     bis     r2,(sp) */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres */
+/*     tst     passno */
+/*     beq     3f */
+/*     sub     dot,r2 */
+/*     neg     r2 */
+/*     mov     r2,r0 */
+/*     cmp     r0,$-2 */
+/*     blt     2f */
+/*     cmp     r0,$175 */
+/*     bgt     2f */
+/*     add     $4,r2 */
+/*     br      1f */
+
+void opl31() {
+       expres();
+       checkreg();
+       opcode |= leftvalue << 6;
+       readop();
+       expres();
+       if (passno == 0)
+               binstr();
+       else {
+               leftvalue = pdot->value - leftvalue;
+               if (leftvalue < -2 || leftvalue > 0175)
+                       errorb();
+               else {
+                       leftvalue += 4;
+                       branch();
+               }
+       }
+}
+
+/* opl6:                                       /branch */
+/*     jsr     pc,expres */
+/*     tst     passno */
+/*     beq     3f */
+
+void opl6() {
+       expres();
+       if (passno == 0)
+               binstr();
+       else
+               dobranch();
+}
+
+/* dobranch: */
+/*     sub     dot,r2 */
+/*     mov     r2,r0 */
+/*     cmp     r0,$-254. */
+/*     blt     2f */
+/*     cmp     r0,$256. */
+/*     bgt     2f */
+
+void dobranch() {
+       leftvalue -= pdot->value;
+       if (leftvalue < -254 || leftvalue > 256)
+               errorb();
+       else
+               branch();
+}
+
+/* 1: */
+/*     bit     $1,r2 */
+/*     bne     2f */
+/*     cmp     r3,dot-2                / same relocation as . */
+/*     bne     2f */
+/*     asr     r2 */
+/*     dec     r2 */
+/*     bic     $177400,r2 */
+
+void branch() {
+       if (leftvalue & 1)
+               errorb();
+       else {
+               leftvalue = ((leftvalue >> 1) - 1) & 0377;
+               binstr();
+       }
+}
+
+/* 3: */
+/*     bis     (sp)+,r2 */
+/*     clr     r3 */
+/*     jsr     pc,outw */
+/*     rts     pc */
+
+void binstr() {
+       outw(leftvalue | opcode, 0);
+}
+
+/* 2: */
+/*     mov     $'b,-(sp) */
+/*     jsr     pc,error */
+/*     clr     r2 */
+/*     br      3b */
+
+void errorb() {
+       error('b');
+       leftvalue = 0;
+       branch();
+}
+
+/* opl7:                                       /jsr */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkreg */
+/*     jmp     op2a */
+
+void opl7() {
+       expres();
+       checkreg();
+       op2a();
+}
+
+/* opl10:                                      / rts */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkreg */
+/*     br      1f */
+
+void opl10() {
+       expres();
+       checkreg();
+       rinstr();
+}
+
+/* opl11:                                      / sys */
+/*     jsr     pc,expres */
+/*     cmp     r2,$256. */
+/*     bhis    0f */
+/*     cmp     r3,$1 */
+/*     ble     1f */
+/* 0: */
+/*     mov     $'a,-(sp) */
+/*     jsr     pc,error */
+
+void opl11() {
+       expres();
+       if (leftvalue < 0 || leftvalue >= 256)
+               error('a');
+       rinstr();
+}
+
+/* 1: */
+/*     bis     (sp)+,r2 */
+/*     jsr     pc,outw */
+/*     rts     pc */
+
+void rinstr() {
+       outw(leftvalue | opcode, leftflags);
+}
+
+/* opl16:                                      / .byte */
+/*     jsr     pc,expres */
+/*     jsr     pc,outb */
+/*     cmp     r4,$', */
+/*     bne     1f */
+/*     jsr     pc,readop */
+/*     br      opl16 */
+/* 1: */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opl16() {
+       while (1) {
+               expres();
+               outb(leftvalue, leftflags);
+               if (token != TCOMMA)
+                       break;
+               readop();
+       }
+}
+
+#if 1 /* modifications for dec syntax */
+void opldotword() {
+       while (1) {
+               expres();
+               outw(leftvalue, leftflags);
+               if (token != TCOMMA)
+                       break;
+               readop();
+       }
+}
+#endif
+
+/* opl17:                                      / < (.ascii) */
+/*     jsr     pc,getw */
+/*     mov     $1,r3 */
+/*     mov     r4,r2 */
+/*     bmi     2f */
+/*     bic     $!377,r2 */
+/*     jsr     pc,outb */
+/*     br      opl17 */
+/* 2: */
+/*     jsr     pc,getw */
+/*     rts     pc */
+
+void opl17() {
+       while (1) {
+               p1getw();
+               if (token == -1)
+                       break;
+               outb(token & 0377, FABS);
+       }
+       p1getw();
+}
+
+/* opl20:                                      /.even */
+/*     bit     $1,dot */
+/*     beq     1f */
+/*     cmp     dot-2,$4 */
+/*     beq     2f                      / bss mode */
+/*     clr     r2 */
+/*     clr     r3 */
+/*     jsr     pc,outb */
+/*     br      1f */
+/* 2: */
+/*     inc     dot */
+/* 1: */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opl20() {
+       if (pdot->value & 1) {
+               if (pdot->flags != FBSS)
+                       outb(0, 0);
+               else
+                       pdot->value++;
+       }
+}
+
+/* opl21:                                      /if */
+/*     jsr     pc,expres */
+
+void opl21() {
+       expres();
+}
+
+/* opl22: */
+/* oplret: */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opl22() {
+}
+
+void oplret() {
+}
+
+/* opl23:                                      /.globl */
+/*     cmp     r4,$200 */
+/*     blo     1f */
+/*     bisb    $40,(r4) */
+/*     jsr     pc,readop */
+/*     cmp     r4,$', */
+/*     bne     1f */
+/*     jsr     pc,readop */
+/*     br      opl23 */
+/* 1: */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opl23() {
+       struct symbol *psymbol;
+
+       while (1) {
+               if (token >= 0 && token < TASCII)
+                       break;
+               psymbol = (struct symbol *)token;
+               psymbol->flags |= FGLOBAL;
+               readop();
+               if (token != TCOMMA)
+                       break;
+               readop();
+       }
+}
+
+/* opl25:                                      / .text, .data, .bss */
+/* opl26: */
+/* opl27: */
+/*     inc     dot */
+/*     bic     $1,dot */
+/*     mov     r0,-(sp) */
+/*     mov     dot-2,r1 */
+/*     asl     r1 */
+/*     mov     dot,savdot-4(r1) */
+/*     tst     passno */
+/*     beq     1f */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,flush */
+/*     mov     $relp,-(sp) */
+/*     jsr     pc,flush */
+/*     mov     (sp),r2 */
+/*     asl     r2 */
+/*     add     $txtseek-[4*25],r2 */
+/*     mov     r2,tseekp */
+/*     mov     (r2),r0 */
+/*     mov     2(r2),r1 */
+/*     mov     $txtp,-(sp) */
+/*     jsr     pc,oset */
+/*     add     $trelseek-txtseek,r2 */
+/*     mov     (r2),r0 */
+/*     mov     2(r2),r1 */
+/*     mov     r2,rseekp */
+/*     mov     $relp,-(sp) */
+/*     jsr     pc,oset */
+/* 1: */
+/*     mov     (sp)+,r0 */
+/*     mov     savdot-[2*25](r0),dot */
+/*     asr     r0 */
+/*     sub     $25-2,r0 */
+/*     mov     r0,dot-2                / new . relocation */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opl25() {
+       pdot->value = (pdot->value + 1) & ~1;
+       savdot[pdot->flags - FTEXT] = pdot->value;
+       if (passno) {
+               flush(&txtp);
+               flush(&relp);
+               tseekp = seek;
+               oset(&txtp, seek[0]);
+               rseekp = seek + 3;
+               oset(&relp, seek[3]);
+       }
+       pdot->value = savdot[0];
+       pdot->flags = FTEXT;
+}
+
+void opl26() {
+       pdot->value = (pdot->value + 1) & ~1;
+       savdot[pdot->flags - FTEXT] = pdot->value;
+       if (passno) {
+               flush(&txtp);
+               flush(&relp);
+               tseekp = seek + 1;
+               oset(&txtp, seek[1]);
+               rseekp = seek + 4;
+               oset(&relp, seek[4]);
+       }
+       pdot->value = savdot[1];
+       pdot->flags = FDATA;
+}
+
+void opl27() {
+       pdot->value = (pdot->value + 1) & ~1;
+       savdot[pdot->flags - FTEXT] = pdot->value;
+       if (passno) { /* this is not really needed: */
+               flush(&txtp);
+               flush(&relp);
+               tseekp = seek + 2;
+               oset(&txtp, seek[2]);
+               rseekp = seek + 5;
+               oset(&relp, seek[5]);
+       }
+       pdot->value = savdot[2];
+       pdot->flags = FBSS;
+}
+
+/* opl32: */
+/*     cmp     r4,$200 */
+/*     blo     1f */
+/*     mov     r4,-(sp) */
+/*     jsr     pc,readop */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres */
+/*     mov     (sp)+,r0 */
+/*     bit     $37,(r0) */
+/*     bne     1f */
+/*     bis     $40,(r0) */
+/*     mov     r2,2(r0) */
+/* 1: */
+/*     tst     (sp)+ */
+/*     rts     pc */
+
+void opl32() {
+       struct symbol *psymbol;
+
+       if (token >= 0 && token < TASCII)
+               return;
+       psymbol = (struct symbol *)token;
+       readop();
+       readop();
+       expres();
+       if ((psymbol->flags & 037) == 0) {
+               psymbol->flags |= FGLOBAL;
+               psymbol->value = leftvalue;
+       }
+}
+
+/* addres: */
+/*     clr     -(sp) */
+
+void addres() {
+/* printf("addres() token = 0x%08x\n", token); */
+       indirect = 0; /* it has a different meaning on pass 1/2 */
+       addres1();
+}
+
+/* 4: */
+/*     cmp     r4,$'( */
+/*     beq     alp */
+/*     cmp     r4,$'- */
+/*     beq     amin */
+/*     cmp     r4,$'$ */
+/*     beq     adoll */
+/*     cmp     r4,$'* */
+/*     bne     getx */
+/*     jmp     astar */
+
+void addres1() {
+       switch (token) {
+       case TLPAREN:
+               alp();
+               return;
+       case TMIN:
+               amin();
+               return;
+       case TDOLL:
+               adoll();
+               return;
+       case TSTAR:
+               astar();
+               return;
+       }
+       getx();
+}
+
+/* getx: */
+/*     jsr     pc,expres */
+/*     cmp     r4,$'( */
+/*     bne     2f */
+/*     jsr     pc,readop */
+/*     mov     r2,(r5)+ */
+/*     mov     r3,(r5)+ */
+/*     mov     xsymbol,(r5)+ */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkreg */
+/*     jsr     pc,checkrp */
+/*     bis     $60,r2 */
+/*     bis     (sp)+,r2 */
+/*     rts     pc */
+/* 2: */
+
+void getx() {
+       expres();
+       if (token == TLPAREN) {
+               readop();
+               *adrptr++ = leftvalue;
+               *adrptr++ = leftflags;
+               *adrptr++ = (intptr_t)xsymbol;
+               expres();
+               checkreg();
+               checkrp();
+               leftvalue |= 060 | indirect;
+       }
+
+/*     cmp     r3,$24 */
+/*     bne     1f */
+/*     jsr     pc,checkreg */
+/*     bis     (sp)+,r2 */
+/*     rts     pc */
+/* 1: */
+
+       else if (leftflags == FREGISTER) {
+               checkreg();
+               leftvalue |= indirect;
+       }
+
+/*     mov     r3,-(sp) */
+/*     bic     $40,r3 */
+/*     mov     (sp)+,r3 */
+/*     bis     $100000,r3 */
+/*     sub     dot,r2 */
+/*     sub     $4,r2 */
+/*     cmp     r5,$adrbuf */
+/*     beq     1f */
+/*     sub     $2,r2 */
+/* 1: */
+
+       else {
+               leftflags |= 0100000; /* relocate flag */
+               leftvalue -= (pdot->value + 4);
+               if (adrptr != adrbuf)
+                       leftvalue -= 2;
+
+/*     mov     r2,(r5)+                / index */
+/*     mov     r3,(r5)+                / index reloc. */
+/*     mov     xsymbol,(r5)+           / index global */
+/*     mov     $67,r2                  / address mode */
+/*     bis     (sp)+,r2 */
+/*     rts     pc */
+
+               *adrptr++ = leftvalue;
+               *adrptr++ = leftflags;
+               *adrptr++ = (intptr_t)xsymbol;
+               leftvalue = 067 | indirect;
+       }
+}
+
+/* alp: */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkrp */
+/*     jsr     pc,checkreg */
+/*     cmp     r4,$'+ */
+/*     beq     1f */
+
+void alp() {
+       readop();
+       expres();
+       checkrp();
+       checkreg();
+       if (token != TPLUS) {
+
+/*     tst     (sp)+ */
+/*     beq     2f */
+/*     bis     $70,r2 */
+/*     clr     (r5)+ */
+/*     clr     (r5)+ */
+/*     mov     xsymbol,(r5)+ */
+/*     rts     pc */
+/* 2: */
+
+               if (indirect) {
+                       leftvalue |= 070;
+                       *adrptr++ = 0;
+                       *adrptr++ = 0;
+                       *adrptr++ = (intptr_t)xsymbol;
+               }
+
+/*     bis     $10,r2 */
+/*     rts     pc */
+
+               else
+                       leftvalue |= 010;
+
+/* 1: */
+/*     jsr     pc,readop */
+/*     bis     $20,r2 */
+/*     bis     (sp)+,r2 */
+/*     rts     pc */
+
+       }
+       else {
+               readop();
+               leftvalue |= 020 | indirect;
+       }
+}
+
+/* amin: */
+/*     jsr     pc,readop */
+/*     cmp     r4,$'( */
+/*     beq     1f */
+/*     mov     r4,savop */
+/*     mov     $'-,r4 */
+/*     br      getx */
+/* 1: */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres */
+/*     jsr     pc,checkrp */
+/*     jsr     pc,checkreg */
+/*     bis     (sp)+,r2 */
+/*     bis     $40,r2 */
+/*     rts     pc */
+
+
+void amin() {
+       readop();
+       if (token != TLPAREN) {
+               savop = token;
+               token = TMIN;
+               getx();
+       }
+       else {
+               readop();
+               expres();
+               checkrp();
+               checkreg();
+               leftvalue |= indirect | 040;
+       }
+}
+
+/* adoll: */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres */
+/*     mov     r2,(r5)+ */
+/*     mov     r3,(r5)+ */
+/*     mov     xsymbol,(r5)+ */
+/*     mov     (sp)+,r2 */
+/*     bis     $27,r2 */
+/*     rts     pc */
+
+void adoll() {
+       readop();
+       expres();
+       *adrptr++ = leftvalue;
+       *adrptr++ = leftflags;
+       *adrptr++ = (intptr_t)xsymbol;
+       leftvalue = indirect | 027; /* means (pc)+ */
+}
+
+/* astar: */
+/*     tst     (sp) */
+/*     beq     1f */
+/*     mov     $'*,-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+/*     mov     $10,(sp) */
+/*     jsr     pc,readop */
+/*     jmp     4b */
+
+void astar() {
+       if (indirect)
+               error('*');
+       indirect = 010;
+       readop();
+       addres1();
+}
+
+/* checkreg: */
+/*     cmp     r2,$7 */
+/*     bhi     1f */
+/*     cmp     r1,$1 */
+/*     blos    2f */
+/*     cmp     r3,$5 */
+/*     blo     1f */
+/* 2: */
+/*     rts     pc */
+/* 1: */
+/*     mov     $'a,-(sp) */
+/*     jsr     pc,error */
+/*     clr     r2 */
+/*     clr     r3 */
+/*     rts     pc */
+
+void checkreg() {
+       if (leftvalue > 7 || (leftflags >= FTEXT && leftflags <= FBSS)) {
+               error('a');
+               leftvalue = 0;
+               leftflags = 0;
+       }
+}
+
+/* checkrp: */
+/*     cmp     r4,$') */
+/*     beq     1f */
+/*     mov     $'),-(sp) */
+/*     jsr     pc,error */
+/*     rts     pc */
+/* 1: */
+/*     jsr     pc,readop */
+/*     rts     pc */
+
+void checkrp() {
+       if (token != TRPAREN)
+               error(')');
+       else
+               readop();
+}
+
+/* setbr: */
+/*     mov     brtabp,r1 */
+/*     cmp     r1,$brlen */
+/*     blt     1f */
+/*     mov     $2,r2 */
+/*     rts     pc */
+/* 1: */
+
+int setbr(value) int value; {
+       int index;
+
+       if (brtabp >= brlen)
+               return 2;
+
+/*     inc     brtabp */
+/*     clr     -(sp) */
+/*     sub     dot,r0 */
+/*     ble     1f */
+/*     sub     brdelt,r0 */
+/* 1: */
+
+       index = brtabp++;
+       value -= pdot->value;
+       if (value > 0)
+               value -= brdelt;
+
+/*     cmp     r0,$-254. */
+/*     blt     1f */
+/*     cmp     r0,$256. */
+/*     ble     2f */
+/* 1: */
+
+       if (value < -254 || value > 256) {
+
+/*     mov     r1,-(sp) */
+/*     bic     $!7,(sp) */
+/*     mov     $1,r0 */
+/*     ash     (sp)+,r0 */
+/*     ash     $-3,r1 */
+/*     bisb    r0,brtab(r1) */
+/*     mov     $2,(sp) */
+
+               brtab[index >> 3] |= 1 << (index & 7);
+               return 2;
+
+/* 2: */
+/*     mov     (sp)+,r2 */
+/*     rts     pc */
+
+       }
+       return 0;
+}
+
+/* getbr: */
+/*     mov     brtabp,r1 */
+/*     cmp     r1,$brlen */
+/*     blt     1f */
+/*     sec */
+/*     rts     pc */
+/* 1: */
+
+int getbr() {
+       int index;
+
+       if (brtabp >= brlen)
+               return 1;
+
+/*     mov     r1,-(sp) */
+/*     bic     $!7,(sp) */
+/*     neg     (sp) */
+/*     inc     brtabp */
+/*     ash     $-3,r1 */
+/*     movb    brtab(r1),r1 */
+/*     ash     (sp)+,r1 */
+/*     ror     r1                      / 0-bit into c-bit */
+/*     rts     pc */
+
+       index = brtabp++;
+       return brtab[index >> 3] & (1 << (index & 7));
+}
+
+/* expres: */
+/*     clr     xsymbol */
+
+void expres() {
+       xsymbol = NULL;
+       expres1();
+}
+
+/* expres1: */
+/*     mov     r5,-(sp) */
+/*     mov     $'+,-(sp) */
+/*     clr     r2 */
+/*     mov     $1,r3 */
+/*     br      1f */
+
+void expres1() {
+       struct symbol *psymbol;
+
+/* printf("expres()\n"); */
+       optoken = TPLUS;
+       opfound = 0;
+       leftvalue = 0;
+       leftflags = FABS;
+       goto entry;
+
+/* advanc: */
+/*     jsr     pc,readop */
+/* 1: */
+/*     mov     r4,r0 */
+/*     blt     6f */
+/*     cmp     r0,$177 */
+/*     ble     7f */
+/* 6: */
+/*     movb    (r4),r0 */
+/*     bne     1f */
+/*     tst     passno */
+/*     beq     1f */
+/*     mov     $'u,-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+
+       while (1) {
+               readop();
+       entry:
+               rightflags = token;
+               if (token < 0 || token >= TASCII) {
+                       psymbol = (struct symbol *)token;
+                       rightflags = psymbol->flags;
+                       if (rightflags == 0 && passno)
+                               error('u');
+
+/*     tst     overlaid */
+/*     beq     0f */
+
+/* Bill Shannon's hack to the assembler to force globl text */
+/* references to remain undefined so that the link editor may */
+/* resolve them. This is necessary if a function is used as an */
+/* arg in an overlay located piece of code, and the function is */
+/* actually in another overlay. Elsewise, the assembler fix's up */
+/* the reference before the link editor changes the globl refrence */
+/* to the thunk. -wfj 5/80 */
+/*     cmp     r0,$42                  / is it globl text ? */
+/*     bne     0f                      / nope */
+/*     mov     $40,r0                  / yes, treat it as undefined external */
+/* 0: */
+
+                       if (overlaid && rightflags == (FTEXT | FGLOBAL))
+                               rightflags = FGLOBAL;
+
+/*     cmp     r0,$40 */
+/*     bne     1f */
+/*     mov     r4,xsymbol */
+/*     clr     r1 */
+/*     br      oprand */
+/* 1: */
+
+                       if (rightflags == FGLOBAL) {
+                               xsymbol = (struct symbol *)token;
+                               rightvalue = 0;
+                       }
+
+/*     mov     2(r4),r1 */
+/*     br      oprand */
+
+                       else
+                               rightvalue = psymbol->value;
+                       oprand();
+                       continue;
+               }
+
+/* 7: */
+/*     cmp     r4,$141 */
+/*     blo     1f */
+/*     asl     r4 */
+/*     mov     curfb-[2*141](r4),r0 */
+/*     mov     2(r0),r1 */
+/*     movb    (r0),r0 */
+/*     br      oprand */
+/* 1: */
+
+               if (token >= TLABEL) {
+                       if (token < TLABEL + 10)
+                               psymbol = *(struct symbol **)
+                                               curfb[token - TLABEL];
+                       else
+                               psymbol = *(struct symbol **)
+                                               nxtfb[token - (TLABEL + 10)];
+                       rightvalue = psymbol->value;
+                       rightflags = psymbol->flags;
+                       oprand();
+                       continue;
+               }
+
+/*     mov     $esw1,r1 */
+/* 1: */
+/*     cmp     (r1)+,r4 */
+/*     beq     1f */
+/*     tst     (r1)+ */
+/*     bne     1b */
+/*     tst     (sp)+ */
+/*     mov     (sp)+,r5 */
+/*     rts     pc */
+/* 1: */
+/*     jmp     *(r1) */
+
+               switch (token) {
+               default:
+                       return;
+
+/*     .data */
+/* esw1: */
+/*     '+;     binop */
+/*     '-;     binop */
+/*     '*;     binop */
+/*     '/;     binop */
+/*     '&;     binop */
+/*     037;    binop */
+/*     035;    binop */
+/*     036;    binop */
+/*     '%;     binop */
+
+               case TPLUS:
+               case TMIN:
+               case TSTAR:
+               case TSLASH:
+               case TAND:
+               case TOR:
+               case TLSH:
+               case TRSH:
+               case TMOD:
+                       binop();
+                       break;
+
+/*     '[;     brack */
+
+               case TLBRACK:
+                       brack();
+                       break;
+
+/*     '^;     binop */
+
+               case TCARET:
+                       binop();
+                       break;
+
+/*     1;      exnum */
+
+               case TABS:
+                       exnum();
+                       break;
+
+/*     2;      exnum1 */
+
+               case TABS2:
+                       exnum1();
+                       break;
+
+/*     '!;     binop */
+
+               case TNOT:
+                       binop();
+                       break;
+
+/*     200;    0 */
+/*     .text */
+
+               }
+       }
+}
+
+/* binop: */
+/*     cmpb    (sp),$'+ */
+/*     beq     1f */
+/*     mov     $'e,-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+/*     movb    r4,(sp) */
+/*     br      advanc */
+
+
+void binop() {
+       if (optoken != TPLUS)
+               error('e');
+       optoken = token;
+}
+
+/* exnum1: */
+/*     mov     numval,r1 */
+/*     br      1f */
+
+/* exnum: */
+/*     jsr     pc,getw */
+/*     mov     r4,r1 */
+/* 1: */
+/*     mov     $1,r0 */
+/*     br      oprand */
+
+void exnum1() {
+/* printf("exnum1() numval = 0%o\n", numval); */
+       rightvalue = numval;
+       rightflags = FABS;
+       oprand();
+}
+
+void exnum() {
+       p1getw();
+/* printf("exnum() token = 0%o\n", rightvalue); */
+       rightvalue = token;
+       rightflags = FABS;
+       oprand();
+}
+
+/* brack: */
+/*     mov     r2,-(sp) */
+/*     mov     r3,-(sp) */
+/*     jsr     pc,readop */
+/*     jsr     pc,expres1 */
+/*     cmp     r4,$'] */
+/*     beq     1f */
+/*     mov     $'],-(sp) */
+/*     jsr     pc,error */
+/* 1: */
+/*     mov     r3,r0 */
+/*     mov     r2,r1 */
+/*     mov     (sp)+,r3 */
+/*     mov     (sp)+,r2 */
+
+void brack() {
+       int tempvalue;
+       int tempflags;
+       int temptoken;
+
+       tempvalue = leftvalue;
+       tempflags = leftflags;
+       temptoken = optoken;
+       readop();
+       expres1();
+       if (token != TRBRACK)
+               error(']');
+       rightflags = leftflags;
+       rightvalue = leftvalue;
+       leftflags = tempflags;
+       leftvalue = tempvalue;
+       optoken = temptoken;
+       oprand();
+}
+
+/* oprand: */
+/*     mov     $exsw2,r5 */
+/* 1: */
+/*     cmp     (sp),(r5)+ */
+/*     beq     1f */
+/*     tst     (r5)+ */
+/*     bne     1b */
+/*     br      eoprnd */
+/* 1: */
+/*     jmp     *(r5) */
+
+
+void oprand() {
+       opfound = 1;
+       switch (optoken) {
+       default:
+               eoprnd();
+               return;
+
+/*     .data */
+/* exsw2: */
+/*     '+; exadd */
+
+       case TPLUS:
+               exadd();
+               return;
+
+/*     '-; exsub */
+
+       case TMIN:
+               exsub();
+               return;
+
+/*     '*; exmul */
+
+       case TSTAR:
+               exmul();
+               return;
+
+/*     '/; exdiv */
+
+       case TSLASH:
+               exdiv();
+               return;
+
+/*     037; exor */
+
+       case TOR:
+               exor();
+               return;
+
+/*     '&; exand */
+
+       case TAND:
+               exand();
+               return;
+
+/*     035;exlsh */
+
+       case TLSH:
+               exlsh();
+               return;
+
+/*     036;exrsh */
+
+       case TRSH:
+               exrsh();
+               return;
+
+/*     '%; exmod */
+
+       case TMOD:
+               exmod();
+               return;
+
+/*     '^; excmbin */
+
+       case TCARET:
+               excmbin();
+               return;
+
+/*     '!; exnot */
+
+       case TNOT:
+               exnot();
+               return;
+
+/*     200;  0 */
+/*     .text */
+
+       }
+}
+
+/* excmbin: */
+/*     mov     r0,r3 */
+/*     br      eoprnd */
+
+void excmbin() {
+       leftflags = rightflags;
+       eoprnd();
+}
+
+/* exrsh: */
+/*     neg     r1 */
+/*     beq     exlsh */
+/*     inc     r1 */
+/*     clc */
+/*     ror     r2 */
+/* exlsh: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     ash     r1,r2 */
+/*     br      eoprnd */
+
+
+void exrsh() {
+       combin(relte2);
+       leftvalue = ((unsigned int)leftvalue & 0177777) >> rightvalue;
+       eoprnd();
+}
+
+void exlsh() {
+       combin(relte2);
+       leftvalue <<= rightvalue;
+       eoprnd();
+}
+
+/* exmod: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     mov     r3,r0 */
+/*     mov     r2,r3 */
+/*     clr     r2 */
+/*     div     r1,r2 */
+/*     mov     r3,r2 */
+/*     mov     r0,r3 */
+/*     br      eoprnd */
+
+void exmod() {
+       int temp;
+
+       combin(relte2);
+       temp = rightvalue & 0177777;
+       if (temp)
+               leftvalue = (leftvalue & 0177777) % temp;
+       else {
+               error('0'); /* a nick innovation */
+               leftvalue = 0;
+       }
+       eoprnd();
+}
+
+/* exadd: */
+/*     mov     $reltp2,r5 */
+/*     jsr     pc,combin */
+/*     add     r1,r2 */
+/*     br      eoprnd */
+
+
+void exadd() {
+       combin(reltp2);
+       leftvalue += rightvalue;
+       eoprnd();
+}
+
+/* exsub: */
+/*     mov     $reltm2,r5 */
+/*     jsr     pc,combin */
+/*     sub     r1,r2 */
+/*     br      eoprnd */
+
+void exsub() {
+       combin(reltm2);
+       leftvalue -= rightvalue;
+       eoprnd();
+}
+
+/* exand: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     com     r1 */
+/*     bic     r1,r2 */
+/*     br      eoprnd */
+
+void exand() {
+       combin(relte2);
+       leftvalue &= rightvalue;
+       eoprnd();
+}
+
+/* exor: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     bis     r1,r2 */
+/*     br      eoprnd */
+
+void exor() {
+       combin(relte2);
+       leftvalue |= rightvalue;
+       eoprnd();
+}
+
+/* exmul: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     mul     r2,r1 */
+/*     mov     r1,r2 */
+/*     br      eoprnd */
+
+void exmul() {
+       combin(relte2);
+       leftvalue *= rightvalue;
+       eoprnd();
+}
+
+/* exdiv: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     mov     r3,r0 */
+/*     mov     r2,r3 */
+/*     clr     r2 */
+/*     div     r1,r2 */
+/*     mov     r0,r3 */
+/*     br      eoprnd */
+
+void exdiv() {
+       int temp;
+
+       combin(relte2);
+       temp = rightvalue & 0177777;
+       if (temp)
+               leftvalue = (leftvalue & 0177777) / temp;
+       else {
+               error('0'); /* a nick innovation */
+               leftvalue = 0;
+       }
+       eoprnd();
+}
+
+/* exnot: */
+/*     mov     $relte2,r5 */
+/*     jsr     pc,combin */
+/*     com     r1 */
+/*     add     r1,r2 */
+/*     br      eoprnd */
+
+void exnot() {
+       combin(relte2);
+       leftvalue += ~rightvalue;
+       eoprnd();
+}
+
+/* eoprnd: */
+/*     mov     $'+,(sp) */
+/*     jmp     advanc */
+
+void eoprnd() {
+       optoken = TPLUS;
+}
+
+/* combin: */
+/*     tst     passno */
+/*     bne     combin1 */
+
+void combin(table) char *table; {
+       int global;
+       int flags;
+
+       if (passno == 0) {
+
+/*     mov     r0,-(sp) */
+/*     bis     r3,(sp) */
+/*     bic     $!40,(sp) */
+/*     bic     $!37,r0 */
+/*     bic     $!37,r3 */
+/*     cmp     r0,r3 */
+/*     ble     1f */
+/*     mov     r0,-(sp) */
+/*     mov     r3,r0 */
+/*     mov     (sp)+,r3 */
+/* 1: */
+
+               global = (rightflags | leftflags) & FGLOBAL;
+               rightflags &= 037;
+               leftflags &= 037;
+               if (rightflags > leftflags) {
+                       flags = rightflags;
+                       rightflags = leftflags;
+                       leftflags = flags;
+               }
+
+/*     tst     r0 */
+/*     beq     1f */
+/*     cmp     r5,$reltm2 */
+/*     bne     2f */
+/*     cmp     r0,r3 */
+/*     bne     2f */
+/*     mov     $1,r3 */
+/*     br      2f */
+/* 1: */
+/*     clr     r3 */
+/* 2: */
+/*     bis     (sp)+,r3 */
+/*     rts     pc */
+
+               if (rightflags) {
+                       if (table == reltm2 && rightflags == leftflags)
+                               leftflags = TABS;
+               }
+               else {
+                       leftflags = 0;
+               }
+               leftflags |= global;
+       }
+
+/* combin1: */
+/*     mov     r1,-(sp) */
+/*     clr     maxtyp */
+
+       else {
+               maxtyp = 0;
+
+/*     jsr     pc,maprel */
+/*     mov     r0,r1 */
+/*     mul     $6,r1 */
+/*     mov     r3,r0 */
+/*     jsr     pc,maprel */
+/*     add     r5,r0 */
+/*     add     r1,r0 */
+/*     movb    (r0),r3 */
+
+               leftflags = table[maprel(rightflags) * 6 + maprel(leftflags)];
+
+/*     bpl     1f */
+/*     cmp     r3,$-1 */
+/*     beq     2f */
+/*     mov     $'r,-(sp) */
+/*     jsr     pc,error */
+/* 2: */
+/*     mov     maxtyp,r3 */
+/* 1: */
+
+               if (leftflags < 0) {
+                       if (leftflags != M)
+                               error('r');
+                       leftflags = maxtyp;
+               }
+
+/*     mov     (sp)+,r1 */
+/*     rts     pc */
+
+       }
+}
+
+/* maprel: */
+/*     cmp     r0,$40 */
+/*     bne     1f */
+/*     mov     $5,r0 */
+/*     rts     pc */
+/* 1: */
+/*     bic     $!37,r0 */
+/*     cmp     r0,maxtyp */
+/*     blos    1f */
+/*     mov     r0,maxtyp */
+/* 1: */
+/*     cmp     r0,$5 */
+/*     blo     1f */
+/*     mov     $1,r0 */
+/* 1: */
+/*     rts     pc */
+
+int maprel(flags) int flags; {
+       if (flags == FGLOBAL)
+               return 5;
+       flags &= 037;
+       if (maxtyp < flags)
+               maxtyp = flags;
+       if (flags > FBSS)
+               flags = FABS;
+       return flags;
+}
+
+/*     .data */
+/* X = -2 */
+/* M = -1 */
+/* reltp2: */
+/*     .byte 0, 0, 0, 0, 0, 0 */
+/*     .byte 0, M, 2, 3, 4,40 */
+/*     .byte 0, 2, X, X, X, X */
+/*     .byte 0, 3, X, X, X, X */
+/*     .byte 0, 4, X, X, X, X */
+/*     .byte 0,40, X, X, X, X */
+
+char reltp2[36] = {
+       0,  0, 0, 0, 0,  0,
+       0,  M, 2, 3, 4,040,
+       0,  2, X, X, X,  X,
+       0,  3, X, X, X,  X,
+       0,  4, X, X, X,  X,
+       0,040, X, X, X,  X
+};
+
+/* reltm2: */
+/*     .byte 0, 0, 0, 0, 0, 0 */
+/*     .byte 0, M, 2, 3, 4,40 */
+/*     .byte 0, X, 1, X, X, X */
+/*     .byte 0, X, X, 1, X, X */
+/*     .byte 0, X, X, X, 1, X */
+/*     .byte 0, X, X, X, X, X */
+
+char reltm2[36] = {
+       0, 0, 0, 0, 0,  0,
+       0, M, 2, 3, 4,040,
+       0, X, 1, X, X,  X,
+       0, X, X, 1, X,  X,
+       0, X, X, X, 1,  X,
+       0, X, X, X, X,  X
+};
+
+/* relte2: */
+/*     .byte 0, 0, 0, 0, 0, 0 */
+/*     .byte 0, M, X, X, X, X */
+/*     .byte 0, X, X, X, X, X */
+/*     .byte 0, X, X, X, X, X */
+/*     .byte 0, X, X, X, X, X */
+/*     .byte 0, X, X, X, X, X */
+
+char relte2[36] = {
+       0, 0, 0, 0, 0, 0,
+       0, M, X, X, X, X,
+       0, X, X, X, X, X,
+       0, X, X, X, X, X,
+       0, X, X, X, X, X,
+       0, X, X, X, X, X
+};
+
+/* qnl:        <?\n> */
+/* a.out:      <a.out\0> */
+/*     .even */
+/* a.outp:     a.out */
+
+char *a_outp = "a.out";
+
+/* obufp:      outbuf */
+
+short *obufp = outbuf;
+
+/* passno: -1 */
+
+int passno = -1;
+
+/* outmod:     0777 */
+
+int outmod = 0777;
+
+/* tseekp:     txtseek */
+
+off_t *tseekp = seek;
+
+/* rseekp:     trelseek */
+
+off_t *rseekp = seek + 3;
+
+/* txtmagic: */
+/*     br      .+20 */
+/* txtsiz:     .=.+2 */
+/* datsiz:     .=.+2 */
+/* bsssiz:     .=.+2 */
+/* symsiz:     .=.+2 */
+/*     .=.+6 */
+
+int siz[4];
+
+/* txtseek:0; 20 */
+/* datseek:.=.+4 */
+/*     .=.+4 */
+/* trelseek:.=.+4 */
+/* drelseek:.=.+4 */
+/*     .=.+4 */
+/* symseek:.=.+4 */
+
+off_t seek[7];
+
+/*     .bss */
+/* brlen       = 1024. */
+/* brtab:      .=.+[brlen\/8.] */
+
+char brtab[brlen / 8];
+
+/* brtabp:     .=.+2 */
+
+int brtabp;
+
+/* brdelt:     .=.+2 */
+
+int brdelt;
+
+/* fbbufp: .=.+2 */
+
+struct symbol **fbbufp;
+
+/* defund:     .=.+2 */
+
+int defund;
+
+/* datbase:.=.+2 */
+/* bssbase:.=.+2 */
+
+int base[3];
+
+/* ibufc:      .=.+2 */
+
+int ibufc;
+
+/* overlaid: .=.+2 */
+
+int overlaid;
+
+/* adrbuf:     .=.+12. */
+
+intptr_t adrbuf[6];
+
+/* xsymbol:.=.+2 */
+
+struct symbol *xsymbol;
+
+/* errflg:     .=.+2 */
+
+int errflg;
+
+/* argb:       .=.+22. */
+
+char argb[22];
+
+#if 0
+/* numval:     .=.+2 */
+
+int numval;
+#endif
+
+/* maxtyp:     .=.+2 */
+
+int maxtyp;
+
+/* ibufp:      .=.+2 */
+
+short *ibufp;
+char *p0ibufp;
+
+/* txtp:       .=.+8. */
+/*     .=.+1024. */
+
+struct stream txtp;
+
+/* relp:       .=.+8. */
+/* outbuf: */
+/*     .=.+1024. */
+
+struct stream relp;
+
+/* swapf:      .=.+2 */
+
+int swapf;
+
+/* rlimit:     .=.+2 */
+
+int rlimit;
+
+/* endtable:.=.+2 */
+
+struct symbol **endtable;
+
+/* totalsz:                    / string table length */
+/*     .=.+4 */
+/*     .text */
+
+off_t totalsz;
+
diff --git a/as2.h b/as2.h
new file mode 100644 (file)
index 0000000..c14867f
--- /dev/null
+++ b/as2.h
@@ -0,0 +1,149 @@
+#ifndef _AS2_H
+#define _AS2_H 1
+
+#include "krcompat.h"
+
+#define brlen 1024
+
+#define X -2
+#define M -1
+
+#define outbuf ((short *)relp.data)
+
+struct stream {
+       char *append;
+       char *limit;
+       off_t offset;
+       char data[02000];
+};
+
+extern intptr_t *adrptr; /* r5 */
+extern int opcode; /* (sp) or 2(sp) if rvalue is present */
+extern int rvalue; /* (sp) */
+extern char reltp2[36];
+extern char reltm2[36];
+extern char relte2[36];
+extern char *a_outp;
+extern short *obufp;
+extern int passno;
+extern int outmod;
+extern off_t *tseekp;
+extern off_t *rseekp;
+extern int siz[4];
+extern off_t seek[7];
+extern char brtab[brlen / 8];
+extern int brtabp;
+extern int brdelt;
+extern struct symbol **fbbufp;
+extern int defund;
+extern int base[3];
+extern int ibufc;
+extern int overlaid;
+extern intptr_t adrbuf[6];
+extern struct symbol *xsymbol;
+extern int errflg;
+extern char argb[22];
+extern int numval;
+extern int maxtyp;
+extern short *ibufp;
+extern char *p0ibufp;
+extern struct stream txtp;
+extern struct stream relp;
+extern int swapf;
+extern int rlimit;
+extern struct symbol **endtable;
+extern off_t totalsz;
+
+void pass1 PARAMS((void));
+void saexit PARAMS((void));
+int aexit PARAMS((void));
+void filerr PARAMS((char *p));
+void osymout PARAMS((void));
+void nsymout PARAMS((void));
+void putstring PARAMS((char *p));
+void doreloc PARAMS((struct symbol *psymbol));
+void setup PARAMS((void));
+void outw PARAMS((int value, int flags));
+void outb PARAMS((int value, int flags));
+void pass1_2 PARAMS((void));
+int checkeos PARAMS((void));
+void fbadv PARAMS((int label));
+void oset PARAMS((struct stream *pstream, off_t offset));
+void p1putw PARAMS((struct stream *pstream, int word));
+void flush PARAMS((struct stream *pstream));
+void wrterr PARAMS((void));
+void readop PARAMS((void));
+void p1getw PARAMS((void));
+int getw1 PARAMS((void));
+void xpr PARAMS((void));
+void opline PARAMS((void));
+void opeof PARAMS((void));
+void opl30 PARAMS((void));
+void opl14 PARAMS((void));
+void opl5 PARAMS((void));
+void opl13 PARAMS((void));
+void op2a PARAMS((void));
+void op2b PARAMS((void));
+void opl15 PARAMS((void));
+void opl12 PARAMS((void));
+void opl35 PARAMS((void));
+void opl36 PARAMS((void));
+void opl31 PARAMS((void));
+void opl6 PARAMS((void));
+void dobranch PARAMS((void));
+void branch PARAMS((void));
+void binstr PARAMS((void));
+void errorb PARAMS((void));
+void opl7 PARAMS((void));
+void opl10 PARAMS((void));
+void opl11 PARAMS((void));
+void rinstr PARAMS((void));
+void opl16 PARAMS((void));
+#if 1 /* modifications for dec syntax */
+void opldotword PARAMS((void));
+#endif
+void opl17 PARAMS((void));
+void opl20 PARAMS((void));
+void opl21 PARAMS((void));
+void opl22 PARAMS((void));
+void oplret PARAMS((void));
+void opl23 PARAMS((void));
+void opl25 PARAMS((void));
+void opl26 PARAMS((void));
+void opl27 PARAMS((void));
+void opl32 PARAMS((void));
+void addres PARAMS((void));
+void addres1 PARAMS((void));
+void getx PARAMS((void));
+void alp PARAMS((void));
+void amin PARAMS((void));
+void adoll PARAMS((void));
+void astar PARAMS((void));
+void checkreg PARAMS((void));
+void checkrp PARAMS((void));
+int setbr PARAMS((int value));
+int getbr PARAMS((void));
+void expres PARAMS((void));
+void expres1 PARAMS((void));
+void binop PARAMS((void));
+void exnum1 PARAMS((void));
+void exnum PARAMS((void));
+void brack PARAMS((void));
+void oprand PARAMS((void));
+void excmbin PARAMS((void));
+void exrsh PARAMS((void));
+void exlsh PARAMS((void));
+void exmod PARAMS((void));
+void exadd PARAMS((void));
+void exsub PARAMS((void));
+void exand PARAMS((void));
+void exor PARAMS((void));
+void exmul PARAMS((void));
+void exdiv PARAMS((void));
+void exnot PARAMS((void));
+void eoprnd PARAMS((void));
+void combin PARAMS((char *table));
+int maprel PARAMS((int flags));
+
+#endif
+
diff --git a/krcompat.h b/krcompat.h
new file mode 100644 (file)
index 0000000..b5c0b7d
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _KRCOMPAT_H
+#define _KRCOMPAT_H 1
+
+#undef PARAMS
+#ifdef __STDC__
+#include <stdarg.h>
+#define VA_START(ap, arg) va_start(ap, arg)
+#define PARAMS(args) args
+#else
+#include <varargs.h>
+#define VA_START(ap, arg) va_start(ap)
+#define PARAMS(args) ()
+#endif
+
+#ifdef __GNUC__
+#define NORETURN __attribute__ ((noreturn))
+#else
+#define NORETURN
+#endif
+
+#endif