begin ;  !M68000 Disassembler
!HD Feb 1982 - revised May 83 - re-written Aug 1983
!
!!!!!!!!!!!  File and control initialisation  !!!!!!!!!!!!!
!$IF VAX
{%include "DR0:[HMD]PAM.INC"
{%ownstring(127) infile="TT:",
{                outfile="TT:"
!$IF APM
include  "INC:UTIL.IMP"
string (255) parm
ownstring (127) infile="",
                outfile=":"
!$FINISH
!Control parameters:
owninteger  LO=0, HI=999999
ownbyte  BINARY=1, BRIEF=0
!
constinteger  STOREMAX=32767
short integerarray  STORE(0:storemax)
!
routine  DECODE(integer  BASE, integername  FROM, integer  UPTO)
!The array DEF defines the format of M68000 opcodes as pairs
! of 32-bit words: the first word is a packed mnemonic and
! the second is an interpretation code consisting of two 16-bit halves.
! The high-order 16-bits are the fixed part of the op-code.
! The low-order value has flag bits in the most significant 6 bits
! and two 5-bit fields defining the types of up to two operands
! for the op-code.  These fields are used (a) to index the array MASK
! to establish which bits the field corresponds to and (b) to
! control interpretation of the corresponding operand.
! There are some arbitrary choices regarding what is part of the
! fixed op-code and what is variable.
! The area is ordered by op-code group (high-order 4 bits) and
! within each group in accordance with REVERSE search order:
! hence the relative position of eg SUB, SUBX, SUBA.

constinteger  SIZED=1<<15, MSIZED=1<<14, ASIZED=3<<14,
              WLSIZED=1<<13,
              COND=1<<12
constinteger  REG=1, AREG=2,
              AT=3, SREG=4, WLREG=5,
              TQUICK=6,
              EA=7, SEA=8, WLSEA=9,
              MQUICK=10, REL=11,
              IMM=12, XIMM=13, USPSR=14, CCR=15,
              DEA=16,
              REG9=17, AREG9=18, QREG9=19,
              QUICK9=20, AT9=21,
              CEA=22, CREG=23, CREL=24,
              SPOST=25, POST9=26, SPRE=27, PRE9=28,
              ADISP=29, SAREG9=30
!
constshortintegerarray  MASK(0:31) <-
  16_FFFF,
  16_FFF8{REG}, 16_FFF8{AREG},
  16_FFF8{AT}, 16_FF38{SREG}, 16_FFB8{WLREG},
  16_FFF0{TQUICK},
  16_FFC0{EA}, 16_FF00{SEA}, 16_FF80{WLSEA},
  16_FF00{MQUICK}, 16_FF00{REL},
  16_FFFF{IMM}, 16_FFFF{XIMM}, 16_FFFF{USPSR}, 16_FFFF{CCR},
  16_F03F{DEA},
  16_F1FF{REG9}, 16_F1FF{AREG9}, 16_F1DF{QREG9}, 16_F1FF{QUICK9},
  16_F1FF{AT9},
  16_F0C0{CEA}, 16_F0F8{CREG}, 16_F000{CREL},
  16_FF38{SPOST}, 16_F1FF{POST9}, 16_FF38{SPRE}, 16_F1FF{PRE9},
  16_FFB8{ADISP}, 16_F0FF{SAREG9},
  0
constinteger  DEFMAX=110
constbyteintegerarray  LIMIT(0:15) =
  45, 47, 49, 51, 121, 131, 135, 137,
  151, 161, 161, 171, 189, 217, defmax+defmax+1, defmax+defmax+1
constintegerarray  DEF(1:defmax+defmax) = c 
 {BTST}  'b'<<25+('t'&31)<<20+('s'&31)<<15+('t'&31)<<10,
  16_01000000+ reg9<<5+ea,
 {BCHG}  'b'<<25+('c'&31)<<20+('h'&31)<<15+('g'&31)<<10,
  16_01400000+ reg9<<5+ea,
 {BCLR}  'b'<<25+('c'&31)<<20+('l'&31)<<15+('r'&31)<<10,
  16_01800000+ reg9<<5+ea,
 {BSET}  'b'<<25+('s'&31)<<20+('e'&31)<<15+('t'&31)<<10,
  16_01C00000+ reg9<<5+ea,
 {BTST}  'b'<<25+('t'&31)<<20+('s'&31)<<15+('t'&31)<<10,
  16_08000000+ imm<<5+ea,
 {BCHG}  'b'<<25+('c'&31)<<20+('h'&31)<<15+('g'&31)<<10,
  16_08400000+ imm<<5+ea,
 {BCLR}  'b'<<25+('c'&31)<<20+('l'&31)<<15+('r'&31)<<10,
  16_08800000+ imm<<5+ea,
 {BSET}  'b'<<25+('s'&31)<<20+('e'&31)<<15+('t'&31)<<10,
  16_08C00000+ imm<<5+ea,
 {MOVEP}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10+('p'&31)<<5,
  16_01080000+ wlsized+reg9<<5+adisp,
 {MOVEP}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10+('p'&31)<<5,
  16_01880000+ wlsized+adisp<<5+reg9,
 {ORI}  'o'<<25+('r'&31)<<20+('i'&31)<<15,
  16_00000000+ sized+imm<<5+sea,
 {ORI}  'o'<<25+('r'&31)<<20+('i'&31)<<15,
  16_003C0000+ imm<<5+ccr,
 {ORI}  'o'<<25+('r'&31)<<20+('i'&31)<<15,
  16_007C0000+ imm<<5+uspsr,
 {ANDI}  'a'<<25+('n'&31)<<20+('d'&31)<<15+('i'&31)<<10,
  16_02000000+ sized+imm<<5+sea,
 {ANDI TO CCR}  'a'<<25+('n'&31)<<20+('d'&31)<<15+('i'&31)<<10,
  16_023C0000+ imm<<5+ccr,
 {ANDI}  'a'<<25+('n'&31)<<20+('d'&31)<<15+('i'&31)<<10,
  16_027C0000+ imm<<5+uspsr,
 {SUBI}  's'<<25+('u'&31)<<20+('b'&31)<<15+('i'&31)<<10,
  16_04000000+ sized+imm<<5+sea,
 {ADDI}  'a'<<25+('d'&31)<<20+('d'&31)<<15+('i'&31)<<10,
  16_06000000+ sized+imm<<5+sea,
 {EORI}  'e'<<25+('o'&31)<<20+('r'&31)<<15+('i'&31)<<10,
  16_0A000000+ sized+imm<<5+sea,
 {EORI}  'e'<<25+('o'&31)<<20+('r'&31)<<15+('i'&31)<<10,
  16_0A3C0000+ imm<<5+ccr,
 {EORI}  'e'<<25+('o'&31)<<20+('r'&31)<<15+('i'&31)<<10,
  16_0A7C0000+ imm<<5+uspsr,
 {CMPI}  'c'<<25+('m'&31)<<20+('p'&31)<<15+('i'&31)<<10,
  16_0C000000+ sized+imm<<5+sea,
 {MOVEB}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_10000000+ msized+ea<<5+dea,
 {MOVEL}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_20000000+ msized+ea<<5+dea,
 {MOVEW}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_30000000+ msized+ea<<5+dea,
 {NEGX}  'n'<<25+('e'&31)<<20+('g'&31)<<15+('x'&31)<<10,
  16_40000000+ ea,
 {MOVE from SR}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_40C00000+ uspsr<<5+ea,
 {CLR}  'c'<<25+('l'&31)<<20+('r'&31)<<15,
  16_42000000+ sized+sea,
 {NEG}  'n'<<25+('e'&31)<<20+('g'&31)<<15,
  16_44000000+ sized+sea,
 {MOVE to CCR}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_44C00000+ ea<<5+ccr,
 {NOT}  'n'<<25+('o'&31)<<20+('t'&31)<<15,
  16_46000000+ sized+sea,
 {MOVE to SR}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_46C00000+ ea<<5+uspsr,
 {NBCD}  'n'<<25+('b'&31)<<20+('c'&31)<<15+('d'&31)<<10,
  16_48000000+ ea,
 {PEA}  'p'<<25+('e'&31)<<20+('a'&31)<<15,
  16_48400000+ ea,
 {SWAP}  's'<<25+('w'&31)<<20+('a'&31)<<15+('p'&31)<<10,
  16_48400000+ reg,
 {MOVEM} 'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10+('m'&31)<<5,
  16_48800000+ wlsized+ximm<<5+wlsea,
 {MOVEM} 'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10+('m'&31)<<5,
  16_4C800000+ wlsized+wlsea<<5+ximm,
 {EXTW}  'e'<<25+('x'&31)<<20+('t'&31)<<15+('w'&31)<<10,
  16_48800000+ reg,
 {EXTL}  'e'<<25+('x'&31)<<20+('t'&31)<<15+('l'&31)<<10,
  16_48C00000+ reg,
 {TST}  't'<<25+('s'&31)<<20+('t'&31)<<15,
  16_4A000000+ sized+sea,
 {TAS}  't'<<25+('a'&31)<<20+('s'&31)<<15,
  16_4AC00000+ ea,
 {TRAP}  't'<<25+('r'&31)<<20+('a'&31)<<15+('p'&31)<<10,
  16_4E400000+ tquick,
 {LINK}  'l'<<25+('i'&31)<<20+('n'&31)<<15+('k'&31)<<10,
  16_4E500000+ areg<<5+imm,
 {UNLK}  'u'<<25+('n'&31)<<20+('l'&31)<<15+('k'&31)<<10,
  16_4E580000+ areg,
 {MOVE to USP}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_4E600000+ areg<<5+uspsr,
 {MOVE from USP}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10,
  16_4E680000+ uspsr<<5+areg,
 {RESET}  'r'<<25+('e'&31)<<20+('s'&31)<<15+('e'&31)<<10+('t'&31)<<5,
  16_4E700000,
 {NOP}  'n'<<25+('o'&31)<<20+('p'&31)<<15,
  16_4E710000,
 {STOP}  's'<<25+('t'&31)<<20+('o'&31)<<15+('p'&31)<<10,
  16_4E720000 +imm,
 {RTE}  'r'<<25+('t'&31)<<20+('e'&31)<<15,
  16_4E730000,
 {RTS}  'r'<<25+('t'&31)<<20+('s'&31)<<15,
  16_4E750000,
 {TRAPV}  't'<<25+('r'&31)<<20+('a'&31)<<15+('p'&31)<<10+('v'&31)<<5,
  16_4E760000,
 {RTR}  'r'<<25+('t'&31)<<20+('r'&31)<<15,
  16_4E770000,
 {JSR}  'j'<<25+('s'&31)<<20+('r'&31)<<15,
  16_4E800000+ ea,
 {JMP}  'j'<<25+('m'&31)<<20+('p'&31)<<15,
  16_4EC00000+ ea,
 {CHK}  'c'<<25+('h'&31)<<20+('k'&31)<<15,
  16_41800000+ ea<<5+reg9,
 {LEA}  'l'<<25+('e'&31)<<20+('a'&31)<<15,
  16_41C00000+ ea<<5+areg9,
 {ADDQ}  'a'<<25+('d'&31)<<20+('d'&31)<<15+('q'&31)<<10,
  16_50000000+ sized+quick9<<5+sea,
 {SUBQ}  's'<<25+('u'&31)<<20+('b'&31)<<15+('q'&31)<<10,
  16_51000000+ sized+quick9<<5+sea,
 {S}  's'<<25,
  16_50C00000+ cond+cea,
 {DB}  'd'<<25+('b'&31)<<20,
  16_50C80000+ cond+creg<<5+imm,
 {DBRA} 'd'<<25+('b'&31)<<20+('r'&31)<<15+('a'&31)<<10,
  16_51C80000+ reg<<5+imm,
 {B}  'b'<<25,
  16_60000000+ cond+crel,
 {BRA}  'b'<<25+('r'&31)<<20+('a'&31)<<15,
  16_60000000+ rel,
 {MOVEQ}  'm'<<25+('o'&31)<<20+('v'&31)<<15+('e'&31)<<10+('q'&31)<<5,
  16_70000000+ mquick<<5+reg9,
 {OR}  'o'<<25+('r'&31)<<20,
  16_80000000+ sized+sea<<5+reg9,
 {OR}  'o'<<25+('r'&31)<<20,
  16_81000000+ sized+reg9<<5+sea,
 {DIVU}  'd'<<25+('i'&31)<<20+('v'&31)<<15+('u'&31)<<10,
  16_80C00000+ ea<<5+reg9,
 {DIVS}  'd'<<25+('i'&31)<<20+('v'&31)<<15+('s'&31)<<10,
  16_81C00000+ ea<<5+reg9,
 {SBCD}  's'<<25+('b'&31)<<20+('c'&31)<<15+('d'&31)<<10,
  16_81000000+ reg9<<5+reg,
 {SBCD}  's'<<25+('b'&31)<<20+('c'&31)<<15+('d'&31)<<10,
  16_81080000+ spre<<5+pre9,
 {SUB}  's'<<25+('u'&31)<<20+('b'&31)<<15,
  16_90000000+ sized+sea<<5+reg9,
 {SUB}  's'<<25+('u'&31)<<20+('b'&31)<<15,
  16_91000000+ sized+reg9<<5+sea,
 {SUBX}  's'<<25+('u'&31)<<20+('b'&31)<<15+('x'&31)<<10,
  16_91000000+ sized+sreg<<5+reg9,
 {SUBX}  's'<<25+('u'&31)<<20+('b'&31)<<15+('x'&31)<<10,
  16_91080000+ sized+spre<<5+pre9,
 {SUBA}  's'<<25+('u'&31)<<20+('b'&31)<<15+('a'&31)<<10,
  16_90C00000+ asized+ea<<5+sareg9,
 {CMP}  'c'<<25+('m'&31)<<20+('p'&31)<<15,
  16_B0000000+ sized+sea<<5+reg9,
 {EOR}  'e'<<25+('o'&31)<<20+('r'&31)<<15,
  16_B1000000+ sized+reg9<<5+sea,
 {CMPM}  'c'<<25+('m'&31)<<20+('p'&31)<<15+('m'&31)<<10,
  16_B1080000+ sized+spost<<5+post9,
 {CMPA}  'c'<<25+('m'&31)<<20+('p'&31)<<15+('a'&31)<<10,
  16_B0C00000+ asized+ea<<5+sareg9,
 {AND}  'a'<<25+('n'&31)<<20+('d'&31)<<15,
  16_C0000000+ sized+sea<<5+reg9,
 {AND}  'a'<<25+('n'&31)<<20+('d'&31)<<15,
  16_C1000000+ sized+reg9<<5+sea,
 {MULU}  'm'<<25+('u'&31)<<20+('l'&31)<<15+('u'&31)<<10,
  16_C0C00000+ ea<<5+reg9,
 {MULS}  'm'<<25+('u'&31)<<20+('l'&31)<<15+('s'&31)<<10,
  16_C1C00000+ ea<<5+reg9,
 {ABCD}  'a'<<25+('b'&31)<<20+('c'&31)<<15+('d'&31)<<10,
  16_C1000000+ reg<<5+reg9,
 {ABCD}  'a'<<25+('b'&31)<<20+('c'&31)<<15+('d'&31)<<10,
  16_C1080000+ spre<<5+pre9,
 {EXG}  'e'<<25+('x'&31)<<20+('g'&31)<<15,
  16_C1400000+ reg9<<5+reg,
 {EXG}  'e'<<25+('x'&31)<<20+('g'&31)<<15,
  16_C1480000+ areg9<<5+areg,
 {EXG}  'e'<<25+('x'&31)<<20+('g'&31)<<15,
  16_C1880000+ reg9<<5+areg,
 {ADD}  'a'<<25+('d'&31)<<20+('d'&31)<<15,
  16_D0000000+ sized+sea<<5+reg9,
 {ADD}  'a'<<25+('d'&31)<<20+('d'&31)<<15,
  16_D1000000+ sized+reg9<<5+sea,
 {ADDX}  'a'<<25+('d'&31)<<20+('d'&31)<<15+('x'&31)<<10,
  16_D1000000+ sized+sreg<<5+reg9,
 {ADDX}  'a'<<25+('d'&31)<<20+('d'&31)<<15+('x'&31)<<10,
  16_D1080000+ sized+spre<<5+pre9,
 {ADDA}  'a'<<25+('d'&31)<<20+('d'&31)<<15+('a'&31)<<10,
  16_D0C00000+ asized+ea<<5+sareg9,
 {ASR}  'a'<<25+('s'&31)<<20+('r'&31)<<15,
  16_E0000000+ sized+qreg9<<5+sreg,
 {ASL}  'a'<<25+('s'&31)<<20+('l'&31)<<15,
  16_E1000000+ sized+qreg9<<5+sreg,
 {LSR}  'l'<<25+('s'&31)<<20+('r'&31)<<15,
  16_E0080000+ sized+qreg9<<5+sreg,
 {LSL}  'l'<<25+('s'&31)<<20+('l'&31)<<15,
  16_E1080000+ sized+qreg9<<5+sreg,
 {ROXR}  'r'<<25+('o'&31)<<20+('x'&31)<<15+('r'&31)<<10,
  16_E0100000+ sized+qreg9<<5+sreg,
 {ROXL}  'r'<<25+('o'&31)<<20+('x'&31)<<15+('l'&31)<<10,
  16_E1100000+ sized+qreg9<<5+sreg,
 {ROR}  'r'<<25+('o'&31)<<20+('r'&31)<<15,
  16_E0180000+ sized+qreg9<<5+sreg,
 {ROL}  'r'<<25+('o'&31)<<20+('l'&31)<<15,
  16_E1180000+ sized+qreg9<<5+sreg,
 {ASRM}  'a'<<25+('s'&31)<<20+('r'&31)<<15,
  16_E0C00000 +ea,
 {ASLM}  'a'<<25+('s'&31)<<20+('l'&31)<<15,
  16_E1C00000 +ea,
 {LSRM}  'l'<<25+('s'&31)<<20+('r'&31)<<15,
  16_E2C00000 +ea,
 {LSLM}  'l'<<25+('s'&31)<<20+('l'&31)<<15,
  16_E3C00000 +ea,
 {ROXRM}  'r'<<25+('o'&31)<<20+('x'&31)<<15,
  16_E4C00000 +ea,
 {ROXLM}  'r'<<25+('o'&31)<<20+('x'&31)<<15,
  16_E5C00000 +ea,
 {RORM}  'r'<<25+('o'&31)<<20+('r'&31)<<15,
  16_E6C00000 +ea,
 {ROLM}  'r'<<25+('o'&31)<<20+('l'&31)<<15,
  16_E7C00000 +ea

constbyteintegerarray  SSYM(0:3) = 'B','W','L','?'
constshortintegerarray  CPAIR(0:15) = c 
  m'??', m'SR', m'HI', m'LS', m'CC', m'CS', m'NE', m'EQ',
  m'VC', m'VS', m'PL', m'MI', m'GE', m'LT', m'GT', m'LE'

integer  CODE,FORMAT,T1,T2,PCREL,SIZE,REGS,NCODE,P,I,FR
owninteger  BP,OUTCOL
ownbyteintegerarray  BUFF(1:60)
constbyteintegerarray  HEXSYM(0:15) = c 
  '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'

routine  PHEX(integer  val)
integer  i
  print symbol(hexsym(val>>i&15)) for  i = 12,-4,0
end 

routine  PUT SYM(integer  k)
  bp = bp+1;  buff(bp) = k
end 

routine  PUT HEX(integer  val)
integer  i
  put sym(hexsym(val>>i&15)) for  i = 12,-4,0
end 

routine  PUT DEC(integer  val)
  put sym('-') and  val = -val if  val < 0
  put dec(val//10) and  val = val-val//10*10 if  val >= 10
  put sym(val+'0')
end 

routine  PUT STRING(string (255) s)
integer  i
  put sym(charno(s,i)) for  i = 1,1,length(s)
end 

routine  INTERPRET(integer  type)
integer  i,j,m,v,v9
switch  s(0:31), e(0:7), ex(0:7)
  m = code>>3&7;  v = code&7;  v9 = code>>9&7
  ->s(type)
s(quick9):
  put sym('#')
  v9 = 8 if  v9 = 0
  put sym(v9+'0')
s(0):
  return 
s(tquick):  !Trap vector
  v = code&15
  put sym('#')
  put dec(v)
  if  v = 15 and  shortinteger(fr)&16_F000 = 0 start 
    put sym(',')
    put dec(shortinteger(fr));  fr = fr+2
  finish 
  return 
s(rel): s(crel):
  pcrel = fr-base
  v = code&255
  if  v = 0 start 
    v = shortinteger(fr);  fr = fr+2
  else 
    v = v-256 if  v&128 # 0
  finish 
  put dec(v)
  pcrel = pcrel+v
  return 
s(mquick):
  v = code&255
  v = v-256 if  v&128 # 0
  put sym('#')
  put dec(v)
  return 
s(ximm):
  put sym('#');  put sym('$')
  put hex(regs)
  return 
s(dea): !dest EA (reg:mode)
  m = code>>6&7;  v = v9
s(ea): s(cea): s(sea): s(wlsea):
  ->e(m)
s(qreg9):
  ->s(quick9) if  code&16_0020 = 0
s(reg9):
  v = v9
e(0): !EA mode 000: D
s(reg): s(creg): s(sreg): s(wlreg):
  put sym('D')
  put sym(v+'0')
  return 
s(areg9): s(sareg9):
  v = v9
e(1): !EA mode 001: A
s(areg):
  put sym('A')
  put sym(v+'0')
  return 
s(at9):
  v = v9
e(2):  !EA mode 010: (A)
s(at):
  put sym('(')
  put sym('A');  put sym(v+'0')
  put sym(')')
  return 
s(post9):
  v = v9
s(spost):
e(3): !EA mode 011: (A)+
  put string("(A")
  put sym(v+'0')
  put sym(')')
  put sym('+')
  return 
s(pre9):
  v = v9
s(spre):
e(4):  !EA mode 100: -(A)
  put sym('-')
  ->s(at)
s(adisp):
e(5):  !EA mode 101: d(A)
  put dec(shortinteger(fr))
  fr = fr+2
  ->s(at)
ex(3): !EA mode 111 011
  v = 8
e(6): !EA mode 110: d(A,R)
  i = shortinteger(fr);  fr = fr+2
  j = i&255;  j = j-256 if  j&128 # 0
  put dec(j);  !displacement
  put sym('(')
  if  v # 8 then  put sym('A') and  put sym(v+'0') c 
  else  put string("PC")
  put sym(',')
  if  i&(1<<15) = 0 then  put sym('D') c 
  else  put sym('A')
  put sym(i>>12&7+'0')
  put sym('.')
  if  i&(1<<11) = 0 then  put sym('W') c 
  else  put sym('L')
  put sym(')')
  return 
e(7): !EA mode 111
  ->ex(v)
ex(0): !EA mode 111 000
word:
  v = shortinteger(fr);  fr = fr+2
  if  -9 <= v <= 9 then  put dec(v) c 
  else  put sym('$') and  put hex(v)
  return 
ex(1): !EA mode 111 001
long:
  put sym('$')
  put hex(shortinteger(fr));  fr = fr+2
  put hex(shortinteger(fr));  fr = fr+2
  return 
ex(2): !EA mode 111 010
  v = shortinteger(fr)
  pcrel = fr-base+v
  put dec(v)
  fr = fr+2
  put string("(PC)")
  return 
ex(4): !EA mode 111 100
s(imm):  !immediate
  put sym('#')
  ->word if  size = 1
  ->long if  size = 2
  v = shortinteger(fr)&255;  fr = fr+2
  v = v-256 if  v&128 # 0
  put dec(v)
  return 
ex(5): !EA mode 111 101
  put string("111101")
  return 
ex(6): !EA mode 111 110
  put string("111110")
  return 
ex(7): !EA mode 111 111
  put string("111111")
  return 
s(uspsr):
  if  code&16_FFF0 = 16_4E60 then  put string("USP") c 
  else  put string("SR")
  return 
s(ccr):
  put string("CCR")
  return 
s(*):
  write(type,0)
end ;  !interpret
  
!To verify group limits:
!  %for p = 0,1,13 %cycle
!      i = def(limit(p))<<2;  !print mnemonic
!      print symbol(i>>27+'A'-1) %and i = i<<5 %until i = 0
!      newline
!  %repeat
  cycle 
    fr = from
    code = shortinteger(fr)&16_FFFF;  fr = fr+2
    p = limit(code>>12)
    ncode = (¬code)<<16
    p = 1 if  code&16_FF00 = 0;  !00xx usually not instr
    cycle 
      p = p-2
      exit  if  p < 0
      format = def(p+1)
      if  format&ncode = 0 start ;  !quick check
        t1 = format>>5&31;  t2 = format&31
        exit  if  code&mask(t1)&mask(t2) = format>>16
      finish 
    repeat 
    bp = 0
    pcrel = 1
    if  p > 0 start 
      i = def(p)<<2;  !print mnemonic
      put sym(i>>27+'A'-1) and  i = i<<5 until  i = 0
      if  format&cond # 0 start ;  !condition mask present
        i = cpair(code>>8&15)
        put sym(i>>8);  put sym(i&255)
      finish 
      size = 1;  !Word-size (for immediate)
      if  format&(sized+msized+wlsized) # 0 start 
        if  format&sized # 0 start 
          size = code>>6&3
          size = code>>8&1+1 if  format&(sized>>1) # 0;  !ASIZED
        else  if  format&msized # 0;  !MOVE
          size = code>>12&3;  size = size>>1 if  size&1 # 0
        else ;                        !WLSIZED (MOVEM,MOVEP)
          size = code>>6&1+1
          if  code > 16_4000 start ;  !MOVEM
            regs = shortinteger(fr);  fr = fr+2;  !reg mask
          finish 
        finish 
        put sym('.')
        put sym(ssym(size))
      finish 
      if  t2 # 0 start 
        put sym(' ')
        if  t1 # 0 start 
          interpret(t1)
          put sym(',')
        finish 
        interpret(t2)
      finish 
    finish  else  put sym('?')
    if  brief = 0 start 
      phex(from-base);  space
      outcol = 5
      cycle 
        space;  phex(shortinteger(from))
        outcol = outcol+5
        from = from+2
      repeat  until  from = fr
      if  pcrel # 1 start 
        printstring(" [");  phex(pcrel);  printsymbol(']')
        outcol = outcol+7
      finish 
      spaces(26-outcol)
    finish  else  from = fr
    print symbol(buff(p)) for  p = 1,1,bp
    newline
    newline if  shortinteger(fr-2) = 16_4E75;  !rts
  repeat  until  from >= upto
end 

routine  READ AND DECODE(integer  lo,hi)
integer  P,Q,K,V,BUFF,LIM
on  9 start 
  q = buff;  decode(lo,q,p) if  p > q
  return 
finish 
  buff = addr(store(0));  lo = buff-lo;  hi = hi+lo
  lim = addr(store(storemax))+2
  cycle 
    p = buff;  lim = hi if  hi < lim
    k = nl
    cycle 
      v = 0;  q = buff
      if  binary = 0 start 
        read symbol(k) while  k < '0'
        exit  if  k = ':'
        cycle 
          k = k-'a'+'A' if  k > 'Z'
          k = k-'0'
          k = k-7 if  k > 9
          v = v<<4+k;  q = q+1
          read symbol(k)
        repeat  until  k < '0' or  q = 4
      else 
!$IF VAX
{        read ch(v);  %signal 9 %if v&(¬255) # 0
{        read ch(k);  %signal 9 %if k&(¬255) # 0
!$IF APM
        read symbol(v);  read symbol(k)
!$FINISH
        v = v<<8+k
      finish 
!$IF VAX
{      v = v!16_FFFF0000 %if v&16_8000 # 0
!$FINISH
      shortinteger(p) <- v if  p >= buff
      p = p+2
    repeat  until  p >= lim
    q = buff;  decode(lo,q,p) if  p > q
    exit  if  p >= hi
    hi = hi-(p-buff)
  repeat 
end 

  parm = cliparam
  define param("CODEFILE",infile,0)
  define param("LISTING",outfile,pamoutfile+pamnewgroup)
  define int param("FROM - Start address",lo,0)
  define int param("TO - Final address",hi,0)
  define enum param("Hex,BINARY",binary,0)
  define enum param("FULL,BRief",brief,0)
  process parameters(cliparam)
  select output(1)
  if  infile # "" or  binary = 0 start 
    if  infile # "" start 
      open input(1,infile)
      select input(1)
    finish 
    read and decode(lo,hi)
  else 
    prompt("Lo(hex):");  rhex(lo)
    prompt("Hi(hex):");  rhex(hi);  hi = lo+256 if  hi < lo
    decode(lo&(¬16_FFFF),lo,hi)
  finish 
endofprogram