--- /dev/null
+/* 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 = ‐
+ }
+
+/* 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);
+
--- /dev/null
+/* 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;
+