// cc -c -g -Wno-multichar decode-77.c -I ../new-parser/imps ../new-parser/imps/perms.c -lm
#include <perms.h>

void Decode(int S, int To, int Base) {
  static const int Opcodes[256 /*0:255*/] = {[0 ... 3] = 0,
                                             'SPM ',
                                             'BALR',
                                             'BCTR',
                                             'BCR ',
                                             'SSK ',
                                             'ISK ',
                                             'SVC ',
                                             [11 ... 15] = 0,
                                             'LPR ',
                                             'LNR ',
                                             'LTR ',
                                             'LCR ',
                                             'NR  ',
                                             'CLR ',
                                             'OR  ',
                                             'XR  ',
                                             'LR  ',
                                             'CR  ',
                                             'AR  ',
                                             'SR  ',
                                             'MR  ',
                                             'DR  ',
                                             'ALR ',
                                             'SLR ',
                                             'LPDR',
                                             'LNDR',
                                             'LTDR',
                                             'LCDR',
                                             'HDR ',
                                             'LRDR',
                                             'MXR ',
                                             'MXDR',
                                             'LDR ',
                                             'CDR ',
                                             'ADR ',
                                             'SDR ',
                                             'MDR ',
                                             'DDR ',
                                             'AWR ',
                                             'SWR ',
                                             'LPER',
                                             'LNER',
                                             'LTER',
                                             'LCER',
                                             'HER ',
                                             'LRER',
                                             'AXR ',
                                             'SXR ',
                                             'LER ',
                                             'CER ',
                                             'AER ',
                                             'SER ',
                                             'MER ',
                                             'DER ',
                                             'AUR ',
                                             'SUR ',
                                             'STH ',
                                             'LA  ',
                                             'STC ',
                                             'IC  ',
                                             'EX  ',
                                             'BAL ',
                                             'BCT ',
                                             'BC  ',
                                             'LH  ',
                                             'CH  ',
                                             'AH  ',
                                             'SH  ',
                                             'MH  ',
                                             0,
                                             'CVD ',
                                             'CVB ',
                                             'ST  ',
                                             [81 ... 83] = 0,
                                             'N   ',
                                             'CL  ',
                                             'O   ',
                                             'X   ',
                                             'L   ',
                                             'C   ',
                                             'A   ',
                                             'S   ',
                                             'M   ',
                                             'D   ',
                                             'AL  ',
                                             'SL  ',
                                             'STD ',
                                             [97 ... 102] = 0,
                                             'MXD ',
                                             'LD  ',
                                             'CD  ',
                                             'AD  ',
                                             'SD  ',
                                             'MD  ',
                                             'DD  ',
                                             'AW  ',
                                             'SW  ',
                                             'STE ',
                                             [113 ... 119] = 0,
                                             'LE  ',
                                             'CE  ',
                                             'AE  ',
                                             'SE  ',
                                             'ME  ',
                                             'DE  ',
                                             'AU  ',
                                             'SU  ',
                                             'SSM',
                                             0,
                                             'LPSW',
                                             'DIAG',
                                             'WRD ',
                                             'RDD ',
                                             'BXH ',
                                             'BXLE',
                                             'SRL ',
                                             'SLL ',
                                             'SRA ',
                                             'SLA ',
                                             'SRDL',
                                             'SLDL',
                                             'SRDA',
                                             'SLDA',
                                             'STM ',
                                             'TM  ',
                                             'MVI ',
                                             'TS  ',
                                             'NI  ',
                                             'CLI ',
                                             'OI  ',
                                             'XI  ',
                                             'LM  ',
                                             [153 ... 155] = 0,
                                             'SIO ',
                                             'TIO ',
                                             'HIO ',
                                             'TCH ',
                                             [160 ... 208] = 0,
                                             'MVN ',
                                             'MVC ',
                                             'MVZ ',
                                             'NC  ',
                                             'CLC ',
                                             'OC  ',
                                             'XC  ',
                                             [216 ... 219] = 0,
                                             'TR  ',
                                             'TRT ',
                                             'ED  ',
                                             'EDMK',
                                             [224 ... 240] = 0,
                                             'MVO ',
                                             'PACK',
                                             'UNPK',
                                             [244 ... 247] = 0,
                                             'ZAP ',
                                             'CP  ',
                                             'AP  ',
                                             'SP  ',
                                             'MP  ',
                                             'DP  ',
                                             0,
                                             0};
  int J;
  int K;
  int L;
  int M;
  int T;
  auto void Hex(int N);
  auto void Put(int S, int C);
#ifdef DEBUG
  fprintf(stderr, "DECODE: %d %d %d\n", S, To, Base);
#endif
  S = S & (~1);
L1:
  Newline();
  if (S >= To) {
    Newline();
    return;
  }
  Hex(S - Base);
  Spaces(4);
  J = *Shortinteger(S);
  S += 2;
  M = (unsigned)J >> 8 & 255;
  T = Opcodes[M];
  Hex(J);
  if (!T) goto L1;
  if (!((unsigned)M >> 6)) {
    Put(12, T);
    Write((unsigned)J >> 4 & 15, 4);
    Printsymbol(',');
    Write(J & 15, 2);
    goto L1;
  }
  K = *Shortinteger(S);
  S += 2;
  Hex(K);
  if ((unsigned)M >> 6 == 1) {
    Put(8, T);
    Write((unsigned)J >> 4 & 15, 4);
    Printsymbol(',');
    Write(K & 0xFFF, 4);
    Printsymbol('(');
    Write(J & 15, 2);
    Printsymbol(',');
  L3:
    Write((unsigned)K >> 12 & 15, 2);
    Printsymbol(')');
    goto L1;
  }
  if ((M & 0xF8) == 0x88) {
    Put(8, T);
    Write((unsigned)J >> 4 & 15, 4);
    Printsymbol(',');
  L2:
    Write(K & 0xFFF, 4);
    Printsymbol('(');
    goto L3;
  }
  if (M > 192) {
    L = *Shortinteger(S);
    S += 2;
    Hex(L);
    Put(4, T);
    Write(K & 0xFFF, 5);
    Printsymbol('(');
    if (((unsigned)M >> 4 & 15) != 15)
      Write((J & 255) + 1, 2);
    else
      Write((unsigned)J >> 4 & 15, 2);
    Printsymbol(',');
    Write((unsigned)K >> 12 & 15, 2);
    Printsymbol(')');
    Printsymbol(',');
    Write(L & 0xFFF, 4);
    Printsymbol('(');
    if (((unsigned)M >> 4 & 15) == 15) {
      Write(J & 15, 2);
      Printsymbol(',');
    }
    Write((unsigned)L >> 12 & 15, 2);
    Printsymbol(')');
    goto L1;
  }
  if (M == 134 || M == 135 || M == 144 || M == 152) {
    Put(8, T);
    Write((unsigned)J >> 4 & 15, 4);
    Printsymbol(',');
    Write(J & 15, 2);
    Printsymbol(',');
    goto L2;
  }
  Put(8, T);
  Write(K & 0xFFF, 5);
  Printsymbol('(');
  Write((unsigned)K >> 12 & 15, 2);
  Printsymbol(')');
  Printsymbol(',');
  Write(J & 255, 2);
  goto L1;
  void Hex(int N) {
    static const unsigned char Xsym[16 /*0:15*/] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    int J;
    int S;
    for (J = 0; J < 4; J++) {
      S = (unsigned)N >> 12;
      N = N << 4;
      Printsymbol(Xsym[S&15]);
    }
  }
  void Put(int Sp, int Syms) {
    Spaces(Sp);
#ifdef NEVER
    Sp = 4;
    Printstring(*String(Addr(Sp) + 3));
#else
    int i;
    for (i = 24; i >= 0; i -= 8) {
      if ((Syms>>i)&255) Printsymbol((Syms>>i)&255);
    }
#endif
  }
}
