#include <perms.h>
static const _imp_string Snl = _imp_str_literal("\n");
int A[500 /*1:500*/];
unsigned char Named[1024 /*1:1024*/];
int Namedlink[256 /*0:255*/];
int Taglink[256 /*0:255*/];
int Tag[512 /*1:512*/];
int Link[512 /*1:512*/];
int Nextrad[16 /*0:15*/];
int Rt[16 /*0:15*/];
int Parms[16 /*0:15*/];
_imp_string Display[16 /*0:15*/];
int Faults = 0;
extern int Tagasl;
extern int Level;
extern int Tagsopt;
extern int Nextcad;
extern int Namedp;
extern int Traceopt;
extern int Aopt;
extern int Pstr;
int Intstr(_imp_string Val);
void Expr(int Exprp);
static void Popitem(int *F, int *L);
int Outstream(void);
static int Used[16 /*0:15*/] = {[0 ... 15] = 0};
static int Worklist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Namelist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Branchlist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Startlist[16 /*0:15*/] = {[0 ... 15] = 0};
static int Cot[128 /*0:127*/];
static int Cotp;
static int Params;
_imp_string Strint(int N, int P) {
  _imp_string R;
  _imp_string S;
  if (N < 0) {
    S = _imp_str_literal("-");
    N = -N;
  } else
    S = _imp_str_literal("");
  R = _imp_str_literal("");
  do {
    R = _imp_join(Tostring(N - N / 10 * 10 + '0'), R);
    N = N / 10;
  } while (N);
  R = _imp_join(S, R);
  while (*Length(R) < P) R = _imp_join(_imp_str_literal(" "), R);
  return (R);
}
_imp_string S(int I) { return (Strint(I, 0)); }
_imp_string Strhex(int N) {
  static const _imp_string H[16 /*0:15*/] = {
      _imp_str_literal("0"), _imp_str_literal("1"), _imp_str_literal("2"), _imp_str_literal("3"),
      _imp_str_literal("4"), _imp_str_literal("5"), _imp_str_literal("6"), _imp_str_literal("7"),
      _imp_str_literal("8"), _imp_str_literal("9"), _imp_str_literal("A"), _imp_str_literal("B"),
      _imp_str_literal("C"), _imp_str_literal("D"), _imp_str_literal("E"), _imp_str_literal("F")};
  int I;
  _imp_string Sh;
  Sh = _imp_str_literal("");
  for (I = 1; I <= 8; I++) {
    Sh = _imp_join(H[N & 0xF], Sh);
    N = (unsigned)N >> 4;
  }
  return (Sh);
}
void Fault(_imp_string Mess) {
  int St;
  Printstring(_imp_join(_imp_str_literal("?  "), _imp_join(Mess, _imp_str_literal("\n\n"))));
  St = Outstream();
  Selectoutput(0);
  Printstring(_imp_join(_imp_str_literal("*"), _imp_join(Mess, Snl)));
  Selectoutput(St);
  Faults++;
}
void Dump(_imp_string Lab, _imp_string Op, _imp_string Reg, _imp_string Addr) {
  static _imp_string Label = _imp_str_literal("");
  auto void Codeout(_imp_string L, _imp_string O, _imp_string R, _imp_string A);
  if (_imp_strcmp(Label, _imp_str_literal("")) != 0)
    if (_imp_strcmp(Lab, _imp_str_literal("")) == 0)
      Lab = Label;
    else {
      Codeout(Label, _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("*"));
      Label = _imp_str_literal("");
    }
  if ((_imp_strcmp(Op, _imp_str_literal("ADD")) == 0 || _imp_strcmp(Op, _imp_str_literal("SUB")) == 0 ||
       _imp_strcmp(Op, _imp_str_literal("EOR")) == 0 || _imp_strcmp(Op, _imp_str_literal("OR")) == 0) &&
      _imp_strcmp(Addr, _imp_str_literal("#0")) == 0)
    return;
  if ((_imp_strcmp(Op, _imp_str_literal("AND")) == 0 || _imp_strcmp(Op, _imp_str_literal("LD")) == 0) &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0 && _imp_strcmp(Addr, _imp_str_literal("#0")) == 0) {
    Op = _imp_str_literal("CLR");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("ADD")) == 0 && _imp_strcmp(Addr, _imp_str_literal("#1")) == 0 &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0) {
    Op = _imp_str_literal("INC");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("SUB")) == 0 && _imp_strcmp(Addr, _imp_str_literal("#1")) == 0 &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0) {
    Op = _imp_str_literal("DEC");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("CMP")) == 0 && _imp_strcmp(Addr, _imp_str_literal("#0")) == 0 &&
      _imp_strcmp(Reg, _imp_str_literal("D")) != 0) {
    Op = _imp_str_literal("TST");
    Addr = _imp_str_literal("");
  }
  if (_imp_strcmp(Op, _imp_str_literal("EQU")) == 0 && _imp_strcmp(Addr, _imp_str_literal("*")) == 0)
    Label = Lab;
  else {
    Label = _imp_str_literal("");
    Codeout(Lab, Op, Reg, Addr);
  }
  void Codeout(_imp_string Lab, _imp_string Op, _imp_string Reg, _imp_string Addr) {
    _imp_string Nums;
    int I;
    void Dump2(_imp_string Lab, _imp_string Op, _imp_string Reg, _imp_string Addr) {
      static _imp_string Lastop = _imp_str_literal("silly");
      static int Inhibit = 0;
      if (_imp_strcmp(Reg, _imp_str_literal("B")) == 0 && _imp_strcmp(Op, _imp_str_literal("LD")) == 0 &&
          _imp_resolve(Addr, NULL, _imp_str_literal("#"), Nums) &&
          (!_imp_resolve(Nums, NULL, _imp_str_literal("-"), Nums)) && Intstr(Nums) > 255)
        Reg = _imp_str_literal("D");
      if (_imp_strcmp(Lab, _imp_str_literal("")) != 0) {
        if (_imp_strcmp(Op, _imp_str_literal("EQU")) == 0 && _imp_strcmp(Addr, _imp_str_literal("*")) == 0) Inhibit = 0;
        if (_imp_strcmp(Op, _imp_str_literal("EQU")) != 0) Inhibit = 0;
      }
      if (Inhibit == 0 || _imp_strcmp(Op, _imp_str_literal("EQU")) == 0) {
        Lastop = Op;
        if (_imp_strcmp(Op, _imp_str_literal("TST")) == 0 && _imp_strcmp(Reg, _imp_str_literal("B")) == 0 &&
            _imp_strcmp(Lab, _imp_str_literal("")) == 0)
          return;
        if (_imp_strcmp(Op, _imp_str_literal("CMP")) == 0 && _imp_strcmp(Addr, _imp_str_literal("#1")) == 0) {
          Addr = _imp_str_literal("");
          Op = _imp_str_literal("DEC");
        }
        Printstring(Lab);
        Spaces(10 - *Length(Lab));
        Op = _imp_join(Op, Reg);
        Printstring(Op);
        Spaces(10 - *Length(Op));
        Printstring(Addr);
        Newline();
        Nextcad++;
      }
      if (_imp_strcmp(Op, _imp_str_literal("LBRA")) == 0 || _imp_strcmp(Op, _imp_str_literal("SWI2")) == 0 ||
          (_imp_strcmp(Op, _imp_str_literal("SWI")) == 0 && _imp_strcmp(Reg, _imp_str_literal("2")) == 0))
        Inhibit = 1;
      if (_imp_strcmp(Op, _imp_str_literal("LBSR")) != 0) return;
      if (_imp_strcmp(Addr, _imp_str_literal("SHL")) == 0) Used[12] = 1;
      if (_imp_strcmp(Addr, _imp_str_literal("SHR")) == 0) Used[13] = 1;
      if (_imp_strcmp(Addr, _imp_str_literal("EXP")) == 0) Used[14] = 1;
      if (_imp_strcmp(Addr, _imp_str_literal("DIV")) == 0) Used[15] = 1;
    }
    static _imp_string L[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
    static _imp_string O[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
    static _imp_string R[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
    static _imp_string A[2 /*1:2*/] = {[0 ... 1] = _imp_str_literal("")};
    static int Buffptr = 0;
    static int Load_sw;
    static void *Load[3 /*0:2*/] = {
        &&Load_0,
        &&Load_1,
        &&Load_2,
    };
    static int Store_sw;
    static void *Store[3 /*0:2*/] = {
        &&Store_0,
        &&Store_1,
        &&Store_2,
    };
    void Flushbuffer(void) {
      int I;
      for (I = 1; I <= Buffptr; I++) Dump2(L[I], O[I], R[I], A[I]);
      Buffptr = 0;
    }
    void Checklabel(int Buff) {
      if (Buff == 3) {
        if (_imp_strcmp(Lab, _imp_str_literal("")) != 0)
          Dump2(Lab, _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("*"));
        return;
      }
      if (_imp_strcmp(L[Buff], _imp_str_literal("")) != 0)
        Dump2(L[Buff], _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("*"));
    }
    void Savethisinstr(void) {
      Buffptr++;
      if (Buffptr > 2) {
        Printstring(_imp_join(_imp_str_literal("*?????Buffer full..."), Snl));
        Flushbuffer();
      }
      L[Buffptr] = Lab;
      O[Buffptr] = Op;
      R[Buffptr] = Reg;
      A[Buffptr] = Addr;
    }
    if (_imp_strcmp(Op, _imp_str_literal("SEX")) == 0 && Buffptr != 0 &&
        _imp_strcmp(O[Buffptr], _imp_str_literal("LD")) == 0 &&
        _imp_resolve(A[Buffptr], NULL, _imp_str_literal("#"), Nums) &&
        (!_imp_resolve(Nums, NULL, _imp_str_literal("-"), Nums)) && Intstr(Nums) > 255)
      return;
    if (_imp_strcmp(Reg, _imp_str_literal("B")) != 0) {
      Flushbuffer();
      Dump2(Lab, Op, Reg, Addr);
      return;
    }
    if (_imp_strcmp(Op, _imp_str_literal("LD")) == 0) {
      goto *Load[Load_sw = Buffptr];
    Load_0:;
      Savethisinstr();
      return;
    Load_1:;
      if (_imp_strcmp(O[1], _imp_str_literal("LD")) == 0) {
        Checklabel(1);
        Buffptr = 0;
      } else if (_imp_strcmp(O[1], _imp_str_literal("ST")) == 0 && A[1] == Addr)
        if (_imp_strcmp(Lab, _imp_str_literal("")) != 0) {
          Flushbuffer();
          Savethisinstr();
          return;
        } else
          return;
      Savethisinstr();
      return;
    Load_2:;
      Dump2(L[1], O[1], R[1], A[1]);
      L[1] = L[2];
      R[1] = R[2];
      O[1] = O[2];
      A[1] = A[2];
      Buffptr = 1;
      Printstring(_imp_join(_imp_str_literal("?***** Unexpected third el = load"), Snl));
      goto *Load[Load_sw = 1];
    }
    if (_imp_strcmp(Op, _imp_str_literal("ST")) == 0) {
      goto *Store[Store_sw = Buffptr];
    Store_0:;
      Savethisinstr();
      return;
    Store_1:;
      if (_imp_strcmp(O[1], _imp_str_literal("LD")) == 0 || _imp_strcmp(O[1], _imp_str_literal("ST")) == 0)
        if (A[1] == Addr)
          if (_imp_strcmp(Lab, _imp_str_literal("")) != 0) {
            Flushbuffer();
            Savethisinstr();
            return;
          } else
            return;
        else {
          Flushbuffer();
          Savethisinstr();
          return;
        }
      if (_imp_strcmp(O[1], _imp_str_literal("CLR")) == 0) {
        Checklabel(1);
        Buffptr = 0;
        Dump2(Lab, _imp_str_literal("CLR"), _imp_str_literal(""), Addr);
        return;
      }
      Flushbuffer();
      Savethisinstr();
      return;
    Store_2:;
      if (_imp_strcmp(O[1], _imp_str_literal("LD")) == 0 && A[1] == Addr &&
          (_imp_strcmp(O[2], _imp_str_literal("INC")) == 0 || _imp_strcmp(O[2], _imp_str_literal("DEC")) == 0 ||
           _imp_strcmp(O[2], _imp_str_literal("NEG")) == 0 || _imp_strcmp(O[2], _imp_str_literal("COM")) == 0)) {
        Checklabel(2);
        Checklabel(3);
        Dump2(L[1], O[2], _imp_str_literal(""), Addr);
        Buffptr = 0;
        return;
      }
      Dump2(L[1], O[1], R[1], A[1]);
      L[1] = L[2];
      O[1] = O[2];
      R[1] = R[2];
      A[1] = A[2];
      Buffptr = 1;
      goto *Store[Store_sw = 1];
    }
    if (_imp_strcmp(Op, _imp_str_literal("TST")) == 0) {
      if (Buffptr)
        if (_imp_strcmp(O[Buffptr], _imp_str_literal("LD")) == 0) {
          Dump2(L[Buffptr], Op, _imp_str_literal(""), A[Buffptr]);
          Checklabel(3);
          Buffptr--;
          return;
        }
      Flushbuffer();
      Dump2(Lab, Op, Reg, Addr);
      return;
    }
    if (_imp_strcmp(Op, _imp_str_literal("INC")) == 0 || _imp_strcmp(Op, _imp_str_literal("DEC")) == 0 ||
        _imp_strcmp(Op, _imp_str_literal("CLR")) == 0 || _imp_strcmp(Op, _imp_str_literal("NEG")) == 0 ||
        _imp_strcmp(Op, _imp_str_literal("COM")) == 0) {
      if (Buffptr == 2) {
        Dump2(L[1], O[1], R[1], A[1]);
        L[1] = L[2];
        O[1] = O[2];
        R[1] = R[2];
        A[1] = A[2];
        L[2] = Lab;
        O[2] = Op;
        R[2] = Reg;
        A[2] = Addr;
        Buffptr = 2;
        return;
      }
      Savethisinstr();
      return;
    }
    Flushbuffer();
    Dump2(Lab, Op, Reg, Addr);
  }
}
_imp_string Name(int Ident) {
  if (0 > Ident || Ident > 255 || Namedlink[Ident] == 0) return (_imp_str_literal(""));
  return (*String(Addr(Named[Namedlink[Ident]])));
}
int Newtag(void) {
  int I;
  if (!Tagasl) {
    Fault(_imp_str_literal("TAG SPACE FULL"));
    exit(0);
  }
  I = Tagasl;
  Tagasl = Link[Tagasl];
  return (I);
}
int Returntag(int Tagi) {
  int L;
  L = Link[Tagi];
  Link[Tagi] = Tagasl;
  Tagasl = Tagi;
  return (L);
}
int Getwork(void) { return (0); }
void Returnwork(int Work) {}
void Clearwork(void) {
  int Cell;
  Cell = Worklist[Level];
  while (Cell) Cell = Returntag(Cell);
  Worklist[Level] = 0;
}
int Getcoti(int Const) {
  int Coti;
  if (Cotp > 0)
    for (Coti = 0; Coti <= Cotp - 1; Coti++)
      if (Cot[Coti] == Const) return (Coti);
  if (Cotp == 128) {
    Fault(_imp_str_literal("CONSTANT TABLE FULL"));
    exit(0);
  }
  Cot[Cotp] = Const;
  Cotp++;
  return (Cotp - 1);
}
void Pushtag(int Ident, int Form, int Type, int Dim, int Level, int Rad) {
  int Tagi;
  if (Taglink[Ident] != 0 && ((unsigned)Tag[Taglink[Ident]] >> 16 & 0xF) == Level)
    Fault(_imp_join(_imp_str_literal("NAME "), _imp_join(Name(Ident), _imp_str_literal(" DECLARED TWICE"))));
  Tagi = Newtag();
  Tag[Tagi] = Form << 28 | Type << 24 | Dim << 20 | Level << 16 | Rad;
  Link[Tagi] = Taglink[Ident];
  Taglink[Ident] = Tagi;
  Tagi = Newtag();
  Tag[Tagi] = Ident;
  Link[Tagi] = Namelist[Level];
  Namelist[Level] = Tagi;
}
void Poptags(void) {
  int Cell;
  int Ident;
  int Nametag;
  int Params;
  _imp_string S;
  if (Tagsopt == 1) Newline();
  Cell = Namelist[Level];
  while (Cell) {
    Ident = Tag[Cell];
    Cell = Returntag(Cell);
    Nametag = Tag[Taglink[Ident]];
    Taglink[Ident] = Returntag(Taglink[Ident]);
    if (Tagsopt == 1) {
      S = Name(Ident);
      Printstring(_imp_join(Strint(Ident, 3), _imp_join(_imp_str_literal("   "), S)));
      Spaces(10 - *Length(S));
      Printstring(Strhex(Nametag));
    }
    if ((unsigned)Nametag >> 28 == 4) {
      Params = (unsigned)Nametag >> 20 & 0xF;
      while (Params) {
        if (Tagsopt == 1)
          Printstring(_imp_join(_imp_str_literal("\n                    "), Strhex(Tag[Taglink[Ident]])));
        Taglink[Ident] = Returntag(Taglink[Ident]);
        Params--;
      }
    }
    if (Tagsopt == 1) Newline();
    if (!Taglink[Ident]) {
      Namedp = Namedlink[Ident];
      Namedlink[Ident] = 0;
    }
  }
  if (Tagsopt == 1) Newline();
  Namelist[Level] = 0;
}
int Getlabel(int Constp) {
  int Label;
  Label = A[Constp + 1];
  if (Label > 9999) {
    Fault(_imp_join(_imp_str_literal("LABEL "), _imp_join(Strint(Label, 1), _imp_str_literal(" TOO LARGE"))));
    return (-1);
  } else
    return (Label);
}
void Filllabel(int Label) {
  if (Label < 0) return;
  Dump(_imp_join(_imp_str_literal("L"), S(Label)), _imp_str_literal("EQU"), _imp_str_literal(""),
       _imp_str_literal("*"));
}
int Fillbranch(int Label) {
  int Cell;
  int Cad;
  if (Label < 0) return (0);
  Cell = Branchlist[Level];
  while (Cell) {
    if ((unsigned)Tag[Cell] >> 16 == Label) {
      Cad = Tag[Cell] & 0x7FFF;
      if (Tag[Cell] & 0x8000) Tag[Cell] = Label << 16 | 0x8000 | Nextcad;
      return (Cad);
    }
    Cell = Link[Cell];
  }
  Cell = Newtag();
  Link[Cell] = Branchlist[Level];
  Branchlist[Level] = Cell;
  Tag[Cell] = Label << 16 | 0x8000 | Nextcad;
  return (0);
}
void Poplabels(void) {
  int Cell;
  Cell = Branchlist[Level];
  while (Cell) {
    if (Tag[Cell] & 0x8000)
      Fault(_imp_join(_imp_str_literal("LABEL "),
                      _imp_join(Strint((unsigned)Tag[Cell] >> 16, 1),
                                _imp_join(_imp_str_literal(" NOT SET (BRANCH LIST "),
                                          _imp_join(Strint(Tag[Cell] & 0x7FFF, 1), _imp_str_literal(")"))))));
    Cell = Returntag(Cell);
  }
  Branchlist[Level] = 0;
}
int Nextplabel(void) {
  static int Plabel = 9999;
  Plabel++;
  return (Plabel);
}
void Pushstart(int Flag, int Plab) {
  int Cell;
  Cell = Newtag();
  Tag[Cell] = Flag << 16 | Plab & 0xFFFF;
  Link[Cell] = Startlist[Level];
  Startlist[Level] = Cell;
}
int /* boolean */ Find(int Type, int *T, int *Lab) {
  int Cell;
  Cell = Startlist[Level];
  while (Cell) {
    *T = (unsigned)Tag[Cell] >> 16;
    if ((*T & 2) == Type) {
      *Lab = Tag[Cell] & 0xFFFF;
      return (1);
    }
    Cell = Link[Cell];
  }
  *T = 0;
  *Lab = 0;
  return (0);
}
void Findcontinue(int *Type, int *Lab) {
  if (Find(2, *Type, *Lab))
    *Lab = *Lab + 1;
  else {
    *Type = 0;
    *Lab = 0;
    Fault(_imp_str_literal("%CYCLE MISSING"));
  }
}
void Findexit(int *Type, int *Lab) {
  if (Find(2, *Type, *Lab))
    *Lab = *Lab + 2;
  else {
    *Type = 0;
    *Lab = 0;
    Fault(_imp_str_literal("%CYCLE MISSING"));
  }
}
static int /* boolean */ Findcycle(void) {
  int T;
  int L;
  if (Find(2, T, L)) return (1);
  return (0);
}
static int /* boolean */ Findstart(void) {
  int T;
  int L;
  if (Find(0, T, L)) return (1);
  return (0);
}
void Popcycle(int *Type, int *Lab) {
  Popitem(*Type, *Lab);
  if (!(*Type & 2)) {
    if (Findcycle())
      Fault(_imp_str_literal("%FINISH MISSING {Or spurious %REPEAT??}"));
    else {
      Fault(_imp_str_literal("SPURIOUS %REPEAT"));
      if (*Lab) Pushstart(*Type, *Lab);
    }
    *Lab = 0;
    *Type = 3;
  }
}
void Popstart(int *Type, int *Lab) {
  Popitem(*Type, *Lab);
  if ((*Type & 2) == 2 || *Lab == 0) {
    if (Findstart())
      Fault(_imp_str_literal("%REPEAT MISSING {Or spurious %FINISH??}"));
    else {
      Fault(_imp_str_literal("SPURIOUS %FINISH"));
      if (*Lab) Pushstart(*Type, *Lab);
    }
    *Lab = 0;
    *Type = 0;
  }
}
static void Popitem(int *Flag, int *Plab) {
  int Cell;
  Cell = Startlist[Level];
  if (!Cell) {
    *Flag = 0;
    *Plab = 0;
  } else {
    *Flag = (unsigned)Tag[Cell] >> 16;
    *Plab = Tag[Cell] & 0xFFFF;
    if (*Plab == 0xFFFF) *Plab = -1;
    Startlist[Level] = Returntag(Cell);
  }
}
void Clearstart(void) {
  int Cell;
  static const _imp_string What[2 /*0:1*/] = {_imp_str_literal("%FINISH"), _imp_str_literal("%REPEAT")};
  Cell = Startlist[Level];
  while (Cell) {
    Fault(_imp_join(What[(unsigned)Tag[Cell] >> 17], _imp_str_literal(" MISSING")));
    Cell = Returntag(Cell);
  }
  Startlist[Level] = 0;
}
int Enter(void) {
  static _imp_string Regs[2 /*1:2*/] = {_imp_str_literal("A"), _imp_str_literal("A,B")};
  _imp_string Base;
  int Alloc;
  int Dim;
  if (Level == 1) {
    if (Nextcad != 1) Fault(_imp_str_literal("%BEGIN NOT FIRST STATEMENT"));
    Dump(_imp_str_literal(""), _imp_str_literal("ORG"), _imp_str_literal(""), _imp_str_literal("$F800"));
    Dump(_imp_str_literal("START"), _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("*"));
    if (Traceopt == 1) Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("3"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("U"), _imp_str_literal("#STACK"));
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("X"), _imp_str_literal("-USTK,U"));
    Base = _imp_str_literal(",X");
    Alloc = 34;
  } else {
    if (Level > 2) Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("Y"), Display[Level - 1]);
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("S"), _imp_str_literal("Y"));
    Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""), _imp_str_literal("S,Y"));
    Alloc = 0;
    Base = _imp_str_literal(",Y");
  }
  if (Level != 1)
    ;
  else
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_join(_imp_str_literal("-A"), _imp_join(S(Rt[Level]), _imp_str_literal(",X"))));
  Nextrad[Level] = Alloc;
  return (Alloc);
}
void Dumpreturn(void) {
  Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""), _imp_str_literal("Y,S"));
  Dump(_imp_str_literal(""), _imp_str_literal("PUL"), _imp_str_literal("S"), _imp_str_literal("Y,PC"));
}
void Array(int Arrayp) {
  int Namep;
  int Actualp;
  int Exprp;
  int Exprsp;
  int Ident;
  int Nametag;
  int Basep;
  int Disp;
  _imp_string Base;
  Namep = A[Arrayp + 1];
  Actualp = A[Arrayp + 2];
  Ident = A[Namep + 1];
  if (A[Actualp] == 1) {
    Dump(_imp_str_literal("  "), _imp_str_literal("CLR"), _imp_str_literal("A"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("ANDCC"), _imp_str_literal(""), _imp_str_literal("0"));
    Exprp = A[Actualp + 1];
    Exprsp = A[Actualp + 2];
    Expr(Exprp);
    Nametag = Tag[Taglink[Ident]];
    Basep = (unsigned)Nametag >> 16 & 0xF;
    Base = Display[Basep];
    if (Basep == Level) Base = _imp_str_literal(",Y");
    if (Basep == 1) Base = _imp_str_literal(",X");
    Disp = Nametag & 0xFFFF;
    Dump(_imp_str_literal(""), _imp_str_literal("BCC"), _imp_str_literal(""), _imp_str_literal("*+3"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal("A"), _imp_str_literal(""));
    if (Basep == 1 || Basep == Level)
      Dump(_imp_str_literal(""), _imp_str_literal("ADD"), _imp_str_literal("D"),
           _imp_join(_imp_str_literal("-"), _imp_join(S(Disp), Base)));
    else {
      Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"), _imp_str_literal("A,B"));
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("D"), Display[Basep]);
      Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("D"),
           _imp_join(_imp_str_literal("#"), S(Disp)));
      Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("D"), _imp_str_literal("0,X"));
      Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("D"), _imp_str_literal("[0,X]"));
      Dump(_imp_str_literal(""), _imp_str_literal("ADD"), _imp_str_literal("D"), _imp_str_literal(",U++"));
    }
    if (!Aopt) Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("D"), _imp_str_literal("0,X"));
    Aopt = 0;
    if (A[Exprsp] == 1)
      Fault(_imp_join(_imp_str_literal("ARRAY "), _imp_join(Name(Ident), _imp_str_literal(" HAS EXTRA INDEX"))));
  } else
    Fault(_imp_join(_imp_str_literal("ARRAY "), _imp_join(Name(Ident), _imp_str_literal(" HAS NO INDEX"))));
}
void Proc(int Procp) {
  _imp_string Opn;
  _imp_string Base;
  _imp_string Reg;
  int Namep;
  int Ident;
  int Nametag;
  int Ptagl;
  int L;
  int Actualp;
  int Exprp;
  int Unaryp;
  int Operandp;
  int Npars;
  int Ptag;
  int Pnamep;
  int Pident;
  int Pnametag;
  int Pactualp;
  int Disp;
  int Exprrestp;
  int Exprsp;
  int Oldparams;
  int Basep;
  int Size;
  if (Params >= 2)
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_join(_imp_str_literal("-"), _imp_join(S(Params + 1), _imp_str_literal(",S"))));
  Oldparams = Params;
  Params = 4;
  Namep = A[Procp + 1];
  Actualp = A[Procp + 2];
  Ident = A[Namep + 1];
  L = Taglink[Ident];
  Nametag = Tag[L];
  Ptagl = Link[L];
  Npars = (unsigned)Nametag >> 20 & 0xF;
  if (!Npars) {
    if (A[Actualp] == 1) {
      Fault(_imp_join(Name(Ident), _imp_str_literal(" HAS PARAMETERS")));
      return;
    }
  } else {
    if (A[Actualp] == 2) {
      Fault(_imp_join(Name(Ident), _imp_str_literal(" MISSING PARAMETERS")));
      return;
    }
    Exprp = A[Actualp + 1];
    Exprsp = A[Actualp + 2];
    for (;;) {
      Ptag = Tag[Ptagl];
      if (!((unsigned)Ptag >> 28)) {
        Expr(Exprp);
        Reg = _imp_str_literal("B");
      } else {
        Reg = _imp_str_literal("D");
        Unaryp = A[Exprp + 1];
        Operandp = A[Exprp + 2];
        Exprrestp = A[Exprp + 3];
        if (A[Unaryp] != 4 || A[Operandp] != 1 || A[Exprrestp] != 2)
          Fault(_imp_str_literal("NOT A %NAME PARAMETER"));
        else {
          Pnamep = A[Operandp + 1];
          Pactualp = A[Operandp + 2];
          Pident = A[Pnamep + 1];
          if (!Taglink[Pident])
            Dump(_imp_str_literal(""), _imp_str_literal("LD"), _imp_str_literal("B"), Name(Pident));
          else {
            Pnametag = Tag[Taglink[Pident]];
            if ((unsigned)Pnametag >> 28 == 4)
              Fault(_imp_join(Name(Pident), _imp_str_literal(" NOT A %NAME")));
            else {
              Basep = (unsigned)Pnametag >> 16 & 0xF;
              Base = Display[Basep];
              Disp = Pnametag & 0xFFFF;
              if (Basep == Level) Base = _imp_str_literal("Y");
              if (Basep == 1) Base = _imp_str_literal("X");
              if ((unsigned)Ptag >> 28 == 1)
                if ((unsigned)Pnametag >> 28 >= 2) {
                  Aopt = 1;
                  Array(Operandp);
                } else {
                  if ((unsigned)Pnametag >> 28 == 1)
                    if (1 < Basep && Basep < Level) {
                      Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg, Base);
                      Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg,
                           _imp_join(_imp_str_literal("#"), S(Disp)));
                      Dump(_imp_str_literal(""), _imp_str_literal("ST"), Reg, _imp_str_literal("0,X"));
                      Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg, _imp_str_literal("[0,X]"));
                    } else
                      Dump(
                          _imp_str_literal(""), _imp_str_literal("LD"), Reg,
                          _imp_join(_imp_str_literal("-"), _imp_join(S(Disp), _imp_join(_imp_str_literal(","), Base))));
                  else if (1 < Basep && Basep < Level) {
                    Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg, Base);
                    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg, _imp_join(_imp_str_literal("#"), S(Disp)));
                  } else {
                    if (Basep == 1 && 1 == Level) {
                      Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("Y"),
                           _imp_join(_imp_str_literal("-"), _imp_join(S(Disp), _imp_str_literal(",X"))));
                      Reg = _imp_str_literal("Y");
                    } else {
                      Dump(_imp_str_literal(""), _imp_str_literal("TFR"), _imp_str_literal(""),
                           _imp_join(Base, _imp_str_literal(",D")));
                      Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg,
                           _imp_join(_imp_str_literal("#"), S(Disp)));
                    }
                  }
                  if (A[Pactualp] == 1) Fault(_imp_join(Name(Pident), _imp_str_literal(" DECLARED AS SCALAR")));
                }
              else {
                if (_imp_strcmp(Base, _imp_str_literal("Y")) == 0 || _imp_strcmp(Base, _imp_str_literal("X")) == 0)
                  Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg,
                       _imp_join(_imp_str_literal("-"), _imp_join(S(Disp), _imp_join(_imp_str_literal(","), Base))));
                else {
                  Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg, Base);
                  Dump(_imp_str_literal(""), _imp_str_literal("SUB"), Reg, _imp_join(_imp_str_literal("#"), S(Disp)));
                  Dump(_imp_str_literal(""), _imp_str_literal("ST"), Reg, _imp_str_literal("0,X"));
                  Dump(_imp_str_literal(""), _imp_str_literal("LD"), Reg, _imp_str_literal("[0,X]"));
                }
                if (A[Pactualp] == 1)
                  Fault(_imp_join(_imp_str_literal("%ARRAYNAME "),
                                  _imp_join(Name(Pident), _imp_str_literal(" HAS INDEX"))));
              }
            }
          }
        }
      }
      if (_imp_strcmp(Reg, _imp_str_literal("D")) == 0 || _imp_strcmp(Reg, _imp_str_literal("Y")) == 0)
        Size = 2;
      else
        Size = 1;
      Params += Size;
      Dump(_imp_str_literal(""), _imp_str_literal("ST"), Reg,
           _imp_join(_imp_str_literal("-"), _imp_join(S(Params), _imp_str_literal(",S"))));
      Npars--;
      if (!Npars) {
        if (A[Exprsp] == 1) Fault(_imp_join(Name(Ident), _imp_str_literal(" HAS EXTRA PARAMETERS")));
        break;
      }
      Ptagl = Link[Ptagl];
      if (A[Exprsp] == 2) {
        Fault(_imp_join(Name(Ident), _imp_str_literal(" IS MISSING PARAMETERS")));
        break;
      }
      Exprp = A[Exprsp + 1];
      Exprsp = A[Exprsp + 2];
    }
  }
  if (!((unsigned)Nametag >> 16 & 0xF))
    Base = _imp_str_literal("EXT");
  else
    Base = _imp_str_literal("E");
  if (!((unsigned)Nametag >> 16 & 0xF)) Used[Nametag & 0xF] = 1;
  Dump(_imp_str_literal(""), _imp_str_literal("LBSR"), _imp_str_literal(""), _imp_join(Base, S(Nametag & 0xFFFF)));
  Params = Oldparams;
  if (Params >= 2)
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"),
         _imp_join(S(Params + 1), _imp_str_literal(",S")));
}
void Endofprog(void) {
  int I;
  Dump(_imp_str_literal(""), _imp_str_literal("SWI"), _imp_str_literal("2"), _imp_str_literal(""));
  Dump(_imp_str_literal("STACK"), _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("$0800-1"));
  Dump(_imp_str_literal("USTK"), _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("$20"));
  if (Used[12] == 1) {
    Dump(_imp_str_literal("DOSHL"), _imp_str_literal("LSL"), _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("A"), _imp_str_literal("#1"));
    Dump(_imp_str_literal("SHL"), _imp_str_literal("CMP"), _imp_str_literal("A"), _imp_str_literal("#0"));
    Dump(_imp_str_literal(""), _imp_str_literal("BGT"), _imp_str_literal(""), _imp_str_literal("DOSHL"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""), _imp_str_literal(""));
  }
  if (Used[13] == 1) {
    Dump(_imp_str_literal("DOSHR"), _imp_str_literal("LSR"), _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("A"), _imp_str_literal("#1"));
    Dump(_imp_str_literal("SHR"), _imp_str_literal("CMP"), _imp_str_literal("A"), _imp_str_literal("#0"));
    Dump(_imp_str_literal(""), _imp_str_literal("BGT"), _imp_str_literal(""), _imp_str_literal("DOSHR"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""), _imp_str_literal(""));
  }
  if (Used[14] == 1) {
    Dump(_imp_str_literal("EXP"), _imp_str_literal("PSH"), _imp_str_literal("S"), _imp_str_literal("B"));
    Dump(_imp_str_literal("EXP2"), _imp_str_literal("CMP"), _imp_str_literal("A"), _imp_str_literal("#1"));
    Dump(_imp_str_literal(""), _imp_str_literal("BGT"), _imp_str_literal(""), _imp_str_literal("DOEXP"));
    Dump(_imp_str_literal(""), _imp_str_literal("LEA"), _imp_str_literal("S"), _imp_str_literal("1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""), _imp_str_literal(""));
    Dump(_imp_str_literal("DOEXP"), _imp_str_literal("PSH"), _imp_str_literal("U"), _imp_str_literal("A"));
    Dump(_imp_str_literal(""), _imp_str_literal("LDA"), _imp_str_literal(""), _imp_str_literal("0,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("MUL"), _imp_str_literal(""), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("PUL"), _imp_str_literal("U"), _imp_str_literal("A"));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("A"), _imp_str_literal("#1"));
    Dump(_imp_str_literal(""), _imp_str_literal("BRA"), _imp_str_literal(""), _imp_str_literal("EXP2"));
  }
  if (Used[15] == 1) {
    Dump(_imp_str_literal("DIV"), _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("*"));
    Dump(_imp_str_literal(""), _imp_str_literal("CLR"), _imp_str_literal(""), _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("CLR"), _imp_str_literal(""), _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""), _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("TST"), _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BGE"), _imp_str_literal(""), _imp_str_literal("TRYA"));
    Dump(_imp_str_literal(""), _imp_str_literal("NEG"), _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("CLR"), _imp_str_literal(""), _imp_str_literal("-2,S"));
    Dump(_imp_str_literal("TRYA"), _imp_str_literal("TST"), _imp_str_literal("A"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BGE"), _imp_str_literal(""), _imp_str_literal("OK"));
    Dump(_imp_str_literal(""), _imp_str_literal("NEG"), _imp_str_literal("A"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("TST"), _imp_str_literal(""), _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""), _imp_str_literal("OK"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""), _imp_str_literal("-2,S"));
    Dump(_imp_str_literal("OK"), _imp_str_literal("TST"), _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BLT"), _imp_str_literal(""), _imp_str_literal("DONE"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""), _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("PSH"), _imp_str_literal("U"), _imp_str_literal("A"));
    Dump(_imp_str_literal(""), _imp_str_literal("SUB"), _imp_str_literal("B"), _imp_str_literal(",U+"));
    Dump(_imp_str_literal(""), _imp_str_literal("BRA"), _imp_str_literal(""), _imp_str_literal("OK"));
    Dump(_imp_str_literal("DONE"), _imp_str_literal("DEC"), _imp_str_literal(""), _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("TST"), _imp_str_literal(""), _imp_str_literal("-2,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""), _imp_str_literal("RET"));
    Dump(_imp_str_literal(""), _imp_str_literal("NEG"), _imp_str_literal(""), _imp_str_literal("-1,S"));
    Dump(_imp_str_literal("RET"), _imp_str_literal("LD"), _imp_str_literal("B"), _imp_str_literal("-1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""), _imp_str_literal(""));
  } else
    Dump(_imp_str_literal("DIV"), _imp_str_literal("EQU"), _imp_str_literal(""), _imp_str_literal("0"));
  if (Pstr) {
    Dump(_imp_str_literal("OUTCH"), _imp_str_literal("LD"), _imp_str_literal("A"), _imp_str_literal("ACIAS"));
    Dump(_imp_str_literal(""), _imp_str_literal("AND"), _imp_str_literal("A"), _imp_str_literal("#2"));
    Dump(_imp_str_literal(""), _imp_str_literal("BEQ"), _imp_str_literal(""), _imp_str_literal("OUTCH"));
    Dump(_imp_str_literal(""), _imp_str_literal("ST"), _imp_str_literal("B"), _imp_str_literal("ACIAD"));
    Dump(_imp_str_literal("WAITX"), _imp_str_literal("LD"), _imp_str_literal("B"), _imp_str_literal("#$FF"));
    Dump(_imp_str_literal(""), _imp_str_literal("DEC"), _imp_str_literal("B"), _imp_str_literal(""));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""), _imp_str_literal("WAITX"));
    Dump(_imp_str_literal("PSTR"), _imp_str_literal("LD"), _imp_str_literal("B"), _imp_str_literal("[0,S]"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""), _imp_str_literal("1,S"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""), _imp_str_literal("NOCAR"));
    Dump(_imp_str_literal(""), _imp_str_literal("INC"), _imp_str_literal(""), _imp_str_literal("0,S"));
    Dump(_imp_str_literal("NOCAR"), _imp_str_literal("CMP"), _imp_str_literal("B"), _imp_str_literal("#$80"));
    Dump(_imp_str_literal(""), _imp_str_literal("BNE"), _imp_str_literal(""), _imp_str_literal("OUTCH"));
    Dump(_imp_str_literal(""), _imp_str_literal("RTS"), _imp_str_literal(""), _imp_str_literal(""));
  }
  if (Faults > 0) {
    int St;
    St = Outstream();
    Selectoutput(0);
    Printstring(_imp_join(_imp_str_literal("Program contains "), _imp_join(S(Faults), _imp_str_literal(" fault"))));
    if (Faults > 1) Printsymbol('s');
    Newline();
    Selectoutput(St);
  }
  Newline();
  if (Faults > 0)
    Printstring(_imp_join(_imp_str_literal("?"), Strint(Faults, 4)));
  else
    Printstring(_imp_str_literal("*NO"));
  Printstring(_imp_str_literal(" FAULT"));
  if (Faults != 1) Printsymbol('S');
  Printstring(_imp_str_literal(" IN THIS PROGRAM\n"));
  _imp_signal(13, 0, 0, _imp_str_literal(""));
}
