! Motorola 88100 dis-assembler include file
! RWT December 1989

%routine dissemble(%integer i)

%owninteger pc=0

%conststring(3)%array condition(0:31)=-
  "0", "GT0", "EQ0", "GE0",   "4",  "5",   "6",  "7",
  "8",   "9",  "10", "NE0", "LT0", "13", "LE0", "15",
 "16",  "17",  "18",  "19",  "20", "21",  "22", "23",
 "24",  "25",  "26",  "27",  "28", "29",  "30", "31"

%conststring(5)%array carry(1:3) = ".CO",".CI",".CIO"

%conststring(7)%array memory(0:15)=-
"XMEM.BU", "XMEM", "LD.HU", "LD.BU",  "LD.D",  "LD",  "LD.H",  "LD.B",
   "ST.D",   "ST",  "ST.H",  "ST.B", "LDA.D", "LDA", "LDA.H", "LDA.B"

%conststring(7)%array logical(0:15)=-
"AND","AND.U","MASK","MASK.U","XOR","XOR.U","OR","OR.U",
"AND","AND.C","MASK","MASK.C","XOR","XOR.C","OR","OR.C"

%conststring(5)%array arithmetic(0:7)=-
"ADDU","SUBU","DIVU","MUL","ADD","SUB","DIV","CMP"

%conststring(5)%array branch(0:7) =-
"BR","BR.N","BSR","BSR.N","BB0","BB0.N","BB1","BB1.N"

%conststring(5)%array jump(0:3) = "JMP","JMP.N","JSR","JSR.N"

%conststring(5)%array field(0:5) = "CLR","SET","EXT","EXTU","MAK","ROT"

%conststring(7)%array rn(0:31)=-
 "R0",     "R1",     "R2/P1", "R3/P2", "R4/P3", "R5/P4", "R6/P5", "R7/P6",
 "R8/P7",  "R9/P8", "R10/T4","R11/T3","R12/T2","R13/T1","R14/V1","R15/V2",
"R16/V3", "R17/V4", "R18/V5","R19/V6","R20/V7","R21/V8","R22/V9","R23/V10",
"R24/V11","R25/V12","R26/B2","R27/B1","R28/PB","R29/SB","R30/FP","R31/SP"

%conststring(5)%array cr(0:63)=-
 "PID",  "PSR", "EPSR", "SSBR", "SXIP", "SNIP", "SFIP",  "VBR",
"DMT0", "DMD0", "DMA0", "DMT1", "DMD1", "DMA1", "DMT2", "DMD2",
"DMA2",  "SR0",  "SR1",  "SR2",  "SR3", "CR21", "CR22", "CR23",
"CR24", "CR25", "CR26", "CR27", "CR28", "CR29", "CR30", "CR31",
"CR32", "CR33", "CR34", "CR35", "CR36", "CR37", "CR38", "CR39",
"CR40", "CR41", "CR42", "CR43", "CR44", "CR45", "CR46", "CR47",
"CR48", "CR49", "CR50", "CR51", "CR52", "CR53", "CR54", "CR55",
"CR56", "CR57", "CR58", "CR59", "CR60", "CR61", "CR62", "CR63"

%conststring(5)%array fcr(0:63)=-
"FPECR","FPHS1","FPLS1","FPHS2","FPLS2", "FPPT", "FPRH", "FPRL",
 "FPIT", "FCR9","FCR10","FCR11","FCR12","FCR13","FCR14","FCR15",
"FCR16","FCR17","FCR18","FCR19","FCR20","FCR21","FCR22","FCR23",
"FCR24","FCR25","FCR26","FCR27","FCR28","FCR29","FCR30","FCR31",
"FCR32","FCR33","FCR34","FCR35","FCR36","FCR37","FCR38","FCR39",
"FCR40","FCR41","FCR42","FCR43","FCR44","FCR45","FCR46","FCR47",
"FCR48","FCR49","FCR50","FCR51","FCR52","FCR53","FCR54","FCR55",
"FCR56","FCR57","FCR58","FCR59","FCR60","FCR61", "FPSR", "FPCR"

%integer d=i>>21&31, s1=i>>16&31, s2=i&31, i16=i&16_ffff, d26=i&16_3ffffff
%integer mainop=i>>26, subop=i>>8&255

  %routine r(%integer n)
    printstring(", ") %and n = \n %if n<0
    printstring(rn(n))
  %end

  %integerfn sign extend(%integer n,bits)
  %integer mask = -(1<<bits)  {eg bits=16 => mask=-00010000=ffff0000}
    n = n&(\mask)
    n = n!mask %if n&(mask>>1)#0
    %result = n
  %end

  %routine phex1(%integer x)
    x = x&15; x = x+'A'-'0'-10 %if x>9; printsymbol(x+'0')
  %end

  %routine phex2(%integer x)
    phex1(x>>4); phex1(x)
  %end

  %routine phex4(%integer x)
    phex2(x>>8); phex2(x)
  %end

  %routine phex6(%integer x)
    phex4(x>>8); phex2(x)
  %end

  %routine phex(%integer x)
    phex6(x>>8); phex2(x)
  %end

  %routine comma
    printstring(", ")
  %end

  %routine f(%string(7)s,%integer zero,suffix)
    %routine sd(%integer x)
      %if x=0 %then printsymbol('S') %else printsymbol('D')
    %end
    printstring("*improper* ") %unless i&zero=0
    printstring(s); printsymbol('.')
    sd(i&1)  %if suffix&4#0
    sd(i&16) %if suffix&2#0
    sd(i&4)  %if suffix&1#0
    space; r(d); r(\s1) %unless suffix&2=0; r(\s2)
    newline
  %end

  phex6(pc); spaces(2); phex(i); spaces(2); pc = pc+4

  %if mainop<16 %start
    printstring(memory(mainop)); space; r(d)
    comma; write(i16,0)
    printsymbol('('); r(s1)
    printsymbol(')'); newline; %return
  %finish

  %if mainop<32 %start
    %if mainop&8=0 %start
      printstring(logical(mainop&7))
    %else
      printstring(arithmetic(mainop&7))
    %finish
    space; r(d); r(\s1); comma; write(i16,0)
    newline; %return
  %finish

  %if mainop=32 %start
    ->junk %unless subop&16_30=0 %and subop&16_c0#0
    printsymbol('F') %if subop&8#0
    %if subop>>6=1 %start
      printstring("LDCR "); r(d)
    %else
      %if subop>>6=2 %start
        printstring("STCR "); r(s1)
      %else
        printstring("XCR "); r(d); r(\s1)
      %finish
      %unless s1=s2 %start
        printsymbol('/'); write(s2,0); printsymbol('?')
      %finish
    %finish
    comma; d = i>>5&63
    %if subop&8=0 %then printstring(cr(d)) %else printstring(fcr(d))
    newline; %return
  %finish

  %if mainop=33 %start
%switch float(0:15)
    ->junk %unless i&16_8540=0
    i = i>>5
    ->float(subop>>3)
float(0):  f("FMUL",4_000,7); %return
float(4):  f("FLT", 4_110,5); %return
float(5):  f("FADD",4_000,7); %return
float(6):  f("FSUB",4_000,7); %return
float(7):  f("FCMP",4_001,7); %return
float(9):  f("INT", 4_101,5); %return
float(10): f("NINT",4_101,5); %return
float(11): f("TRNC",4_101,5); %return
float(14): f("FDIV",4_000,7); %return
  %finish

  %if mainop<56 %start
    printstring(branch(mainop&7)); space
    %if mainop&4=0 %start
      phex6(signextend(d26-1,26)<<2+pc)
    %else
      write(d,0)
br:   r(\s1); comma
      phex6(signextend(i16-1,16)<<2+pc)
    %finish
    newline; %return
  %finish

  %if mainop&(\1)=58 %start
    printstring("BCND"); printstring(".N") %if mainop&1#0
    space; printstring(condition(d)); ->br
  %finish

  %if mainop=60 %start
    ->junk %unless subop&16_84=16_80
    subop = subop>>3&7; ->junk %if subop>5
    %if i&16_4000=0 %start
      printstring(field(subop)); space; r(d); r(\s1)
      d = i>>5&31; d = 32 %if d=0
      comma; write(d,0) %unless subop=5
      printsymbol('<'); write(s2,0); printsymbol('>')
    %else
      ->junk %unless i&16_c600=16_c000
      %if subop=2 %start
        printstring("TB0"); write(d,1)
      %elseif subop=3
        printstring("TB1"); write(d,1)
      %elseif subop=5
        printstring("TCND "); printstring(condition(d))
      %finishelse ->junk
      r(\s1); comma; write(i&511,0)
    %finish
    newline; %return
  %finish

  %if mainop=61 %start
    ->junk %unless i&16_e0=0
    %unless subop&16_c0=0 %or subop&16_e0=16_60 %start
      ->junk %unless subop&3=0
    %finish
    %if subop<16_40 %start
      printstring(memory(subop>>2)); printstring(".USR") %if subop&1#0
      space; r(d); r(\s1)
      %if subop&2=0 %then r(\s2) %elsestart
        printsymbol('['); r(s2); printsymbol(']')
      %finish
    %elseif subop<16_60
      printstring("*improper* ") %if subop>>3&3=1
      printstring(logical(subop>>2&7+8))
r3:   space; r(d); r(\s1); r(\s2)
    %elseif subop<16_80
      printstring(arithmetic(subop>>2&7))
      %if subop&3#0 %start
        printstring(carry(subop&3))
        printstring("??") %if subop&8#0
      %finish
      ->r3
    %elseif subop<16_b0
      ->junk %if subop&7#0
      ->junk %if subop>>3&7>5
      printstring(field(subop>>3&7))
      ->r3
    %elseif subop&16_f0=16_c0
      printstring(jump(subop>>2&3))
      space; r(s2)
    %elseif subop&16_f8=16_e8
      printstring("FF"); printsymbol('1'-subop>>2&1)
      space; r(d); r(\s2)
    %elseif subop=16_f8
      printstring("TBND "); r(s1); r(\s2)
    %elseif subop=16_fc
      printstring("RTE")
    %finishelse ->junk
    newline; %return
  %finish

  %if mainop=62 %start
    printstring("TBND "); r(s1); comma; write(i16,0); newline; %return
  %finish

float(*): junk:
  printstring("*undefined*"); newline

%end  {of dissemble}
