#include <perms.h>
#include <stdlib.h>
extern void Ncode(int Start, int Finish, int Ca) {
  auto void Primarydecode(void);
  auto void Secondarydecode(void);
  auto void Tertiarydecode(void);
  auto void Decompile(void);
  static const _imp_string Ops[128 /*0:127*/] = {
      _imp_str_literal("     "), _imp_str_literal("JCC  "),
      _imp_str_literal("JAT  "), _imp_str_literal("JAF  "),
      _imp_str_literal("     "), _imp_str_literal("     "),
      _imp_str_literal("     "), _imp_str_literal("     "),
      _imp_str_literal("VAL  "), _imp_str_literal("CYD  "),
      _imp_str_literal("INCA "), _imp_str_literal("MODD "),
      _imp_str_literal("PRCL "), _imp_str_literal("J    "),
      _imp_str_literal("JLK  "), _imp_str_literal("CALL "),
      _imp_str_literal("ADB  "), _imp_str_literal("SBB  "),
      _imp_str_literal("DEBJ "), _imp_str_literal("CPB  "),
      _imp_str_literal("SIG  "), _imp_str_literal("MYB  "),
      _imp_str_literal("VMY  "), _imp_str_literal("CPIB "),
      _imp_str_literal("LCT  "), _imp_str_literal("MPSR "),
      _imp_str_literal("CPSR "), _imp_str_literal("STCT "),
      _imp_str_literal("EXIT "), _imp_str_literal("ESEX "),
      _imp_str_literal("OUT  "), _imp_str_literal("ACT  "),
      _imp_str_literal("SL   "), _imp_str_literal("SLSS "),
      _imp_str_literal("SLSD "), _imp_str_literal("SLSQ "),
      _imp_str_literal("ST   "), _imp_str_literal("STUH "),
      _imp_str_literal("STXN "), _imp_str_literal("IDLE "),
      _imp_str_literal("SLD  "), _imp_str_literal("SLB  "),
      _imp_str_literal("TDEC "), _imp_str_literal("INCT "),
      _imp_str_literal("STD  "), _imp_str_literal("STB  "),
      _imp_str_literal("STLN "), _imp_str_literal("STSF "),
      _imp_str_literal("L    "), _imp_str_literal("LSS  "),
      _imp_str_literal("LSD  "), _imp_str_literal("LSQ  "),
      _imp_str_literal("RRTC "), _imp_str_literal("LUH  "),
      _imp_str_literal("RALN "), _imp_str_literal("ASF  "),
      _imp_str_literal("LDRL "), _imp_str_literal("LDA  "),
      _imp_str_literal("LDTB "), _imp_str_literal("LDB  "),
      _imp_str_literal("LD   "), _imp_str_literal("LB   "),
      _imp_str_literal("LLN  "), _imp_str_literal("LXN  "),
      _imp_str_literal("TCH  "), _imp_str_literal("ANDS "),
      _imp_str_literal("ORS  "), _imp_str_literal("NEQS "),
      _imp_str_literal("EXPA "), _imp_str_literal("AND  "),
      _imp_str_literal("OR   "), _imp_str_literal("NEQ  "),
      _imp_str_literal("PK   "), _imp_str_literal("INS  "),
      _imp_str_literal("SUPK "), _imp_str_literal("     "),
      _imp_str_literal("COMA "), _imp_str_literal("DDV  "),
      _imp_str_literal("DRDV "), _imp_str_literal("DMDV "),
      _imp_str_literal("SWEQ "), _imp_str_literal("SWNE "),
      _imp_str_literal("CPS  "), _imp_str_literal("TTR  "),
      _imp_str_literal("FLT  "), _imp_str_literal("IDV  "),
      _imp_str_literal("IRDV "), _imp_str_literal("IMDV "),
      _imp_str_literal("MVL  "), _imp_str_literal("MV   "),
      _imp_str_literal("CHOV "), _imp_str_literal("     "),
      _imp_str_literal("FIX  "), _imp_str_literal("RDV  "),
      _imp_str_literal("RRDV "), _imp_str_literal("RDVD "),
      _imp_str_literal("UAD  "), _imp_str_literal("USB  "),
      _imp_str_literal("URSB "), _imp_str_literal("UCP  "),
      _imp_str_literal("USH  "), _imp_str_literal("ROT  "),
      _imp_str_literal("SHS  "), _imp_str_literal("SHZ  "),
      _imp_str_literal("DAD  "), _imp_str_literal("DSB  "),
      _imp_str_literal("DRSB "), _imp_str_literal("DCP  "),
      _imp_str_literal("DSH  "), _imp_str_literal("DMY  "),
      _imp_str_literal("DMYD "), _imp_str_literal("CBIN "),
      _imp_str_literal("IAD  "), _imp_str_literal("ISB  "),
      _imp_str_literal("IRSB "), _imp_str_literal("ICP  "),
      _imp_str_literal("ISH  "), _imp_str_literal("IMY  "),
      _imp_str_literal("IMYD "), _imp_str_literal("CDEC "),
      _imp_str_literal("RAD  "), _imp_str_literal("RSB  "),
      _imp_str_literal("RRSB "), _imp_str_literal("RCP  "),
      _imp_str_literal("RSC  "), _imp_str_literal("RMY  "),
      _imp_str_literal("RMYD "), _imp_str_literal("     ")};
  int I;
  int J;
  int K;
  int Kp;
  int Kpp;
  int N;
  int Opcode;
  int Flag;
  int Size;
  int L;
  int Trace;
  int Decomp;
  int Insl;
  int Dec;
  int Tos;
  int H;
  int Q;
  int Ins;
  int Mask;
  int Litfill;
  int M;
  int Kppp;
  int Pc;
  int All;
  static const int Hx[16 /*0:15*/] = {'0', '1', '2', '3', '4', '5', '6', '7',
                                      '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  void Move(int Length, int From, int To) {
#ifdef NEVER
    int I;
    if (Length <= 0)
      return;
    I = 0x18000000 | Length;
    asm("LSS FROM ");
    asm("LUH I ");
    asm("LDTB I ");
    asm("LDA TO ");
    asm("MV %L=%DR ");
#else
    // void *memmove(void *dest, const void *src, size_t n)
    memmove((void *)To, (void *)From, Length);
#endif
  }
  void Phex(int N) {
    int I;
    int J;
    int H;
    H = Addr(N);
    for (I = 0; I <= 3; I++) {
      J = *Byteinteger(I + H);
      Printsymbol(Hx[(unsigned)J >> 4]);
      Printsymbol(Hx[J & 15]);
    }
  }
  Pc = 0;
  if ((unsigned)Start >> 18 != (unsigned)Finish >> 18) { // EMAS page size...
    Start = ((unsigned)Finish >> 18) << 18;
    Ca = Start;
  }
  All = Finish - Start;
  I = 0x18000000 | All;
  // if Start is not valid memory, goto BADADDR...
  //asm("LDTB I ");
  //asm("LDA START ");
  //asm("VAL (%LNB+1) ");
  //asm("JCC 3,<BADADDR> ");
  Newline();
  while (Pc < All) {
    Flag = 0;
    H = 0;
    Dec = 0;
    Move(4, Start + Pc, Addr(Ins));
    Opcode = (unsigned)Ins >> 25 << 1;
    if (Opcode == 0 || Opcode == 254 || 8 <= Opcode && Opcode <= 14) {
      Insl = 16;
      Flag = 1;
    } else if (2 <= Opcode && Opcode <= 8)
      Tertiarydecode();
    else if (0x8 <= (unsigned)Opcode >> 4 && (unsigned)Opcode >> 4 <= 0xB &&
             (Opcode & 0xF) < 7)
      Secondarydecode();
    else
      Primarydecode();
    Decompile();
    Pc += (unsigned)Insl >> 3;
    Newline();
  }
  return;
Badaddr:;
  Printstring(_imp_str_literal(
      " \nINACCESSIBLE CODE AREA PASSED TO NCODE FOR PRINTING - "));
  Phex(Start);
  Printstring(_imp_str_literal(" TO "));
  Phex(Finish);
  Newlines(2);
  void Primarydecode(void) {
    Dec = 1;
    K = (unsigned)Ins << 7 >> 30;
    N = (unsigned)Ins << 9 >> 25;
    if (K != 3) {
      Insl = 16;
      return;
    }
    Kp = (unsigned)Ins << 9 >> 30;
    Kpp = (unsigned)Ins << 11 >> 29;
    if (Kpp < 6) {
      Insl = 32;
      N = Ins & 0x3FFFF;
    } else {
      if (Ins & 0x30000)
        Printstring(_imp_str_literal(" RES. FIELD #0 \n"));
      Insl = 16;
    }
  }
  void Secondarydecode(void) {
    H = (unsigned)Ins << 7 >> 31;
    Q = (unsigned)Ins << 8 >> 31;
    N = (unsigned)Ins << 9 >> 25;
    if (Q == 1)
      Insl = 32;
    else
      Insl = 16;
  }
  void Tertiarydecode(void) {
    Dec = 3;
    Kppp = (unsigned)Ins << 11 >> 29;
    if (Kppp > 5)
      Insl = 16;
    else
      Insl = 32;
    N = Ins & 0x3FFFF;
    if (Insl == 16 && (unsigned)Ins << 14 >> 16 != 0)
      Printstring(_imp_str_literal(" 2 LS BITS #0 \n"));
  }
  void Decompile(void) {
    static const _imp_string Pop[32 /*0:31*/] = {
        _imp_str_literal("N           "), _imp_str_literal("***         "),
        _imp_str_literal("(LNB+N)     "), _imp_str_literal("(XNB+N)     "),
        _imp_str_literal("(PC+N)      "), _imp_str_literal("(CTB+N)     "),
        _imp_str_literal("TOS         "), _imp_str_literal("B           "),
        _imp_str_literal("(DR+N)      "), _imp_str_literal("***         "),
        _imp_str_literal("(DR+(LNB+N))"), _imp_str_literal("(DR+(XNB+N))"),
        _imp_str_literal("(DR+(PC+N)) "), _imp_str_literal("(DR+(CTB+N))"),
        _imp_str_literal("(DR+TOS)    "), _imp_str_literal("***         "),
        _imp_str_literal("ISN         "), _imp_str_literal("***         "),
        _imp_str_literal("((LNB+N))   "), _imp_str_literal("((XNB+N))   "),
        _imp_str_literal("((PC+N))    "), _imp_str_literal("((CTB+N))   "),
        _imp_str_literal("(TOS)       "), _imp_str_literal("(DR)        "),
        _imp_str_literal("ISB         "), _imp_str_literal("***         "),
        _imp_str_literal("((LNB+N)+B) "), _imp_str_literal("((XNB+N)+B) "),
        _imp_str_literal("((PC+N)+B)  "), _imp_str_literal("((CTB+N)+B) "),
        _imp_str_literal("(TOS+B)   "),   _imp_str_literal("(DR+B)    ")};
    static const _imp_string Top[8 /*0:7*/] = {
        _imp_str_literal("N           "), _imp_str_literal("(DR+N)      "),
        _imp_str_literal("(LNB+N)     "), _imp_str_literal("(XNB+N)     "),
        _imp_str_literal("(PC+N)      "), _imp_str_literal("(CTB+N)     "),
        _imp_str_literal("(DR)        "), _imp_str_literal("(DR+B)      ")};
    J = Pc + Ca;
    Printsymbol(Hx[((unsigned)J >> 16) & 3]);
    Printsymbol(Hx[((unsigned)J >> 12) & 15]);
    Printsymbol(Hx[((unsigned)J >> 8) & 15]);
    Printsymbol(Hx[((unsigned)J >> 4) & 15]);
    Printsymbol(Hx[J & 15]);
    Spaces(4);
    if (Insl == 16)
      Spaces(4);
    if (Insl == 16)
      for (J = 28; J >= 16; J -= 4)
        Printsymbol(Hx[((unsigned)Ins >> J) & 15]);
    else
      Phex(Ins);
    if (Flag == 1)
      return;
    Space();
    Printstring(Ops[((unsigned)Opcode >> 1)]);
    Space();
    if (Dec == 1) {
      if (K < 3) {
        if (K == 1)
          Printstring(_imp_str_literal("(LNB+N)     X"));
        if (K == 2)
          Printstring(_imp_str_literal("@(LNB+N)    X"));
        if (!K)
          Printstring(_imp_str_literal("            X"));
        if (!K)
          if ((unsigned)N >> 6 == 1) {
            N = -(N | 0xFFFFFF80);
            Printsymbol('-');
          }
        Printsymbol(Hx[((unsigned)N >> 4) & 7]);
        Printsymbol(Hx[N & 15]);
      } else {
        Printstring(Pop[Kp * 8 + Kpp]);
        if (Insl == 32) {
          Printstring(_imp_str_literal("X"));
          if ((Kp == 0 && Kpp == 0) || Kpp == 4)
            if (((unsigned)N >> 16) > 1) {
              N = -(N | 0xFFFC0000);
              Printsymbol('-');
            }
          Printsymbol(Hx[((unsigned)N >> 16) & 3]);
          for (I = 12; I >= 0; I -= 4)
            Printsymbol(Hx[((unsigned)N >> I) & 15]);
        }
      }
      if (Ins == 0x62) {
        Printstring(_imp_str_literal("  ("));
        Write(N, 1);
        Printstring(_imp_str_literal(")"));
      }
    }
    if (Dec == 2) {
      Printstring(_imp_str_literal("            X"));
      Printsymbol(Hx[((unsigned)Ins >> 20) & 7]);
      Printsymbol(Hx[((unsigned)Ins >> 16) & 15]);
      if (Insl == 32) {
        Printstring(_imp_str_literal(" X"));
        Printsymbol(Hx[((unsigned)Ins >> 12) & 15]);
        Printsymbol(Hx[((unsigned)Ins >> 8) & 15]);
        Printstring(_imp_str_literal(" X"));
        Printsymbol(Hx[((unsigned)Ins >> 4) & 15]);
        Printsymbol(Hx[Ins & 15]);
        Printstring(_imp_str_literal(" H="));
        Write(H, 1);
      }
    }
    if (Dec == 3) {
      Printstring(Top[Kppp]);
      if (Insl == 32) {
        Printstring(_imp_str_literal(" X"));
        Printsymbol(Hx[((unsigned)Ins >> 21) & 15]);
        Printstring(_imp_str_literal(" X"));
        if (Kppp == 0 || Kppp == 4)
          if (((unsigned)N >> 16) > 1) {
            N = -(N | 0xFFFC0000);
            Printsymbol('-');
          }
        Printsymbol(Hx[((unsigned)N >> 16) & 3]);
        for (I = 12; I >= 0; I -= 4)
          Printsymbol(Hx[((unsigned)N >> I) & 15]);
      }
    }
  }
}
