/*
 *   Copyright (C) 1985, 1991 by the University of Waterloo,
 *   Computer Systems Group. All rights reserved. No part
 *   of this software may be reproduced in any form or by
 *   any means - graphic, electronic or mechanical,
 *   including photocopying, recording, taping or
 *   information storage and retrieval systems - except
 *   with the written permission of the copyright owner.
 */

/*
 * dasm370 -- disassemble a 370 instruction
 */

#include <opcodes.h>
#include <stdlib.h>
#include <string.h>
#include <vopcodes.h>

#define MAX_INS_LENGTH  34
#define stchar( chr )   (*dst++ = (chr))

/* instruction formats (note that IFM_xxx values are used as indices */
/*  into the trans and opclen tables;  therefore, modifications to */
/*  the following list may require modifications to those tables... */

typedef enum
  {
    IFM_UNDEF,
    IFM_RR1,    IFM_RR,     IFM_RRF,
    IFM_RR2,    IFM_RRBC,   IFM_RRSVC,
    IFM_RRE1,   IFM_RRE0,   IFM_RRE,    IFM_E,
    IFM_RX,     IFM_RXF,    IFM_RX2,    IFM_RXBC,
    IFM_RS1,    IFM_RS,     IFM_RSM,    IFM_RRX,
    IFM_S1,     IFM_SI,     IFM_S0,     IFM_S,
    IFM_SS,     IFM_SS2,    IFM_SSI,    IFM_SSR,
    IFM_SSE,
    IFM_QST,
    IFM_QV,     IFM_QV2,
    IFM_VR,     IFM_VR1,    IFM_VR2,
    IFM_VS,
    IFM_VST,    IFM_VST2,
    IFM_VV,     IFM_VV1,    IFM_VV2,
    IFM_RSE
  } inst_format;

typedef struct
  {
    int  oi_notes;
    char oi_format;
    char oi_mnemonic[ 5 ];
  } op_info;

/* values for oi_notes... */
#define OIN_ESA 0x00000001      /* 370/ESA */
#define OIN_PR  0x00000002      /* privileged */
#define OIN_XA  0x00000004      /* 370/XA */
#define OIN_BAS 0x00000008      /* branch and save */
#define OIN_CSS 0x00000010      /* channel-set switching */
#define OIN_CS  0x00000020      /* condition swapping */
#define OIN_TCC 0x00000040      /* CPU timer and clock comparator */
#define OIN_DC  0x00000080      /* direct control */
#define OIN_DAS 0x00000100      /* dual address space */
#define OIN_EF  0x00000200      /* extended facility */
#define OIN_EPF 0x00000400      /* extended-precision floating point */
#define OIN_MI  0x00000800      /* move inverse */
#define OIN_MP  0x00001000      /* multiprocessing */
#define OIN_PKH 0x00002000      /* PSW-key handling */
#define OIN_SKI 0x00004000      /* storage-key-instruction extensions */
#define OIN_SR  0x00008000      /* suspend and resume */
#define OIN_TB  0x00010000      /* test block */
#define OIN_TR  0x00020000      /* translation */
#define OIN_VEC 0x00040000      /* vector */

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_r1      : 4;
    unsigned oc_r2      : 4;
  } opcode_rr;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_num     : 8;
  } opcode_rrsvc;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned            : 8;
    unsigned oc_r1      : 4;
    unsigned oc_r2      : 4;
  } opcode_rre;

typedef struct
  {
    unsigned oc_op16    : 16;
  } opcode_e;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_r1      : 4;
    unsigned oc_x2      : 4;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_rx;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_r1      : 4;
    unsigned oc_r2      : 4;
    unsigned oc_x       : 16;
  } opcode_rrx;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_r1      : 4;
    unsigned oc_r3      : 4;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_rs;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_i2      : 8;
    unsigned oc_b1      : 4;
    unsigned oc_d1      : 12;
  } opcode_si;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_s;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_l       : 8;
    unsigned oc_b1      : 4;
    unsigned oc_d1      : 12;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_ss1;

typedef struct
  {
    unsigned oc_op      : 8;
    unsigned oc_l1      : 4;
    unsigned oc_l2      : 4;
    unsigned oc_b1      : 4;
    unsigned oc_d1      : 12;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_ss2;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_b1      : 4;
    unsigned oc_d1      : 12;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_sse;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_qr3     : 4;
    unsigned oc_rt2     : 4;
    unsigned oc_vr1     : 4;
    unsigned oc_rs2     : 4;
  } opcode_qst;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_qr3     : 4;
    unsigned            : 4;
    unsigned oc_vr1     : 4;
    unsigned oc_vr2     : 4;
  } opcode_qv;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_qr3     : 4;
    unsigned            : 4;
    unsigned oc_vr1     : 4;
    unsigned oc_gr2     : 4;
  } opcode_vr;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned            : 12;
    unsigned oc_rs2     : 4;
  } opcode_vs;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_vr3     : 4;
    unsigned oc_rt2     : 4;
    unsigned oc_vr1     : 4;
    unsigned oc_rs2     : 4;
  } opcode_vst;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_vr3     : 4;
    unsigned            : 4;
    unsigned oc_vr1     : 4;
    unsigned oc_vr2     : 4;
  } opcode_vv;

typedef struct
  {
    unsigned oc_op16    : 16;
    unsigned oc_r3      : 4;
    unsigned            : 4;
    unsigned oc_vr1     : 4;
    unsigned            : 4;
    unsigned oc_b2      : 4;
    unsigned oc_d2      : 12;
  } opcode_rse;

static int tranrre1( char *dst, const opcode_rre *addr, int rchr );
static int tranrre0( char *dst, const opcode_rre *addr, int rchr );
static int tranrre( char *dst, const opcode_rre *addr, int rchr );
static int trane( char *dst, const opcode_e *addr, int rchr );
static int tranrr1( char *dst, const opcode_rr *addr, int rchr );
static int tranrr( char *dst, const opcode_rr *addr, int rchr );
static int tranrrf( char *dst, const opcode_rr *addr, int rchr );
static int tranrr2( char *dst, const opcode_rr *addr, int rchr );
static int tranrrbc( char *dst, const opcode_rr *addr, int rchr );
static int tranrrsvc( char *dst, const opcode_rrsvc *addr, int rchr );
static int tranrx( char *dst, const opcode_rx *addr, int rchr );
static int tranrxf( char *dst, const opcode_rx *addr, int rchr );
static int tranrx2( char *dst, const opcode_rx *addr, int rchr );
static int tranrxbc( char *dst, const opcode_rx *addr, int rchr );
static int tranrs1( char *dst, const opcode_rs *addr, int rchr );
static int tranrrx( char *dst, const opcode_rrx *addr, int rchr );
static int tranrs( char *dst, const opcode_rs *addr, int rchr );
static int tranrsm( char *dst, const opcode_rs *addr, int rchr );
static int trans1( char *dst, const opcode_s *addr, int rchr );
static int transi( char *dst, const opcode_si *addr, int rchr );
static int trans( char *dst, const opcode_s *addr, int rchr );
static int transs( char *dst, const opcode_ss1 *addr, int rchr );
static int transs2( char *dst, const opcode_ss2 *addr, int rchr );
static int transsi( char *dst, const opcode_ss2 *addr, int rchr );
static int transsr( char *dst, const opcode_ss2 *addr, int rchr );
static int transse( char *dst, const opcode_sse *addr, int rchr );
static int tranqst( char *dst, const opcode_qst *addr, int rchr );
static int tranqv( char *dst, const opcode_qv *addr, int rchr );
static int tranqv2( char *dst, const opcode_qv *addr, int rchr );
static int tranvr( char *dst, const opcode_vr *addr, int rchr );
static int tranvr1( char *dst, const opcode_vr *addr, int rchr );
static int tranvr2( char *dst, const opcode_vr *addr, int rchr );
static int tranvs( char *dst, const opcode_vs *addr, int rchr );
static int tranvst( char *dst, const opcode_vst *addr, int rchr );
static int tranvst2( char *dst, const opcode_vst *addr, int rchr );
static int tranvv( char *dst, const opcode_vv *addr, int rchr );
static int tranvv1( char *dst, const opcode_vv *addr, int rchr );
static int tranvv2( char *dst, const opcode_vv *addr, int rchr );
static int tranrse( char *dst, const opcode_rse *addr, int rchr );
static char *setdlb( char *dst, unsigned int disp, unsigned int lenm1,
    unsigned int base, int rchr );
static char *setdrb( char *dst, unsigned int disp, unsigned int reg,
    unsigned int base, int rchr );
static char *setdb( char *dst, unsigned int disp, unsigned int base,
    int rchr );
static char *setgreg( char *dst, int reg, int rchr );
static char *setfreg( char *dst, int freg, int rchr );

static const op_info opi[] =
  {
    { 0,                IFM_UNDEF,      "     " }, /* 0x00 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x01 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x02 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x03 */
    { 0,                IFM_RR1,        "SPM  " }, /* 0x04 */
    { 0,                IFM_RR,         "BALR " }, /* 0x05 */
    { 0,                IFM_RR,         "BCTR " }, /* 0x06 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x07 */
    { OIN_PR,           IFM_RR,         "SSK  " }, /* 0x08 */
    { 0,                IFM_RR,         "ISK  " }, /* 0x09 */
    { 0,                IFM_RRSVC,      "SVC  " }, /* 0x0a */
    { OIN_XA,           IFM_RR,         "BSM  " }, /* 0x0b */
    { OIN_XA,           IFM_RR,         "BASSM" }, /* 0x0c */
    { OIN_BAS,          IFM_RR,         "BASR " }, /* 0x0d */
    { 0,                IFM_RR,         "MVCL " }, /* 0x0e */
    { 0,                IFM_RR,         "CLCL " }, /* 0x0f */
    { 0,                IFM_RR,         "LPR  " }, /* 0x10 */
    { 0,                IFM_RR,         "LNR  " }, /* 0x11 */
    { 0,                IFM_RR,         "LTR  " }, /* 0x12 */
    { 0,                IFM_RR,         "LCR  " }, /* 0x13 */
    { 0,                IFM_RR,         "NR   " }, /* 0x14 */
    { 0,                IFM_RR,         "CLR  " }, /* 0x15 */
    { 0,                IFM_RR,         "OR   " }, /* 0x16 */
    { 0,                IFM_RR,         "XR   " }, /* 0x17 */
    { 0,                IFM_RR,         "LR   " }, /* 0x18 */
    { 0,                IFM_RR,         "CR   " }, /* 0x19 */
    { 0,                IFM_RR,         "AR   " }, /* 0x1a */
    { 0,                IFM_RR,         "SR   " }, /* 0x1b */
    { 0,                IFM_RR,         "MR   " }, /* 0x1c */
    { 0,                IFM_RR,         "DR   " }, /* 0x1d */
    { 0,                IFM_RR,         "ALR  " }, /* 0x1e */
    { 0,                IFM_RR,         "SLR  " }, /* 0x1f */
    { 0,                IFM_RRF,        "LPDR " }, /* 0x20 */
    { 0,                IFM_RRF,        "LNDR " }, /* 0x21 */
    { 0,                IFM_RRF,        "LTDR " }, /* 0x22 */
    { 0,                IFM_RRF,        "LCDR " }, /* 0x23 */
    { 0,                IFM_RRF,        "HDR  " }, /* 0x24 */
    { OIN_EPF,          IFM_RRF,        "LRDR " }, /* 0x25 */
    { OIN_EPF,          IFM_RRF,        "MXR  " }, /* 0x26 */
    { OIN_EPF,          IFM_RRF,        "MXDR " }, /* 0x27 */
    { 0,                IFM_RRF,        "LDR  " }, /* 0x28 */
    { 0,                IFM_RRF,        "CDR  " }, /* 0x29 */
    { 0,                IFM_RRF,        "ADR  " }, /* 0x2a */
    { 0,                IFM_RRF,        "SDR  " }, /* 0x2b */
    { 0,                IFM_RRF,        "MDR  " }, /* 0x2c */
    { 0,                IFM_RRF,        "DDR  " }, /* 0x2d */
    { 0,                IFM_RRF,        "AWR  " }, /* 0x2e */
    { 0,                IFM_RRF,        "SWR  " }, /* 0x2f */
    { 0,                IFM_RRF,        "LPER " }, /* 0x30 */
    { 0,                IFM_RRF,        "LNER " }, /* 0x31 */
    { 0,                IFM_RRF,        "LTER " }, /* 0x32 */
    { 0,                IFM_RRF,        "LCER " }, /* 0x33 */
    { 0,                IFM_RRF,        "HER  " }, /* 0x34 */
    { OIN_EPF,          IFM_RRF,        "LRER " }, /* 0x35 */
    { OIN_EPF,          IFM_RRF,        "AXR  " }, /* 0x36 */
    { OIN_EPF,          IFM_RRF,        "SXR  " }, /* 0x37 */
    { 0,                IFM_RRF,        "LER  " }, /* 0x38 */
    { 0,                IFM_RRF,        "CER  " }, /* 0x39 */
    { 0,                IFM_RRF,        "AER  " }, /* 0x3a */
    { 0,                IFM_RRF,        "SER  " }, /* 0x3b */
    { 0,                IFM_RRF,        "MER  " }, /* 0x3c */
    { 0,                IFM_RRF,        "DER  " }, /* 0x3d */
    { 0,                IFM_RRF,        "AUR  " }, /* 0x3e */
    { 0,                IFM_RRF,        "SUR  " }, /* 0x3f */
    { 0,                IFM_RX,         "STH  " }, /* 0x40 */
    { 0,                IFM_RX,         "LA   " }, /* 0x41 */
    { 0,                IFM_RX,         "STC  " }, /* 0x42 */
    { 0,                IFM_RX,         "IC   " }, /* 0x43 */
    { 0,                IFM_RX,         "EX   " }, /* 0x44 */
    { 0,                IFM_RX,         "BAL  " }, /* 0x45 */
    { 0,                IFM_RX,         "BCT  " }, /* 0x46 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x47 */
    { 0,                IFM_RX,         "LH   " }, /* 0x48 */
    { 0,                IFM_RX,         "CH   " }, /* 0x49 */
    { 0,                IFM_RX,         "AH   " }, /* 0x4a */
    { 0,                IFM_RX,         "SH   " }, /* 0x4b */
    { 0,                IFM_RX,         "MH   " }, /* 0x4c */
    { OIN_BAS,          IFM_RX,         "BAS  " }, /* 0x4d */
    { 0,                IFM_RX,         "CVD  " }, /* 0x4e */
    { 0,                IFM_RX,         "CVB  " }, /* 0x4f */
    { 0,                IFM_RX,         "ST   " }, /* 0x50 */
    { OIN_ESA,          IFM_RX,         "LAE  " }, /* 0x51 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x52 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x53 */
    { 0,                IFM_RX,         "N    " }, /* 0x54 */
    { 0,                IFM_RX,         "CL   " }, /* 0x55 */
    { 0,                IFM_RX,         "O    " }, /* 0x56 */
    { 0,                IFM_RX,         "X    " }, /* 0x57 */
    { 0,                IFM_RX,         "L    " }, /* 0x58 */
    { 0,                IFM_RX,         "C    " }, /* 0x59 */
    { 0,                IFM_RX,         "A    " }, /* 0x5a */
    { 0,                IFM_RX,         "S    " }, /* 0x5b */
    { 0,                IFM_RX,         "M    " }, /* 0x5c */
    { 0,                IFM_RX,         "D    " }, /* 0x5d */
    { 0,                IFM_RX,         "AL   " }, /* 0x5e */
    { 0,                IFM_RX,         "SL   " }, /* 0x5f */
    { 0,                IFM_RXF,        "STD  " }, /* 0x60 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x61 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x62 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x63 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x64 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x65 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x66 */
    { OIN_EPF,          IFM_RXF,        "MXD  " }, /* 0x67 */
    { 0,                IFM_RXF,        "LD   " }, /* 0x68 */
    { 0,                IFM_RXF,        "CD   " }, /* 0x69 */
    { 0,                IFM_RXF,        "AD   " }, /* 0x6a */
    { 0,                IFM_RXF,        "SD   " }, /* 0x6b */
    { 0,                IFM_RXF,        "MD   " }, /* 0x6c */
    { 0,                IFM_RXF,        "DD   " }, /* 0x6d */
    { 0,                IFM_RXF,        "AW   " }, /* 0x6e */
    { 0,                IFM_RXF,        "SW   " }, /* 0x6f */
    { 0,                IFM_RXF,        "STE  " }, /* 0x70 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x71 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x72 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x73 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x74 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x75 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x76 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x77 */
    { 0,                IFM_RXF,        "LE   " }, /* 0x78 */
    { 0,                IFM_RXF,        "CE   " }, /* 0x79 */
    { 0,                IFM_RXF,        "AE   " }, /* 0x7a */
    { 0,                IFM_RXF,        "SE   " }, /* 0x7b */
    { 0,                IFM_RXF,        "ME   " }, /* 0x7c */
    { 0,                IFM_RXF,        "DE   " }, /* 0x7d */
    { 0,                IFM_RXF,        "AU   " }, /* 0x7e */
    { 0,                IFM_RXF,        "SU   " }, /* 0x7f */
    { OIN_PR,           IFM_S1,         "SSM  " }, /* 0x80 */
    { 0,                IFM_UNDEF,      "     " }, /* 0x81 */
    { OIN_PR,           IFM_S1,         "LPSW " }, /* 0x82 */
    { OIN_PR,           IFM_RRX,        "DIAG " }, /* 0x83 */
    { OIN_PR|OIN_DC,    IFM_SI,         "WRD  " }, /* 0x84 */
    { OIN_PR|OIN_DC,    IFM_SI,         "RDD  " }, /* 0x85 */
    { 0,                IFM_RS,         "BXH  " }, /* 0x86 */
    { 0,                IFM_RS,         "BXLE " }, /* 0x87 */
    { 0,                IFM_RS1,        "SRL  " }, /* 0x88 */
    { 0,                IFM_RS1,        "SLL  " }, /* 0x89 */
    { 0,                IFM_RS1,        "SRA  " }, /* 0x8a */
    { 0,                IFM_RS1,        "SLA  " }, /* 0x8b */
    { 0,                IFM_RS1,        "SRDL " }, /* 0x8c */
    { 0,                IFM_RS1,        "SLDL " }, /* 0x8d */
    { 0,                IFM_RS1,        "SRDA " }, /* 0x8e */
    { 0,                IFM_RS1,        "SLDA " }, /* 0x8f */
    { 0,                IFM_RS,         "STM  " }, /* 0x90 */
    { 0,                IFM_SI,         "TM   " }, /* 0x91 */
    { 0,                IFM_SI,         "MVI  " }, /* 0x92 */
    { 0,                IFM_S1,         "TS   " }, /* 0x93 */
    { 0,                IFM_SI,         "NI   " }, /* 0x94 */
    { 0,                IFM_SI,         "CLI  " }, /* 0x95 */
    { 0,                IFM_SI,         "OI   " }, /* 0x96 */
    { 0,                IFM_SI,         "XI   " }, /* 0x97 */
    { 0,                IFM_RS,         "LM   " }, /* 0x98 */
    { OIN_XA,           IFM_RS,         "TRACE" }, /* 0x99 */
    { OIN_ESA,          IFM_RS,         "LAM  " }, /* 0x9a */
    { OIN_ESA,          IFM_RS,         "STAM " }, /* 0x9b */
    { 0,                IFM_UNDEF,      "     " }, /* 0x9c */
    { 0,                IFM_UNDEF,      "     " }, /* 0x9d */
    { 0,                IFM_UNDEF,      "     " }, /* 0x9e */
    { 0,                IFM_UNDEF,      "     " }, /* 0x9f */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa0 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa1 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa2 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa3 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa4 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa5 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa7 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa8 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa9 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xaa */
    { 0,                IFM_UNDEF,      "     " }, /* 0xab */
    { OIN_PR|OIN_TR,    IFM_SI,         "STNSM" }, /* 0xac */
    { OIN_PR|OIN_TR,    IFM_SI,         "STOSM" }, /* 0xad */
    { OIN_PR|OIN_MP,    IFM_RS,         "SIGP " }, /* 0xae */
    { 0,                IFM_SI,         "MC   " }, /* 0xaf */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb0 */
    { OIN_PR|OIN_TR,    IFM_RX,         "LRA  " }, /* 0xb1 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb2 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb3 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb4 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb5 */
    { OIN_PR,           IFM_RS,         "STCTL" }, /* 0xb6 */
    { OIN_PR,           IFM_RS,         "LCTL " }, /* 0xb7 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb8 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb9 */
    { OIN_CS,           IFM_RS,         "CS   " }, /* 0xba */
    { OIN_CS,           IFM_RS,         "CDS  " }, /* 0xbb */
    { 0,                IFM_UNDEF,      "     " }, /* 0xbc */
    { 0,                IFM_RSM,        "CLM  " }, /* 0xbd */
    { 0,                IFM_RSM,        "STCM " }, /* 0xbe */
    { 0,                IFM_RSM,        "ICM  " }, /* 0xbf */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc0 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc1 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc2 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc3 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc4 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc5 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc7 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc8 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xc9 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xca */
    { 0,                IFM_UNDEF,      "     " }, /* 0xcb */
    { 0,                IFM_UNDEF,      "     " }, /* 0xcc */
    { 0,                IFM_UNDEF,      "     " }, /* 0xcd */
    { 0,                IFM_UNDEF,      "     " }, /* 0xce */
    { 0,                IFM_UNDEF,      "     " }, /* 0xcf */
    { 0,                IFM_UNDEF,      "     " }, /* 0xd0 */
    { 0,                IFM_SS,         "MVN  " }, /* 0xd1 */
    { 0,                IFM_SS,         "MVC  " }, /* 0xd2 */
    { 0,                IFM_SS,         "MVZ  " }, /* 0xd3 */
    { 0,                IFM_SS,         "NC   " }, /* 0xd4 */
    { 0,                IFM_SS,         "CLC  " }, /* 0xd5 */
    { 0,                IFM_SS,         "OC   " }, /* 0xd6 */
    { 0,                IFM_SS,         "XC   " }, /* 0xd7 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xd8 */
    { OIN_DAS,          IFM_SSR,        "MVCK " }, /* 0xd9 */
    { OIN_DAS,          IFM_SSR,        "MVCP " }, /* 0xda */
    { OIN_DAS,          IFM_SSR,        "MVCS " }, /* 0xdb */
    { 0,                IFM_SS,         "TR   " }, /* 0xdc */
    { 0,                IFM_SS,         "TRT  " }, /* 0xdd */
    { 0,                IFM_SS,         "ED   " }, /* 0xde */
    { 0,                IFM_SS,         "EDMK " }, /* 0xdf */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe0 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe1 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe2 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe3 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe4 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe5 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe7 */
    { OIN_MI,           IFM_SS,         "MVCIN" }, /* 0xe8 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe9 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xea */
    { 0,                IFM_UNDEF,      "     " }, /* 0xeb */
    { 0,                IFM_UNDEF,      "     " }, /* 0xec */
    { 0,                IFM_UNDEF,      "     " }, /* 0xed */
    { 0,                IFM_UNDEF,      "     " }, /* 0xee */
    { 0,                IFM_UNDEF,      "     " }, /* 0xef */
    { 0,                IFM_SSI,        "SRP  " }, /* 0xf0 */
    { 0,                IFM_SS2,        "MVO  " }, /* 0xf1 */
    { 0,                IFM_SS2,        "PACK " }, /* 0xf2 */
    { 0,                IFM_SS2,        "UNPK " }, /* 0xf3 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xf4 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xf5 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xf6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xf7 */
    { 0,                IFM_SS2,        "ZAP  " }, /* 0xf8 */
    { 0,                IFM_SS2,        "CP   " }, /* 0xf9 */
    { 0,                IFM_SS2,        "AP   " }, /* 0xfa */
    { 0,                IFM_SS2,        "SP   " }, /* 0xfb */
    { 0,                IFM_SS2,        "MP   " }, /* 0xfc */
    { 0,                IFM_SS2,        "DP   " }, /* 0xfd */
    { 0,                IFM_UNDEF,      "     " }, /* 0xfe */
    { 0,                IFM_UNDEF,      "     " }  /* 0xff */
  };

static const op_info e01opi[] =
  {
    { 0,                IFM_UNDEF,      "     " }, /* 0x0100 */
    { OIN_ESA,          IFM_E,          "PR   " }, /* 0x0101 */
    { 0,                IFM_E,          "UPT  " }  /* 0x0102 */
  };

#define LAST_EXT_01     (OP_UPT & 0xff)

static const op_info bcri[] =
  {
    { 0,                IFM_RR2,        "NOPR " }, /* 0x070r */
    { 0,                IFM_RR2,        "BOR  " }, /* 0x071r */
    { 0,                IFM_RR2,        "BPR  " }, /* 0x072r */
    { 0,                IFM_RRBC,       "BCR  " }, /* 0x073r */
    { 0,                IFM_RR2,        "BMR  " }, /* 0x074r */
    { 0,                IFM_RRBC,       "BCR  " }, /* 0x075r */
    { 0,                IFM_RRBC,       "BCR  " }, /* 0x076r */
    { 0,                IFM_RR2,        "BNZR " }, /* 0x077r */
    { 0,                IFM_RR2,        "BZR  " }, /* 0x078r */
    { 0,                IFM_RRBC,       "BCR  " }, /* 0x079r */
    { 0,                IFM_RRBC,       "BCR  " }, /* 0x07ar */
    { 0,                IFM_RR2,        "BNMR " }, /* 0x07br */
    { 0,                IFM_RRBC,       "BCR  " }, /* 0x07cr */
    { 0,                IFM_RR2,        "BNPR " }, /* 0x07dr */
    { 0,                IFM_RR2,        "BNOR " }, /* 0x07er */
    { 0,                IFM_RR2,        "BR   " }  /* 0x07fr */
  };

static const op_info bci[] =
  {
    { 0,                IFM_RX2,        "NOP  " }, /* 0x470x */
    { 0,                IFM_RX2,        "BO   " }, /* 0x471x */
    { 0,                IFM_RX2,        "BP   " }, /* 0x472x */
    { 0,                IFM_RXBC,       "BC   " }, /* 0x473x */
    { 0,                IFM_RX2,        "BM   " }, /* 0x474x */
    { 0,                IFM_RXBC,       "BC   " }, /* 0x475x */
    { 0,                IFM_RXBC,       "BC   " }, /* 0x476x */
    { 0,                IFM_RX2,        "BNZ  " }, /* 0x477x */
    { 0,                IFM_RX2,        "BZ   " }, /* 0x478x */
    { 0,                IFM_RXBC,       "BC   " }, /* 0x479x */
    { 0,                IFM_RXBC,       "BC   " }, /* 0x47ax */
    { 0,                IFM_RX2,        "BNM  " }, /* 0x47bx */
    { 0,                IFM_RXBC,       "BC   " }, /* 0x47cx */
    { 0,                IFM_RX2,        "BNP  " }, /* 0x47dx */
    { 0,                IFM_RX2,        "BNO  " }, /* 0x47ex */
    { 0,                IFM_RX2,        "B    " }  /* 0x47fx */
  };

static const op_info e9copi[] =
  {
    { OIN_PR,           IFM_S,          "SIO  " }, /* 0x9c00 */
    { OIN_PR,           IFM_S,          "SIOF " }, /* 0x9c01 */
    { OIN_PR|OIN_SR,    IFM_S,          "RIO  " }  /* 0x9c02 */
  };

#define LAST_EXT_9C     (OP_RIO & 0xff)

static const op_info e9dopi[] =
  {
    { OIN_PR,           IFM_S,          "TIO  " }, /* 0x9d00 */
    { OIN_PR,           IFM_S,          "CLRIO" }  /* 0x9d01 */
  };

#define LAST_EXT_9D     (OP_CLRIO & 0xff)

static const op_info e9eopi[] =
  {
    { OIN_PR,           IFM_S,          "HIO  " }, /* 0x9e00 */
    { OIN_PR,           IFM_S,          "HDV  " }  /* 0x9e01 */
  };

#define LAST_EXT_9E     (OP_HDV & 0xff)

static const op_info e9fopi[] =
  {
    { OIN_PR,           IFM_S,          "TCH  " }, /* 0x9f00 */
    { OIN_PR,           IFM_S,          "CLRCH" }  /* 0x9f01 */
  };

#define LAST_EXT_9F     (OP_CLRCH & 0xff)

static const op_info ea4opi[] =
  {
    { OIN_VEC,          IFM_VST2,       "VAE  " }, /* 0xa400 */
    { OIN_VEC,          IFM_VST2,       "VSE  " }, /* 0xa401 */
    { OIN_VEC,          IFM_VST2,       "VME  " }, /* 0xa402 */
    { OIN_VEC,          IFM_VST2,       "VDE  " }, /* 0xa403 */
    { OIN_VEC,          IFM_VST2,       "VMAE " }, /* 0xa404 */
    { OIN_VEC,          IFM_VST2,       "VMSE " }, /* 0xa405 */
    { OIN_VEC,          IFM_VST2,       "VMCE " }, /* 0xa406 */
    { OIN_VEC,          IFM_VST,        "VACE " }, /* 0xa407 */
    { OIN_VEC,          IFM_VST2,       "VCE  " }, /* 0xa408 */
    { OIN_VEC,          IFM_VST,        "VL   " }, /* 0xa409 */
    { OIN_VEC,          IFM_VST,        "VLM  " }, /* 0xa40a */
    { OIN_VEC,          IFM_VST,        "VLY  " }, /* 0xa40b */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa40c */
    { OIN_VEC,          IFM_VST,        "VST  " }, /* 0xa40d */
    { OIN_VEC,          IFM_VST,        "VSTM " }, /* 0xa40e */
    { OIN_VEC,          IFM_VST,        "VSTK " }, /* 0xa40f */
    { OIN_VEC,          IFM_VST2,       "VAD  " }, /* 0xa410 */
    { OIN_VEC,          IFM_VST2,       "VSD  " }, /* 0xa411 */
    { OIN_VEC,          IFM_VST2,       "VMD  " }, /* 0xa412 */
    { OIN_VEC,          IFM_VST2,       "VDD  " }, /* 0xa413 */
    { OIN_VEC,          IFM_VST2,       "VMAD " }, /* 0xa414 */
    { OIN_VEC,          IFM_VST2,       "VMSD " }, /* 0xa415 */
    { OIN_VEC,          IFM_VST2,       "VMCD " }, /* 0xa416 */
    { OIN_VEC,          IFM_VST,        "VACD " }, /* 0xa417 */
    { OIN_VEC,          IFM_VST2,       "VCD  " }, /* 0xa418 */
    { OIN_VEC,          IFM_VST,        "VLD  " }, /* 0xa419 */
    { OIN_VEC,          IFM_VST,        "VLMD " }, /* 0xa41a */
    { OIN_VEC,          IFM_VST,        "VLYD " }, /* 0xa41b */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa41c */
    { OIN_VEC,          IFM_VST,        "VSTD " }, /* 0xa41d */
    { OIN_VEC,          IFM_VST,        "VSTMD" }, /* 0xa41e */
    { OIN_VEC,          IFM_VST,        "VSTKD" }, /* 0xa41f */
    { OIN_VEC,          IFM_VST2,       "VA   " }, /* 0xa420 */
    { OIN_VEC,          IFM_VST2,       "VS   " }, /* 0xa421 */
    { OIN_VEC,          IFM_VST2,       "VM   " }, /* 0xa422 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa423 */
    { OIN_VEC,          IFM_VST2,       "VN   " }, /* 0xa424 */
    { OIN_VEC,          IFM_VST2,       "VO   " }, /* 0xa425 */
    { OIN_VEC,          IFM_VST2,       "VX   " }, /* 0xa426 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa427 */
    { OIN_VEC,          IFM_VST2,       "VC   " }, /* 0xa428 */
    { OIN_VEC,          IFM_VST,        "VLH  " }, /* 0xa429 */
    { OIN_VEC,          IFM_VST,        "VLINT" }, /* 0xa42a */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa42b */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa42c */
    { OIN_VEC,          IFM_VST,        "VSTH " }, /* 0xa42d */
  };

#define LAST_EXT_A4     (OP_VSTH & 0xff)

static const op_info ea48opi[] =
  {
    { OIN_VEC,          IFM_QST,        "VAES " }, /* 0xa480 */
    { OIN_VEC,          IFM_QST,        "VSES " }, /* 0xa481 */
    { OIN_VEC,          IFM_QST,        "VMES " }, /* 0xa482 */
    { OIN_VEC,          IFM_QST,        "VDES " }, /* 0xa483 */
    { OIN_VEC,          IFM_QST,        "VMAES" }, /* 0xa484 */
    { OIN_VEC,          IFM_QST,        "VMSES" }, /* 0xa485 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa486 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa487 */
    { OIN_VEC,          IFM_QST,        "VCES " }, /* 0xa488 */
  };

#define LAST_EXT_A48    (OP_VCES & 0xff)

static const op_info ea49opi[] =
  {
    { OIN_VEC,          IFM_QST,        "VADS " }, /* 0xa490 */
    { OIN_VEC,          IFM_QST,        "VSDS " }, /* 0xa491 */
    { OIN_VEC,          IFM_QST,        "VMDS " }, /* 0xa492 */
    { OIN_VEC,          IFM_QST,        "VDDS " }, /* 0xa493 */
    { OIN_VEC,          IFM_QST,        "VMADS" }, /* 0xa494 */
    { OIN_VEC,          IFM_QST,        "VMSDS" }, /* 0xa495 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa496 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa497 */
    { OIN_VEC,          IFM_QST,        "VCDS " }, /* 0xa498 */
  };

#define LAST_EXT_A49    (OP_VCDS & 0xff)

static const op_info ea4aopi[] =
  {
    { OIN_VEC,          IFM_QST,        "VAS  " }, /* 0xa4a0 */
    { OIN_VEC,          IFM_QST,        "VSS  " }, /* 0xa4a1 */
    { OIN_VEC,          IFM_QST,        "VMS  " }, /* 0xa4a2 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa4a3 */
    { OIN_VEC,          IFM_QST,        "VNS  " }, /* 0xa4a4 */
    { OIN_VEC,          IFM_QST,        "VOS  " }, /* 0xa4a5 */
    { OIN_VEC,          IFM_QST,        "VXS  " }, /* 0xa4a6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa4a7 */
    { OIN_VEC,          IFM_QST,        "VCS  " }, /* 0xa4a8 */
  };

#define LAST_EXT_A4A    (OP_VCS & 0xff)

static const op_info ea50opi[] =
  {
    { OIN_VEC,          IFM_VV,         "VAER " }, /* 0xa500 */
    { OIN_VEC,          IFM_VV,         "VSER " }, /* 0xa501 */
    { OIN_VEC,          IFM_VV,         "VMER " }, /* 0xa502 */
    { OIN_VEC,          IFM_VV,         "VDER " }, /* 0xa503 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa504 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa505 */
    { OIN_VEC,          IFM_VV,         "VMCER" }, /* 0xa506 */
    { OIN_VEC,          IFM_VV2,        "VACER" }, /* 0xa507 */
    { OIN_VEC,          IFM_VV,         "VCER " }, /* 0xa508 */
    { OIN_VEC,          IFM_VV2,        "VLR  " }, /* 0xa509 */
    { OIN_VEC,          IFM_VV2,        "VLMR " }, /* 0xa50a */
    { OIN_VEC,          IFM_VV1,        "VLZR " }, /* 0xa50b */
  };

#define LAST_EXT_A50    (OP_VLZR & 0xff)

static const op_info ea51opi[] =
  {
    { OIN_VEC,          IFM_VV,         "VADR " }, /* 0xa510 */
    { OIN_VEC,          IFM_VV,         "VSDR " }, /* 0xa511 */
    { OIN_VEC,          IFM_VV,         "VMDR " }, /* 0xa512 */
    { OIN_VEC,          IFM_VV,         "VDDR " }, /* 0xa513 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa514 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa515 */
    { OIN_VEC,          IFM_VV,         "VMCDR" }, /* 0xa516 */
    { OIN_VEC,          IFM_VV2,        "VACDR" }, /* 0xa517 */
    { OIN_VEC,          IFM_VV,         "VCDR " }, /* 0xa518 */
    { OIN_VEC,          IFM_VV2,        "VLDR " }, /* 0xa519 */
    { OIN_VEC,          IFM_VV2,        "VLMDR" }, /* 0xa51a */
    { OIN_VEC,          IFM_VV1,        "VLZDR" }, /* 0xa51b */
  };

#define LAST_EXT_A51    (OP_VLZDR & 0xff)

static const op_info ea52opi[] =
  {
    { OIN_VEC,          IFM_VV,         "VAR  " }, /* 0xa520 */
    { OIN_VEC,          IFM_VV,         "VSR  " }, /* 0xa521 */
    { OIN_VEC,          IFM_VV,         "VMR  " }, /* 0xa522 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa523 */
    { OIN_VEC,          IFM_VV,         "VNR  " }, /* 0xa524 */
    { OIN_VEC,          IFM_VV,         "VOR  " }, /* 0xa525 */
    { OIN_VEC,          IFM_VV,         "VXR  " }, /* 0xa526 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa527 */
    { OIN_VEC,          IFM_VV,         "VCR  " }, /* 0xa528 */
  };

#define LAST_EXT_A52    (OP_VCR & 0xff)

static const op_info ea54opi[] =
  {
    { OIN_VEC,          IFM_VV2,        "VLPER" }, /* 0xa540 */
    { OIN_VEC,          IFM_VV2,        "VLNER" }, /* 0xa541 */
    { OIN_VEC,          IFM_VV2,        "VLCER" }, /* 0xa542 */
  };

#define LAST_EXT_A54    (OP_VLCER & 0xff)

static const op_info ea55opi[] =
  {
    { OIN_VEC,          IFM_VV2,        "VLPDR" }, /* 0xa550 */
    { OIN_VEC,          IFM_VV2,        "VLNDR" }, /* 0xa551 */
    { OIN_VEC,          IFM_VV2,        "VLCDR" }, /* 0xa552 */
  };

#define LAST_EXT_A55    (OP_VLCDR & 0xff)

static const op_info ea56opi[] =
  {
    { OIN_VEC,          IFM_VV2,        "VLPR " }, /* 0xa560 */
    { OIN_VEC,          IFM_VV2,        "VLNR " }, /* 0xa561 */
    { OIN_VEC,          IFM_VV2,        "VLCR " }, /* 0xa562 */
  };

#define LAST_EXT_A56    (OP_VLCR & 0xff)

static const op_info ea58opi[] =
  {
    { OIN_VEC,          IFM_QV,         "VAEQ " }, /* 0xa580 */
    { OIN_VEC,          IFM_QV,         "VSEQ " }, /* 0xa581 */
    { OIN_VEC,          IFM_QV,         "VMEQ " }, /* 0xa582 */
    { OIN_VEC,          IFM_QV,         "VDEQ " }, /* 0xa583 */
    { OIN_VEC,          IFM_QV,         "VMAEQ" }, /* 0xa584 */
    { OIN_VEC,          IFM_QV,         "VMSEQ" }, /* 0xa585 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa586 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa587 */
    { OIN_VEC,          IFM_QV,         "VCEQ " }, /* 0xa588 */
    { OIN_VEC,          IFM_QV2,        "VLEQ " }, /* 0xa589 */
    { OIN_VEC,          IFM_QV2,        "VLMEQ" }, /* 0xa58a */
  };

#define LAST_EXT_A58    (OP_VLMEQ & 0xff)

static const op_info ea59opi[] =
  {
    { OIN_VEC,          IFM_QV,         "VADQ " }, /* 0xa590 */
    { OIN_VEC,          IFM_QV,         "VSDQ " }, /* 0xa591 */
    { OIN_VEC,          IFM_QV,         "VMDQ " }, /* 0xa592 */
    { OIN_VEC,          IFM_QV,         "VDDQ " }, /* 0xa593 */
    { OIN_VEC,          IFM_QV,         "VMADQ" }, /* 0xa594 */
    { OIN_VEC,          IFM_QV,         "VMSDQ" }, /* 0xa595 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa596 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa597 */
    { OIN_VEC,          IFM_QV,         "VCDQ " }, /* 0xa598 */
    { OIN_VEC,          IFM_QV2,        "VLDQ " }, /* 0xa599 */
    { OIN_VEC,          IFM_QV2,        "VLMDQ" }, /* 0xa59a */
  };

#define LAST_EXT_A59    (OP_VLMDQ & 0xff)

static const op_info ea5aopi[] =
  {
    { OIN_VEC,          IFM_QV,         "VAQ  " }, /* 0xa5a0 */
    { OIN_VEC,          IFM_QV,         "VSQ  " }, /* 0xa5a1 */
    { OIN_VEC,          IFM_QV,         "VMQ  " }, /* 0xa5a2 */
    { OIN_VEC,          IFM_QV,         "VNQ  " }, /* 0xa5a4 */
    { OIN_VEC,          IFM_QV,         "VOQ  " }, /* 0xa5a5 */
    { OIN_VEC,          IFM_QV,         "VXQ  " }, /* 0xa5a6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa5a7 */
    { OIN_VEC,          IFM_QV,         "VCQ  " }, /* 0xa5a8 */
    { OIN_VEC,          IFM_QV2,        "VLQ  " }, /* 0xa5a9 */
    { OIN_VEC,          IFM_QV2,        "VLMQ " }, /* 0xa5aa */
  };

#define LAST_EXT_A5A    (OP_VLMQ & 0xff)

static const op_info ea60opi[] =
  {
    { OIN_VEC,          IFM_VR,         "VMXSE" }, /* 0xa600 */
    { OIN_VEC,          IFM_VR,         "VMNSE" }, /* 0xa601 */
    { OIN_VEC,          IFM_VR,         "VMXAE" }, /* 0xa602 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa603 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa604 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa605 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa606 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa607 */
    { OIN_VEC,          IFM_VR,         "VLELE" }, /* 0xa608 */
    { OIN_VEC,          IFM_VR,         "VXELE" }, /* 0xa609 */
  };

#define LAST_EXT_A60    (OP_VXELE & 0xff)

static const op_info ea61opi[] =
  {
    { OIN_VEC,          IFM_VR,         "VMXSD" }, /* 0xa610 */
    { OIN_VEC,          IFM_VR,         "VMNSD" }, /* 0xa611 */
    { OIN_VEC,          IFM_VR,         "VMXAD" }, /* 0xa612 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa613 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa614 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa615 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa616 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa617 */
    { OIN_VEC,          IFM_VR,         "VLELD" }, /* 0xa618 */
    { OIN_VEC,          IFM_VR,         "VXELD" }, /* 0xa619 */
    { OIN_VEC,          IFM_VR2,        "VSPSD" }, /* 0xa61a */
    { OIN_VEC,          IFM_VR1,        "VZPSD" }, /* 0xa61b */
  };

#define LAST_EXT_A61    (OP_VZPSD & 0xff)
#define FIRST_EXT_A62   (OP_VLEL & 0xff)

static const op_info ea62opi[] =
  {
    { OIN_VEC,          IFM_VR,         "VLEL " }, /* 0xa628 */
    { OIN_VEC,          IFM_VR,         "VXEL " }, /* 0xa629 */
  };

#define LAST_EXT_A62    (OP_VXEL & 0xff)

static const op_info ea64opi[] =
  {
    { OIN_VEC,          IFM_RRE0,       "VTVM " }, /* 0xa640 */
    { OIN_VEC,          IFM_RRE0,       "VCVM " }, /* 0xa641 */
    { OIN_VEC,          IFM_RRE1,       "VCZVM" }, /* 0xa642 */
    { OIN_VEC,          IFM_RRE1,       "VCOVM" }, /* 0xa643 */
    { OIN_VEC,          IFM_RRE1,       "VXVC " }, /* 0xa644 */
    { OIN_VEC,          IFM_RRE1,       "VLVCU" }, /* 0xa645 */
    { OIN_VEC,          IFM_RRE1,       "VXVMM" }, /* 0xa646 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa647 */
    { OIN_VEC,          IFM_RRE1,       "VRRS " }, /* 0xa648 */
    { OIN_VEC,          IFM_RRE1,       "VRSVC" }, /* 0xa649 */
    { OIN_VEC,          IFM_RRE1,       "VRSV " }, /* 0xa64a */
  };

#define LAST_EXT_A64    (OP_VRSV & 0xff)

static const op_info ea68opi[] =
  {
    { OIN_VEC,          IFM_VS,         "VLVM " }, /* 0xa680 */
    { OIN_VEC,          IFM_VS,         "VLCVM" }, /* 0xa681 */
    { OIN_VEC,          IFM_VS,         "VSTVM" }, /* 0xa682 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa683 */
    { OIN_VEC,          IFM_VS,         "VNVM " }, /* 0xa684 */
    { OIN_VEC,          IFM_VS,         "VOVM " }, /* 0xa685 */
    { OIN_VEC,          IFM_VS,         "VXVM " }, /* 0xa686 */
  };

#define LAST_EXT_A68    (OP_VXVM & 0xff)

static const op_info ea6copi[] =
  {
    { OIN_VEC,          IFM_S,          "VSRSV" }, /* 0xa6c0 */
    { OIN_VEC,          IFM_S,          "VMRSV" }, /* 0xa6c1 */
    { OIN_VEC,          IFM_S,          "VSRRS" }, /* 0xa6c2 */
    { OIN_VEC,          IFM_S,          "VMRRS" }, /* 0xa6c3 */
    { OIN_VEC,          IFM_S,          "VLVCA" }, /* 0xa6c4 */
    { OIN_VEC,          IFM_S,          "VRCL " }, /* 0xa6c5 */
    { OIN_VEC,          IFM_S,          "VSVMM" }, /* 0xa6c6 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa6c7 */
    { OIN_VEC,          IFM_S,          "VSTVP" }, /* 0xa6c8 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xa6c9 */
    { OIN_VEC,          IFM_S,          "VACSV" }, /* 0xa6ca */
    { OIN_VEC,          IFM_S,          "VACRS" }, /* 0xa6cb */
  };

#define LAST_EXT_A6C    (OP_VACRS & 0xff)

static const op_info eb2opi[] =
  {
    { OIN_PR|OIN_CSS,   IFM_S,          "CONCS" }, /* 0xb200 */
    { OIN_PR|OIN_CSS,   IFM_S,          "DISCS" }, /* 0xb201 */
    { OIN_PR,           IFM_S,          "STIDP" }, /* 0xb202 */
    { OIN_PR,           IFM_S,          "STIDC" }, /* 0xb203 */
    { OIN_PR,           IFM_S,          "SCK  " }, /* 0xb204 */
    { 0,                IFM_S,          "STCK " }, /* 0xb205 */
    { OIN_PR|OIN_TCC,   IFM_S,          "SCKC " }, /* 0xb206 */
    { OIN_PR|OIN_TCC,   IFM_S,          "STCKC" }, /* 0xb207 */
    { OIN_PR|OIN_TCC,   IFM_S,          "SPT  " }, /* 0xb208 */
    { OIN_PR|OIN_TCC,   IFM_S,          "STPT " }, /* 0xb209 */
    { OIN_PKH,          IFM_S,          "SPKA " }, /* 0xb20a */
    { OIN_PKH,          IFM_S0,         "IPK  " }, /* 0xb20b */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb20c */
    { OIN_PR|OIN_TR,    IFM_S0,         "PTLB " }, /* 0xb20d */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb20e */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb20f */
    { OIN_PR|OIN_MP,    IFM_S,          "SPX  " }, /* 0xb210 */
    { OIN_PR|OIN_MP,    IFM_S,          "STPX " }, /* 0xb211 */
    { OIN_PR|OIN_MP,    IFM_S,          "STAP " }, /* 0xb212 */
    { OIN_PR|OIN_TR,    IFM_S,          "RRB  " }, /* 0xb213 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb214 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb215 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb216 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb217 */
    { OIN_DAS,          IFM_S,          "PC   " }, /* 0xb218 */
    { OIN_DAS,          IFM_S,          "SAC  " }, /* 0xb219 */
    { 0,                IFM_S,          "CFC  " }, /* 0xb21a */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb21b */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb21c */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb21d */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb21e */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb21f */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb220 */
    { OIN_PR|OIN_EF,    IFM_RRE,        "IPTE " }, /* 0xb221 */
    { OIN_XA,           IFM_RRE1,       "IPM  " }, /* 0xb222 */
    { OIN_DAS,          IFM_RRE,        "IVSK " }, /* 0xb223 */
    { OIN_DAS,          IFM_RRE1,       "IAC  " }, /* 0xb224 */
    { OIN_DAS,          IFM_RRE1,       "SSAR " }, /* 0xb225 */
    { OIN_DAS,          IFM_RRE1,       "EPAR " }, /* 0xb226 */
    { OIN_DAS,          IFM_RRE1,       "ESAR " }, /* 0xb227 */
    { OIN_DAS,          IFM_RRE,        "PT   " }, /* 0xb228 */
    { OIN_SKI,          IFM_RRE,        "ISKE " }, /* 0xb229 */
    { OIN_PR|OIN_SKI,   IFM_RRE,        "RRBE " }, /* 0xb22a */
    { OIN_PR|OIN_SKI,   IFM_RRE,        "SSKE " }, /* 0xb22b */
    { OIN_PR|OIN_TB,    IFM_RRE,        "TB   " }, /* 0xb22c */
    { OIN_XA,           IFM_RRE,        "DXR  " }, /* 0xb22d */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb22e */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb22f */
    { OIN_XA,           IFM_S,          "CSCH " }, /* 0xb230 */
    { OIN_XA,           IFM_S,          "HSCH " }, /* 0xb231 */
    { OIN_XA,           IFM_S,          "MSCH " }, /* 0xb232 */
    { OIN_XA,           IFM_S,          "SSCH " }, /* 0xb233 */
    { OIN_XA,           IFM_S,          "STSCH" }, /* 0xb234 */
    { OIN_XA,           IFM_S,          "TSCH " }, /* 0xb235 */
    { OIN_XA,           IFM_S,          "TPI  " }, /* 0xb236 */
    { OIN_XA,           IFM_S,          "SAL  " }, /* 0xb237 */
    { OIN_XA,           IFM_S,          "RSCH " }, /* 0xb238 */
    { OIN_XA,           IFM_S,          "STCRW" }, /* 0xb239 */
    { OIN_XA,           IFM_S,          "STCPS" }, /* 0xb23a */
    { OIN_XA,           IFM_S,          "RCHP " }, /* 0xb23b */
    { OIN_XA,           IFM_S,          "SCHM " }, /* 0xb23c */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb23d */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb23e */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb23f */
    { OIN_ESA,          IFM_RRE,        "BAKR " }, /* 0xb240 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb241 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb242 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb243 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb244 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xb245 */
    { OIN_ESA|OIN_PR,   IFM_RRE,        "STURA" }, /* 0xb246 */
    { OIN_ESA,          IFM_RRE1,       "MSTA " }, /* 0xb247 */
    { OIN_ESA|OIN_PR,   IFM_RRE0,       "PALB " }, /* 0xb248 */
    { OIN_ESA,          IFM_RRE,        "EREG " }, /* 0xb249 */
    { OIN_ESA,          IFM_RRE,        "ESTA " }, /* 0xb24a */
    { OIN_ESA|OIN_PR,   IFM_RRE,        "LURA " }, /* 0xb24b */
    { OIN_ESA,          IFM_RRE,        "TAR  " }, /* 0xb24c */
    { OIN_ESA,          IFM_RRE,        "CPYA " }, /* 0xb24d */
    { OIN_ESA,          IFM_RRE,        "SAR  " }, /* 0xb24e */
    { OIN_ESA,          IFM_RRE,        "EAR  " }  /* 0xb24f */
  };

#define LAST_EXT_B2     (OP_EAR & 0xff)

static const op_info ee40opi[] =
  {
    { OIN_VEC,          IFM_RSE,        "VLI  " }, /* 0xe400 */
    { OIN_VEC,          IFM_RSE,        "VSTI " }, /* 0xe401 */
  };

#define LAST_EXT_E40    (OP_VSTI & 0xff)

static const op_info ee41opi[] =
  {
    { OIN_VEC,          IFM_RSE,        "VLID " }, /* 0xe410 */
    { OIN_VEC,          IFM_RSE,        "VSTID" }, /* 0xe411 */
  };

#define LAST_EXT_E41    (OP_VSTID & 0xff)
#define FIRST_EXT_E42   (OP_VSRL & 0xff)

static const op_info ee42opi[] =
  {
    { OIN_VEC,          IFM_RSE,        "VSRL " }, /* 0xe424 */
    { OIN_VEC,          IFM_RSE,        "VSLL " }, /* 0xe425 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe426 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe427 */
    { OIN_VEC,          IFM_RSE,        "VLBIX" }, /* 0xe428 */
  };

#define LAST_EXT_E42    (OP_VLBIX & 0xff)

static const op_info ee5opi[] =
  {
    { OIN_PR|OIN_DAS,   IFM_SSE,        "LASP " }, /* 0xe500 */
    { OIN_PR|OIN_EF,    IFM_SSE,        "TPROT" }, /* 0xe501 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe502 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe503 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe504 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe505 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe506 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe507 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe508 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe509 */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe50a */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe50b */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe50c */
    { 0,                IFM_UNDEF,      "     " }, /* 0xe50d */
    { OIN_ESA|OIN_PR,   IFM_SSE,        "MVCSK" }, /* 0xe50e */
    { OIN_ESA|OIN_PR,   IFM_SSE,        "MVCDK" }  /* 0xe50f */
  };

#define LAST_EXT_E5     (OP_MVCDK & 0xff)

static int ((* const (tran[]))()) =
  {
    NULL,
    tranrr1,    tranrr,     tranrrf,
    tranrr2,    tranrrbc,   tranrrsvc,
    tranrre1,   tranrre0,   tranrre,    trane,
    tranrx,     tranrxf,    tranrx2,    tranrxbc,
    tranrs1,    tranrs,     tranrsm,    tranrrx,
    trans1,     transi,     NULL,       trans,
    transs,     transs2,    transsi,    transsr,
    transse,
    tranqst,
    tranqv,     tranqv2,
    tranvr,     tranvr1,    tranvr2,
    tranvs,
    tranvst,    tranvst2,
    tranvv,     tranvv1,    tranvv2,
    tranrse
  };

static const char opclen[] =
  {
    0,  /* UNUSED */
    1,  /* RR1  */
    1,  /* RR   */
    1,  /* RRF  */
    1,  /* RR2  */
    1,  /* RRBC */
    1,  /* RRSVC */
    2,  /* RRE1 */
    2,  /* RRE0 */
    2,  /* RRE  */
    1,  /* E    */
    2,  /* RX   */
    2,  /* RXF  */
    2,  /* RX2  */
    2,  /* RXBC */
    2,  /* RS1  */
    2,  /* RS   */
    2,  /* RSM  */
    2,  /* RRX  */
    2,  /* S1   */
    2,  /* SI   */
    2,  /* S0   */
    2,  /* S    */
    3,  /* SS   */
    3,  /* SS2  */
    3,  /* SSI  */
    3,  /* SSR  */
    3,  /* SSE  */
    2,  /* QST  */
    2,  /* QV   */
    2,  /* QV2  */
    2,  /* VR   */
    2,  /* VR1  */
    2,  /* VR2  */
    2,  /* VS   */
    2,  /* VST  */
    2,  /* VST2 */
    2,  /* VV   */
    2,  /* VV1  */
    2,  /* VV2  */
    3   /* RSE  */
  };


/*
 * dasm370 -- disassemble a 370 instruction at src into the buffer dst;
 *            if( dasmopts & 0x80000000 ) is non-zero, then register
 *            prefixes (F and R) are generated for register operands;
 *            some opcodes can be suppressed by setting the appropriate
 *            bit in dasmopts;  the address of the next instruction is
 *            returned if the instruction at src could be disassembled,
 *            otherwise, src is returned;  dst is assumed to be of
 *            sufficient length to contain the longest possible
 *            instruction (MAX_INS_LENGTH)
 *              DC    X'D9ADBFFECFFF'
 *              (1+strlen( "MVCK  4094(R10,R11),4095(R12),R13" )) == 34
 *
 * Example:
 *   char *dst; short int *src;
 *
 *   src = 0xb1 12 30 04
 *   a) dasm370( src, dst, 0 )
 *       upon completion, dst = "", and src is returned
 *   b) dasm370( src, dst, -1 )
 *       upon completion, dst = "LRA   R1,4(R3,R2)";  src+2 is returned
 *   c) dasm370( src, dst, OIN_PR )    ...suppress privileged instr's
 *       upon completion, dst = "", and src is returned
 *   d) dasm370( src, dst, 0x80000000 )
 *       upon completion, dst = "LRA   1,4(3,2)";  src+2 is returned
 */

unsigned short int *dasm370( const unsigned short int *src,
                             char       *dst,
                             int        dasmopts )
  {
    char        *srcc;
    op_info     *opinfoptr;
    unsigned int opformat, extop;
    size_t      inslen;
    int         ((*rtn)());

    /* put the '\0' in first, so we won't have to do it later... */
    memzero( dst, MAX_INS_LENGTH );
    srcc = (char *) src;
    opinfoptr = &opi[ *srcc ];
    if( opinfoptr->oi_format == IFM_UNDEF )
      {
        extop = srcc[ 1 ];
        opinfoptr = &opi[ 0 ];
        switch( *srcc )
          {
            case 0x01:
                if( extop <= LAST_EXT_01 )
                    opinfoptr = &e01opi[ extop ];
                break;
            case (OP_BCR >> 8):
                opinfoptr = &bcri[ extop >> 4 ];
                break;
            case (OP_BC >> 8):
                opinfoptr = &bci[ extop >> 4 ];
                break;
            case 0x9c:
                if( extop <= LAST_EXT_9C )
                    opinfoptr = &e9copi[ extop ];
                break;
            case 0x9d:
                if( extop <= LAST_EXT_9D )
                    opinfoptr = &e9dopi[ extop ];
                break;
            case 0x9e:
                if( extop <= LAST_EXT_9E )
                    opinfoptr = &e9eopi[ extop ];
                break;
            case 0x9f:
                if( extop <= LAST_EXT_9F )
                    opinfoptr = &e9fopi[ extop ];
                break;
            case 0xa4:
                if( extop <= LAST_EXT_A4 )
                    opinfoptr = &ea4opi[ extop ];
                else if( ( extop >= 0x80 ) &&
                         ( extop <= LAST_EXT_A48 ) )
                    opinfoptr = &ea48opi[ extop & 0x0f ];
                else if( ( extop >= 0x90 ) &&
                         ( extop <= LAST_EXT_A49 ) )
                    opinfoptr = &ea49opi[ extop & 0x0f ];
                else if( ( extop >= 0xa0 ) &&
                         ( extop <= LAST_EXT_A4A ) )
                    opinfoptr = &ea4aopi[ extop & 0x0f ];
                break;
            case 0xa5:
                switch( extop >> 4 )
                  {
                    case 0:
                        if( extop <= LAST_EXT_A50 )
                            opinfoptr = &ea50opi[ extop & 0x0f ];
                        break;
                    case 1:
                        if( extop <= LAST_EXT_A51 )
                            opinfoptr = &ea51opi[ extop & 0x0f ];
                        break;
                    case 2:
                        if( extop <= LAST_EXT_A52 )
                            opinfoptr = &ea52opi[ extop & 0x0f];
                        break;
                    case 4:
                        if( extop <= LAST_EXT_A54 )
                            opinfoptr = &ea54opi[ extop & 0x0f ];
                        break;
                    case 5:
                        if( extop <= LAST_EXT_A55 )
                            opinfoptr = &ea55opi[ extop & 0x0f ];
                        break;
                    case 6:
                        if( extop <= LAST_EXT_A56 )
                            opinfoptr = &ea56opi[ extop & 0x0f ];
                        break;
                    case 8:
                        if( extop <= LAST_EXT_A58 )
                            opinfoptr = &ea58opi[ extop & 0x0f ];
                        break;
                    case 9:
                        if( extop <= LAST_EXT_A59 )
                            opinfoptr = &ea59opi[ extop & 0x0f ];
                        break;
                    case 0xa:
                        if( extop <= LAST_EXT_A5A )
                            opinfoptr = &ea5aopi[ extop & 0x0f ];
                        break;
                  }
                break;
            case 0xa6:
                switch( extop >> 4 )
                  {
                    case 0:
                        if( extop <= LAST_EXT_A60 )
                            opinfoptr = &ea60opi[ extop & 0x0f ];
                        break;
                    case 1:
                        if( extop <= LAST_EXT_A61 )
                            opinfoptr = &ea61opi[ extop & 0x0f ];
                        break;
                    case 2:
                        if( ( extop >= FIRST_EXT_A62 ) &&
                            ( extop <= LAST_EXT_A62 ) )
                            opinfoptr =
                                &ea62opi[(extop - FIRST_EXT_A62) & 0x0f];
                        break;
                    case 4:
                        if( extop <= LAST_EXT_A64 )
                            opinfoptr = &ea64opi[ extop & 0x0f ];
                        break;
                    case 8:
                        if( extop <= LAST_EXT_A68 )
                            opinfoptr = &ea68opi[ extop & 0x0f ];
                        break;
                    case 0xc:
                        if( extop <= LAST_EXT_A6C )
                            opinfoptr = &ea6copi[ extop & 0x0f ];
                        break;
                  }
                break;
            case 0xb2:
                if( extop <= LAST_EXT_B2 )
                    opinfoptr = &eb2opi[ extop ];
                break;
            case 0xe4:
                switch( extop >> 4 )
                  {
                    case 0:
                        if( extop <= LAST_EXT_E40 )
                            opinfoptr = &ee40opi[ extop & 0x0f ];
                        break;
                    case 1:
                        if( extop <= LAST_EXT_E41 )
                            opinfoptr = &ee41opi[ extop & 0x0f ];
                        break;
                    case 2:
                        if( ( extop >= FIRST_EXT_E42 ) &&
                            ( extop <= LAST_EXT_E42 ) )
                            opinfoptr =
                                &ee42opi[(extop - FIRST_EXT_E42) & 0x0f];
                        break;
                  }
                break;
            case 0xe5:
                if( extop <= LAST_EXT_E5 )
                    opinfoptr = &ee5opi[ extop ];
                break;
          }
      }
    if( (opinfoptr->oi_notes) & dasmopts )
        opinfoptr = &opi[ 0 ];
    opformat = opinfoptr->oi_format;
    if( opformat == IFM_UNDEF )
        return( src );
    inslen = opclen[ opformat ];
    memcpy( dst, opinfoptr->oi_mnemonic, 5 );
    rtn = tran[ opformat ];
    if( rtn == NULL )
        strrtrm( dst );
    else
      {
        dst += 5;
        stchar( ' ' );
        if( ((*rtn)( dst, src, dasmopts & 0x80000000 )) == 0 )
          {
            dst -= 6;
            *dst = '\0';
            inslen = 0;
          }
      }
    return( src + inslen );
  }


static int tranrre1( char *dst,
                     const opcode_rre *addr,
                     int rchr )
  {
    setgreg( dst, addr->oc_r1, rchr );
    return( 1 );
  }

static int tranrre0( char *dst,
                     const opcode_rre *addr,
                     int rchr )
  {
    /* no operands */
    return( 1 );
  }

static int tranrre( char *dst,
                    const opcode_rre *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    setgreg( dst, addr->oc_r2, rchr );
    return( 1 );
  }

static int trane( char *dst,
                  const opcode_e *addr,
                  int rchr )
  {
    return( 1 );
  }

static int tranrr1( char *dst,
                    const opcode_rr *addr,
                    int rchr )
  {
    setgreg( dst, addr->oc_r1, rchr );
    return( 1 );
  }

static int tranrr( char *dst,
                   const opcode_rr *addr,
                   int rchr )
  {
    /* reject odd-valued R1 with MR, DR, MVCL, CLCL operations... */
    if( ( (addr->oc_r1 & 1) != 0 ) &&
        ( ( addr->oc_op == (OP_MR >> 8) ) ||
          ( addr->oc_op == (OP_DR >> 8) ) ||
          ( addr->oc_op == (OP_MVCL >> 8) ) ||
          ( addr->oc_op == (OP_CLCL >> 8) ) ) )
        return( 0 );
    /* reject odd-valued R2 with MVCL, CLCL operations... */
    if( ( (addr->oc_r2 & 1) != 0 ) &&
        ( ( addr->oc_op == (OP_MVCL >> 8) ) ||
          ( addr->oc_op == (OP_CLCL >> 8) ) ) )
        return( 0 );
    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    setgreg( dst, addr->oc_r2, rchr );
    return( 1 );
  }

static int tranrrf( char *dst,
                    const opcode_rr *addr,
                    int rchr )
  {
    if( ( (addr->oc_r1 & 1) != 0 ) ||
        ( (addr->oc_r1) >= 8 ) ||
        ( (addr->oc_r2 & 1) != 0 ) ||
        ( (addr->oc_r2) >= 8 ) )
        return( 0 );
    if( ( addr->oc_r1 != 0 ) &&
        ( addr->oc_r1 != 4 ) &&
        ( ( addr->oc_op == (OP_AXR >> 8) ) ||
          ( addr->oc_op == (OP_SXR >> 8) ) ||
          ( addr->oc_op == (OP_MXDR >> 8) ) ||
          ( addr->oc_op == (OP_MXR >> 8) ) ) )
        return( 0 );
    if( ( addr->oc_r2 != 0 ) &&
        ( addr->oc_r2 != 4 ) &&
        ( ( addr->oc_op == (OP_AXR >> 8) ) ||
          ( addr->oc_op == (OP_LRDR >> 8) ) ||
          ( addr->oc_op == (OP_MXR >> 8) ) ) )
        return( 0 );
    dst = setfreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    setfreg( dst, addr->oc_r2, rchr );
    return( 1 );
  }

static int tranrr2( char *dst,
                    const opcode_rr *addr,
                    int rchr )
  {
    setgreg( dst, addr->oc_r2, rchr );
    return( 1 );
  }

static int tranrrbc( char *dst,
                     const opcode_rr *addr,
                     int rchr )
  {
    dst = itos( dst, addr->oc_r1 );
    stchar( ',' );
    setgreg( dst, addr->oc_r2, rchr );
    return( 1 );
  }

static int tranrrsvc( char *dst,
                      const opcode_rrsvc *addr,
                      int rchr )
  {
    itos( dst, addr->oc_num );
    return( 1 );
  }

static int tranrx( char *dst,
                   const opcode_rx *addr,
                   int rchr )
  {
    /* reject odd-valued oc_d2 with BC if oc_x2 and oc_b2 are both 0...*/
    if( ( (addr->oc_d2 & 1) != 0 ) &&
        ( addr->oc_x2 == 0 ) &&
        ( addr->oc_b2 == 0 ) &&
        ( addr->oc_op == (OP_BC >> 8) ) )
        return( 0 );
    /* reject odd-valued R1 with M and D instructions... */
    if( ( (addr->oc_r1 & 1) != 0 ) &&
        ( ( addr->oc_op == (OP_D >> 8) ) ||
          ( addr->oc_op == (OP_M >> 8) ) ) )
        return( 0 );
    /* alignment error for BAL when oc_d2 is odd and oc_x2 is zero... */
    if( ( addr->oc_x2 == 0 ) &&
        ( (addr->oc_d2 & 1) != 0 ) &&
        ( addr->oc_op == (OP_BAL >> 8) ) )
        return( 0 );
    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    setdrb( dst, addr->oc_d2, addr->oc_x2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranrxf( char *dst,
                    const opcode_rx *addr,
                    int rchr )
  {
    if( ( (addr->oc_r1 & 1) != 0 ) ||
        ( addr->oc_r1 >= 8 ) )
        return( 0 );
    if( ( addr->oc_r1 != 0 ) &&
        ( addr->oc_r1 != 4 ) &&
        ( addr->oc_op == (OP_MXD >> 8) ) )
        return( 0 );
    dst = setfreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    setdrb( dst, addr->oc_d2, addr->oc_x2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranrx2( char *dst,
                    const opcode_rx *addr,
                    int rchr )
  {
    /* reject odd-valued oc_d2 with BC if oc_x2 and oc_b2 are both 0...*/
    if( ( (addr->oc_d2 & 1) != 0 ) &&
        ( addr->oc_x2 == 0 ) &&
        ( addr->oc_b2 == 0 ) &&
        ( addr->oc_op == (OP_BC >> 8) ) )
        return( 0 );
    setdrb( dst, addr->oc_d2, addr->oc_x2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranrxbc( char *dst,
                     const opcode_rx *addr,
                     int rchr )
  {
    dst = itos( dst, addr->oc_r1 );
    stchar( ',' );
    setdrb( dst, addr->oc_d2, addr->oc_x2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranrs1( char *dst,
                    const opcode_rs *addr,
                    int rchr )
  {
    /* reject Shift-Double instructions with odd-valued R1... */
    if( ( (addr->oc_r1 & 1) != 0 ) &&
        ( ( addr->oc_op == (OP_SRDA >> 8) ) ||
          ( addr->oc_op == (OP_SRDL >> 8) ) ||
          ( addr->oc_op == (OP_SLDA >> 8) ) ||
          ( addr->oc_op == (OP_SLDL >> 8) ) ) )
        return( 0 );
    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranrrx( char *dst,
                    const opcode_rrx *addr,
                    int rchr )
  {
    char *xcon;

    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_r2, rchr );
    stchar( ',' );
    stchar( 'X' );
    stchar( '\'' );
    xcon = dst;
    dst = itohs( dst, addr->oc_x );
    strupr( xcon );
    stchar( '\'' );
    return( 1 );
  }

static int tranrs( char *dst,
                   const opcode_rs *addr,
                   int rchr )
  {
    if( ( (addr->oc_d2 & 1) != 0 ) &&
        ( addr->oc_b2 == 0 ) &&
        ( ( addr->oc_op == (OP_BXH >> 8) ) ||
          ( addr->oc_op == (OP_BXLE >> 8) ) ) )
        return( 0 );
    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_r3, rchr );
    stchar( ',' );
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranrsm( char *dst,
                    const opcode_rs *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_r1, rchr );
    stchar( ',' );
    dst = itos( dst, addr->oc_r3 );
    stchar( ',' );
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int trans1( char *dst,
                   const opcode_s *addr,
                   int rchr )
  {
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int transi( char *dst,
                   const opcode_si *addr,
                   int rchr )
  {
    dst = setdb( dst, addr->oc_d1, addr->oc_b1, rchr );
    stchar( ',' );
    itos( dst, addr->oc_i2 );
    return( 1 );
  }

static int trans( char *dst,
                  const opcode_s *addr,
                  int rchr )
  {
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int transs( char *dst,
                   const opcode_ss1 *addr,
                   int rchr )
  {
    dst = setdlb( dst, addr->oc_d1, addr->oc_l, addr->oc_b1, rchr );
    stchar( ',' );
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int transs2( char *dst,
                    const opcode_ss2 *addr,
                    int rchr )
  {
    dst = setdlb( dst, addr->oc_d1, addr->oc_l1, addr->oc_b1, rchr );
    stchar( ',' );
    setdlb( dst, addr->oc_d2, addr->oc_l2, addr->oc_b2, rchr );
    return( 1 );
  }

static int transsi( char *dst,
                    const opcode_ss2 *addr,
                    int rchr )
  {
    if( ( addr->oc_op == (OP_SRP >> 8) ) &&
        ( addr->oc_l2 > 9 ) )
        return( 0 );
    dst = setdlb( dst, addr->oc_d1, addr->oc_l1, addr->oc_b1, rchr );
    stchar( ',' );
    dst = setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    stchar( ',' );
    itos( dst, addr->oc_l2 );
    return( 1 );
  }

static int transsr( char *dst,
                    const opcode_ss2 *addr,
                    int rchr )
  {
    dst = setdrb( dst, addr->oc_d1, addr->oc_l1, addr->oc_b1, rchr );
    stchar( ',' );
    dst = setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    stchar( ',' );
    setgreg( dst, addr->oc_l2, rchr );
    return( 1 );
  }

static int transse( char *dst,
                    const opcode_sse *addr,
                    int rchr )
  {
    dst = setdb( dst, addr->oc_d1, addr->oc_b1, rchr );
    stchar( ',' );
    setdb( dst, addr->oc_d2, addr->oc_b2, rchr );
    return( 1 );
  }

static int tranqst( char *dst,
                    const opcode_qst *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_qr3, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_rs2, rchr );
    stchar( '(' );
    dst = setgreg( dst, addr->oc_rt2, rchr );
    stchar( ')' );
    return( 1 );                /* dst == "VR1,FR3,RS2(RT2)" */
  }

static int tranqv( char *dst,
                   const opcode_qv *addr,
                   int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_qr3, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_vr2, rchr );
    return( 1 );                /* dst == "VR1,FR3,VR2" */
  }

static int tranqv2( char *dst,
                    const opcode_qv *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_vr2, rchr );
    return( 1 );                /* dst == "VR1,FR2" */
  }

static int tranvr( char *dst,
                   const opcode_vr *addr,
                   int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_qr3, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_gr2, rchr );
    return( 1 );                /* dst == "VR1,FR3,GR2" */
  }

static int tranvr1( char *dst,
                    const opcode_vr *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    return( 1 );                /* dst == "VR1" */
  }

static int tranvr2( char *dst,
                    const opcode_vr *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_gr2, rchr );
    return( 1 );                /* dst == "VR1,GR2" */
  }

static int tranvs( char *dst,
                   const opcode_vs *addr,
                   int rchr )
  {
    setgreg( dst, addr->oc_rs2, rchr );
    return( 1 );                /* dst == "RS2" */
  }

static int tranvst( char *dst,
                    const opcode_vst *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_rs2, rchr );
    stchar( '(' );
    dst = setgreg( dst, addr->oc_rt2, rchr );
    stchar( ')' );
    return( 1 );                /* dst == "VR1,RS2(RT2)" */
  }

static int tranvst2( char *dst,
                     const opcode_vst *addr,
                     int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_vr3, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_rs2, rchr );
    stchar( '(' );
    dst = setgreg( dst, addr->oc_rt2, rchr );
    stchar( ')' );
    return( 1 );                /* dst == "VR1,VR3,RS2(RT2)" */
  }

static int tranvv( char *dst,
                   const opcode_vv *addr,
                   int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_vr2, rchr );
    stchar( ',' );
    setgreg( dst, addr->oc_vr3, rchr );
    return( 1 );                /* dst == "VR1,VR2,VR3" */
  }

static int tranvv1( char *dst,
                    const opcode_vv *addr,
                    int rchr )
  {
    setgreg( dst, addr->oc_vr1, rchr );
    return( 1 );                /* dst == "VR1" */
  }

static int tranvv2( char *dst,
                    const opcode_vv *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    setgreg( dst, addr->oc_vr2, rchr );
    return( 1 );                /* dst == "VR1,VR2" */
  }

static int tranrse( char *dst,
                    const opcode_rse *addr,
                    int rchr )
  {
    dst = setgreg( dst, addr->oc_vr1, rchr );
    stchar( ',' );
    dst = setgreg( dst, addr->oc_r3, rchr );
    stchar( ',' );
    dst = itos( dst, addr->oc_d2 );
    stchar( '(' );
    dst = setgreg( dst, addr->oc_b2, rchr );
    stchar( ')' );
    return( 1 );                /* dst == "VR1,R3,D2(B2)" */
  }

static char *setdlb( char *dst,
                     unsigned int disp,
                     unsigned int lenm1,
                     unsigned int base,
                     int rchr )
  {
    dst = itos( dst, disp );
    stchar( '(' );
    dst = itos( dst, lenm1 + 1 );
    stchar( ',' );
    dst = setgreg( dst, base, rchr );
    stchar( ')' );
    return( dst );                      /* dst == "DISP(LEN+1,BASE)" */
  }

static char *setdrb( char *dst,
                     unsigned int disp,
                     unsigned int reg,
                     unsigned int base,
                     int rchr )
  {
    dst = itos( dst, disp );
    stchar( '(' );
    dst = setgreg( dst, reg, rchr );
    stchar( ',' );
    dst = setgreg( dst, base, rchr );
    stchar( ')' );
    return( dst );                      /* dst == "DISP(REG,BASE)" */
  }

static char *setdb( char *dst,
                    unsigned int disp,
                    unsigned int base,
                    int rchr )
  {
    dst = itos( dst, disp );
    stchar( '(' );
    dst = setgreg( dst, base, rchr );
    stchar( ')' );
    return( dst );                      /* dst == "DISP(BASE)" */
  }

static char *setgreg( char *dst,
                      int  greg,
                      int  rchr )
  {
    if( rchr )
        stchar( 'R' );
    return( itos( dst, greg ) );        /* dst == "Rn", or "n" */
  }

static char *setfreg( char *dst,
                      int  freg,
                      int  rchr )
  {
    if( rchr )
        stchar( 'F' );
    return( itos( dst, freg ) );        /* dst == "Fn", or "n" */
  }