home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / oberon / system / decoder.mod (.txt) < prev    next >
Oberon Text  |  1977-12-31  |  66KB  |  2,112 lines

  1. Syntax10.Scn.Fnt
  2. MODULE Decoder;
  3. (* Disassembler for MC68020-code with coprocessor MC68881.
  4.  Diplomarbeit Samuel Urech
  5.  Programming language: Oberon-2 on Ceres-1
  6.  Date: 7.11.92  Current version: 23.2.93 *)
  7.  IMPORT Oberon, Texts, Files, TextFrames, MenuViewers;
  8.  CONST DUMMY = 0;
  9.     PC = -1;
  10.     (* instructions *)
  11.     ORI = 0; ANDI = 1; EORI = 2; CMPI = 3; ADDI = 4; SUBI = 5; JMP = 6; JSR = 7; PEA = 8; NBCD = 9; TAS = 10;
  12.     RTD = 11; STOP = 12; MUL = 13; dIV = 14; ADD = 15; AND = 16; CMP = 17; EOR = 18; oR = 19; SUB = 20;
  13.     ABCD = 21; SBCD = 22; PACK = 23; UNPK = 24; ADDA = 25; CMPA = 26; SUBA = 27; ADDX = 28; SUBX = 29;
  14.     ASL = 30; ASR = 31; LSL = 32; LSR = 33; ROL = 34; ROR = 35; ROXL = 36; ROXR = 37; BFTST = 38; BFCHG = 39;
  15.     BFEXTU = 40; BFEXTS = 41; BFCLR = 42; BFFFO = 43; BFSET = 44;
  16.     (* coprocessor opcodes *)
  17.     FABS = 18H; FACOS = 1CH; FADD = 22H; FASIN = 0CH; FATAN = 0AH; FATANH = 0DH; FCMP = 38H;
  18.     FCOS = 1DH; FCOSH = 19H; FDIV = 20H; FETOX = 10H; FETOXM1 = 8; FGETEXP = 1EH; FGETMAN = 1FH;
  19.     FINT = 1; FINTRZ = 3; FLOG10 = 15H; FLOG2 = 16H; FLOGN = 14H; FLOGNP1 = 6; FMOD = 21H; FMOVE = 0;
  20.     FMUL = 23H; FNEG = 1AH; FREM = 25H; FSCALE = 26H; FSGLDIV = 24H; FSGLMUL = 27H; FSIN = 0EH;
  21.     FSINH = 2; FSQRT = 4; FSUB = 28H; FTAN = 0FH; FTANH = 9; FTENTOX = 12H; FTST = 3AH; FTWOTOX = 11H;
  22.     (* Floating Point Condition Codes *)
  23.     FEQ = 1; FNE = 0EH; FGT = 12H; FNGT = 1DH; FGE = 13H; FNGE = 1CH; FLT = 14H; FNLT = 1BH; FLE = 15H;
  24.     FNLE = 1AH; FGL = 16H; FNGL = 19H; FGLE = 17H; FNGLE = 18H; FOGT = 2; FULE = 0DH; FOGE = 3; FULT = 0CH;
  25.     FOLT = 4; FUGE = 0BH; FOLE = 5; FUGT = 0AH; FOGL = 6; FUEQ = 9; fOR = 7; FUN = 8; FF = 0; FT = 0FH;
  26.     FSF = 10H; FST = 1FH; FSEQ = 11H; FSNE = 1EH;
  27.     (* instruction sizes *)
  28.     byte = 0; word = 1; long = 2; other = 3;
  29.     (* structure forms *)
  30.     Byte = 1; Bool = 2; Char = 3; SInt = 4; Int = 5; LInt = 6; Real = 7; LReal = 8; Set = 9; String = 10;
  31.     Pointer = 13; ProcTyp = 14; Comp = 15;
  32.     BlockMisaligned = "Block misaligned.";
  33.  VAR scanner : Texts.Scanner;
  34.    writer : Texts.Writer;
  35.    file : Files.File;
  36.    rider : Files.Rider;
  37.    frame : TextFrames.Frame;
  38.    output : Texts.Text;
  39.    viewer : MenuViewers.Viewer;
  40.    pc : LONGINT;
  41.  PROCEDURE Getbits( x : INTEGER; from, to : INTEGER) : INTEGER;
  42.  (* Returns a number of bits of a number. *)
  43.  BEGIN (* Getbits *)
  44.   RETURN SHORT( ASH( x, -to ) MOD ASH( 2, from - to ) )
  45.  END Getbits;
  46.  PROCEDURE Write( ch : CHAR );
  47.  (* Writes a character to the output. *)
  48.  BEGIN
  49.   Texts.Write( writer,ch );
  50.  END Write;
  51.  PROCEDURE WriteString( s : ARRAY OF CHAR );
  52.  (* Writes a string to the output. *)
  53.  BEGIN
  54.   Texts.WriteString( writer, s );
  55.  END WriteString;
  56.  PROCEDURE WriteLn;
  57.  (* Writes a line feed to the output. *)
  58.  BEGIN
  59.   Texts.WriteLn( writer );
  60.  END WriteLn;
  61.  PROCEDURE WriteInt( x : LONGINT );
  62.  (* Writes a longint to the output. *)
  63.  BEGIN
  64.   Texts.WriteInt( writer, x, 0 );
  65.  END WriteInt;
  66.  PROCEDURE WriteHex( x : LONGINT );
  67.  (* Writes a longint in hexadecimal form to the output. *)
  68.  BEGIN
  69.   Texts.WriteHex( writer, x );
  70.  END WriteHex;
  71.  PROCEDURE Read( VAR ch : CHAR );
  72.  (* Reads a character from the file. *)
  73.  BEGIN (* Read *)
  74.   Files.Read( rider, ch );
  75.  END Read;
  76.  PROCEDURE ReadInt( VAR x : INTEGER );
  77.  (* Reads a word from the file. *)
  78.   VAR hi, lo : CHAR;
  79.  BEGIN (* ReadInt *)
  80.   Files.Read( rider, hi );
  81.   Files.Read( rider, lo );
  82.   x := 100H * ORD( hi )+ ORD( lo );
  83.   INC( pc, 2 );
  84.  END ReadInt;
  85.  PROCEDURE ReadLongint( VAR x : LONGINT );
  86.  (* Reads a longword from the file. *)
  87.   VAR lo : LONGINT;
  88.     hi, l : INTEGER;
  89.  BEGIN (* ReadLongint *)
  90.   ReadInt( hi );
  91.   ReadInt( l ); lo := l;
  92.   IF lo < 0 THEN INC( lo, 65536 ); END;
  93.   x := 10000H * hi + lo;
  94.  END ReadLongint;
  95.  PROCEDURE ReadDynint( VAR x : LONGINT );
  96.  (* Reads an integer of dynamic length. *)
  97.   VAR n : LONGINT;
  98.     shift : SHORTINT;
  99.     ch : CHAR;
  100.  BEGIN (* ReadDynint *)
  101.   shift := 0;
  102.   n := 0;
  103.   Files.Read( rider, ch );
  104.   WHILE ORD( ch ) >= 128 DO
  105.    INC( n, ASH( ORD( ch ) MOD 128, shift ) );
  106.    INC( shift, 7 );
  107.    Files.Read( rider, ch );
  108.   END; (* WHILE *)
  109.   x := n + ASH( ORD( ch ) MOD 64, shift ) - ASH( ORD( ch ) DIV 64, shift ) * 64
  110.  END ReadDynint;
  111.  PROCEDURE ReadString( VAR string : ARRAY OF CHAR; len : INTEGER );
  112.  (* Reads a string from the file. Reads at least len characters. *)
  113.   VAR i : INTEGER;
  114.     ch : CHAR;
  115.  BEGIN (* ReadString *)
  116.   i := 0;
  117.   REPEAT
  118.    Read( ch );
  119.    string[ i ] := ch;
  120.    INC( i );
  121.   UNTIL ch = 0X;
  122.   WHILE i < len DO string[ i ] := 0X; Read( ch ); INC( i ); END;
  123.  END ReadString;
  124.  PROCEDURE WriteType( ch : CHAR );
  125.  (* Writes the given type in plain text. *)
  126.  BEGIN (* WriteType *)
  127.   CASE ORD( ch ) OF
  128.    Byte : WriteString( " : BYTE" );
  129.    | Bool : WriteString( " : BOOLEAN" );
  130.    | Char : WriteString( " : CHAR" );
  131.    | SInt : WriteString( " : SHORTINT" );
  132.    | Int : WriteString( " : INTEGER" );
  133.    | LInt : WriteString( " : LONGINT" );
  134.    | Real : WriteString( " : REAL" );
  135.    | LReal : WriteString( " : LONGREAL" );
  136.    | Set : WriteString( " : SET" );
  137.    | String : WriteString( " : String" );
  138.    | Pointer : WriteString( " : POINTER" );
  139.    | ProcTyp : WriteString( " : PROCEDURE" );
  140.    | Comp : WriteString( " : Composite" );
  141.   ELSE WriteString( " : Undefined" );
  142.   END; (* CASE *)
  143.   WriteString( "   " );
  144.  END WriteType;
  145.  PROCEDURE WriteRegister( da, reg : INTEGER );
  146.  (* Writes a register. *)
  147.  BEGIN (* WriteRegister *)
  148.   IF da = 0 THEN
  149.    Write( "D" );
  150.   ELSE
  151.    Write( "A" );
  152.   END; (* IF *)
  153.   WriteInt( reg );
  154.  END WriteRegister;
  155.  PROCEDURE WriteCondition( condition : INTEGER );
  156.  (* Writes a condition. *)
  157.  BEGIN (* WriteCondition *)
  158.   CASE condition OF
  159.       0 : Write( "T" );
  160.    | 1 : Write( "F" );
  161.    | 2 : WriteString( "HI" );
  162.    | 3 : WriteString( "LS" );
  163.    | 4 : WriteString(  "CC" );
  164.    | 5 : WriteString( "CS" );
  165.    | 6 : WriteString( "NE" );
  166.    | 7 : WriteString( "EQ" );
  167.    | 8 : WriteString( "VC" );
  168.    | 9 : WriteString( "VS" );
  169.    | 10 : WriteString( "PL" );
  170.    | 11 : WriteString( "MI" );
  171.    | 12 : WriteString( "GE" );
  172.    | 13 : WriteString( "LT" );
  173.    | 14 : WriteString( "GT" );
  174.    | 15 : WriteString( "LE" );
  175.   END; (* CASE *)
  176.  END WriteCondition;
  177.  PROCEDURE WriteFloatCondition( condition : INTEGER );
  178.  (* Writes a coprocessor condition. *)
  179.  BEGIN (* WriteFloatCondition *)
  180.   CASE condition OF
  181.    FEQ : WriteString( "EQ" );
  182.    | FNE : WriteString( "NE" );
  183.    | FGT : WriteString( "GT" );
  184.    | FNGT : WriteString( "NGT" );
  185.    | FGE : WriteString( "GE" );
  186.    | FNGE : WriteString( "NGE" );
  187.    | FLT : WriteString( "LT" );
  188.    | FNLT : WriteString( "NLT" );
  189.    | FLE : WriteString( "LE" );
  190.    | FNLE : WriteString( "NLE" );
  191.    | FGL : WriteString( "GL" );
  192.    | FNGL : WriteString( "NGL" );
  193.    | FGLE : WriteString( "GLE" );
  194.    | FNGLE : WriteString( "NGLE" );
  195.    | FOGT : WriteString( "OGT" );
  196.    | FULE : WriteString( "ULE" );
  197.    | FOGE : WriteString( "OGE" );
  198.    | FULT : WriteString( "ULT" );
  199.    | FOLT : WriteString( "OLT" );
  200.    | FUGE : WriteString( "UGE" );
  201.    | FOLE : WriteString( "OLE" );
  202.    | FUGT : WriteString( "UGT" );
  203.    | FOGL : WriteString( "OGL" );
  204.    | FUEQ : WriteString( "UEQ" );
  205.    | fOR : WriteString( "OR" );
  206.    | FUN : WriteString( "UN" );
  207.    | FF : Write( "F" );
  208.    | FT : Write( "T" );
  209.    | FSF : WriteString( "SF" );
  210.    | FST : WriteString( "ST" );
  211.    | FSEQ : WriteString( "SEQ" );
  212.    | FSNE : WriteString( "SNE" );
  213.   END; (* CASE *)
  214.  END WriteFloatCondition;
  215.  PROCEDURE WriteSize( size : INTEGER );
  216.  (* Writes an operand size. *)
  217.  BEGIN
  218.   CASE size OF
  219.    byte : WriteString( ".B " );
  220.    | word : WriteString( ".W " );
  221.    | long : WriteString( ".L " );
  222.    | other : WriteString( "illegal operand size." );
  223.   END; (* CASE *)
  224.  END WriteSize;
  225.  PROCEDURE WriteFloatFormat( format : INTEGER; VAR size : INTEGER );
  226.  (* Writes an operand format of the coprocessor and returns the size of integer formats. *)
  227.  BEGIN (* WriteFloatFormat *)
  228.   size := other;
  229.   CASE format OF
  230.    0 : WriteString( "L " ); size := long;
  231.    | 1 : WriteString( "S " );
  232.    | 2 : WriteString( "X " );
  233.    | 3 : WriteString( "P " );
  234.    | 4 : WriteString( "W " ); size := word;
  235.    | 5 : WriteString( "D " );
  236.    | 6 : WriteString( "B " ); size := byte;
  237.    | 7 : WriteString( "P " );
  238.   END; (* CASE *)
  239.  END WriteFloatFormat;
  240.  PROCEDURE WriteComplexAddrMode( reg : INTEGER );
  241.  (* Reads extension word(s) if necessary and writes a complex adressing mode.
  242.   If reg = PC, the addressing mode is PC-relative. *)
  243.   VAR extension, bdSize, suppressBase, disp : INTEGER;
  244.   PROCEDURE WriteBaseDisplacement( bdSize, suppressBase, reg : INTEGER );
  245.   (* Reads the base displacement and writes it, writes address register or "CB", if necessary. *)
  246.    VAR displacement : INTEGER;
  247.      longDisplacement, offset : LONGINT;
  248.   BEGIN (* WriteBaseDisplacement *)
  249.    IF reg = PC THEN
  250.     offset := pc - 2;
  251.    ELSE
  252.     offset := 0;
  253.    END; (* IF *)
  254.    CASE bdSize OF
  255.        0 : WriteString( "illegal displacement size." );
  256.     | 1 : (* no displacement *)
  257.     | 2 : ReadInt( displacement );
  258.       WriteInt( displacement + offset );
  259.     | 3 : ReadLongint( longDisplacement );
  260.       WriteInt( longDisplacement + offset );
  261.    END; (* CASE *)
  262.    IF suppressBase = 0 THEN
  263.     IF reg = PC THEN
  264.      WriteString( ", PC" );
  265.     ELSE
  266.      WriteString( ", A" );
  267.      WriteInt( reg );
  268.     END; (* IF *)
  269.    END; (* IF *)
  270.   END WriteBaseDisplacement;
  271.   PROCEDURE WriteIndexRegister( extension : INTEGER );
  272.   (* Writes an index register with size and scaling. *)
  273.   BEGIN (* WriteIndexRegister *)
  274.    WriteRegister( Getbits( extension, 15, 15 ), Getbits( extension, 14, 12 ) );
  275.    IF Getbits( extension, 11, 11 ) = 0 THEN
  276.     WriteString( ".W*" );
  277.    ELSE
  278.     WriteString( ".L*" );
  279.    END; (* IF *)
  280.    CASE Getbits( extension, 10, 9 ) OF
  281.        0 : Write( "1" );
  282.     | 1 : Write( "2" );
  283.     | 2 : Write( "4" );
  284.     | 3 : Write( "8" );
  285.    END; (* CASE *)
  286.   END WriteIndexRegister;
  287.   PROCEDURE WriteOuterDisplacement( long : BOOLEAN );
  288.   (* Writes the outer displacement, which can be one or two words. *)
  289.    VAR displacement : INTEGER;
  290.      longDisplacement : LONGINT;
  291.   BEGIN (* WriteOuterDisplacement *)
  292.    IF long THEN
  293.     ReadLongint( longDisplacement );
  294.     WriteInt( longDisplacement );
  295.    ELSE
  296.     ReadInt( displacement );
  297.     WriteInt( displacement );
  298.    END; (* IF *)
  299.   END WriteOuterDisplacement;
  300.  BEGIN (* WriteComplexAddrMode *)
  301.   ReadInt( extension );
  302.   Write( "(" );
  303.   IF Getbits( extension, 8, 8 ) = 0 THEN
  304.    disp := Getbits( extension, 7, 0 );
  305.    IF reg = PC THEN
  306.     IF disp > 127 THEN
  307.      WriteInt( pc - 2 + disp - 256 );
  308.     ELSE
  309.      WriteInt( pc - 2 + disp );
  310.     END; (* IF *)
  311.     WriteString( ", CB" );
  312.    ELSE
  313.     IF disp > 127 THEN
  314.      WriteInt( disp - 256 );
  315.     ELSE
  316.      WriteInt( disp );
  317.     END; (* IF *)
  318.     WriteString( ", A" );
  319.     WriteInt( reg );
  320.    END; (* IF *)
  321.    WriteString( ", " );
  322.    WriteIndexRegister( extension );
  323.   ELSE
  324.    bdSize := Getbits( extension, 5, 4 );
  325.    suppressBase := Getbits( extension, 7, 7 );
  326.    IF Getbits( extension, 6, 6 ) = 0 THEN
  327.     CASE Getbits( extension, 2, 0 ) OF
  328.         0 : WriteBaseDisplacement( bdSize, suppressBase, reg );
  329.        WriteString( ", " );
  330.        WriteIndexRegister( extension );
  331.      | 1 : Write( "[" );
  332.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  333.        WriteString( ", " );
  334.        WriteIndexRegister( extension );
  335.        Write( "]" );
  336.      | 2 : Write( "[" );
  337.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  338.        WriteString( ", " );
  339.        WriteIndexRegister( extension );
  340.        WriteString( "], " );
  341.        WriteOuterDisplacement( FALSE );
  342.      | 3 : Write( "[" );
  343.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  344.        WriteString( ", " );
  345.        WriteIndexRegister( extension );
  346.        WriteString( "], " );
  347.        WriteOuterDisplacement( TRUE );
  348.      | 4 : WriteString( "illegal addressing mode." );
  349.      | 5 : Write( "[" );
  350.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  351.        Write( "]" );
  352.        WriteString( ", " );
  353.        WriteIndexRegister( extension );
  354.      | 6 : Write( "[" );
  355.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  356.        WriteString( "], " );
  357.        WriteIndexRegister( extension );
  358.        WriteString( ", " );
  359.        WriteOuterDisplacement( FALSE );
  360.      | 7 : Write( "[" );
  361.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  362.        WriteString( "], " );
  363.        WriteIndexRegister( extension );
  364.        WriteString( ", " );
  365.        WriteOuterDisplacement( TRUE );
  366.     END; (* CASE *)
  367.    ELSE (* without index *)
  368.     CASE Getbits( extension, 2, 0 ) OF
  369.         0 : WriteBaseDisplacement( bdSize, suppressBase, reg );
  370.      | 1 : Write( "[" );
  371.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  372.        Write( "]" );
  373.      | 2 : Write( "[" );
  374.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  375.        WriteString( "], " );
  376.        WriteOuterDisplacement( FALSE );
  377.      | 3 : Write( "[" );
  378.        WriteBaseDisplacement( bdSize, suppressBase, reg );
  379.        WriteString( "], " );
  380.        WriteOuterDisplacement( TRUE );
  381.      | 4, 5, 6, 7 : WriteString( "illegal addressing mode." );
  382.     END; (* CASE *)
  383.    END; (* IF *)
  384.   END; (* IF *)
  385.   Write( ")" );
  386.  END WriteComplexAddrMode;
  387.  PROCEDURE SingleAddressDecode( mode, reg, size : INTEGER );
  388.  (* Decodes an effective address comletely. Extension words are read if necessary. *)
  389.   VAR displacement, address, data : INTEGER;
  390.     longAddress, longData : LONGINT;
  391.  BEGIN (* SingleAddressDecode *)
  392.   CASE mode OF
  393.       0 : Write( "D" );
  394.      WriteInt( reg );
  395.    | 1 : Write( "A" );
  396.      WriteInt( reg );
  397.    | 2 : WriteString( "(A" );
  398.      WriteInt( reg );
  399.      Write( ")" );
  400.    | 3 : WriteString( "(A" );
  401.      WriteInt( reg );
  402.      WriteString( ")+" );
  403.    | 4 : WriteString( "-(A" );
  404.      WriteInt( reg );
  405.      Write( ")" );
  406.    | 5 : ReadInt( displacement );
  407.      Write( "(" );
  408.      WriteInt( displacement );
  409.      WriteString( ", A" );
  410.      WriteInt( reg );
  411.      Write( ")" );
  412.    | 6 : WriteComplexAddrMode( reg );
  413.    | 7 : CASE reg OF
  414.          0 : Write( "$" );
  415.         ReadInt( address );
  416.         WriteHex( address );
  417.       | 1 : Write( "$" );
  418.         ReadLongint( longAddress );
  419.         WriteHex( longAddress );
  420.       | 2 : ReadInt( displacement );
  421.         Write( "(" );
  422.         WriteInt( pc - 2 + displacement );
  423.         WriteString( ", CB)" );
  424.       | 3 : WriteComplexAddrMode( PC );
  425.       | 4 : Write( "#" );
  426.         CASE size OF
  427.          byte, word :
  428.           ReadInt( data );
  429.           WriteInt( data );
  430.          | long :
  431.           ReadLongint( longData );
  432.           Write( "$" );
  433.           WriteHex( longData );
  434.          | other :
  435.           WriteString( "illegal operand size." );
  436.         END; (* CASE *)
  437.       | 5, 6, 7 : WriteString( "illegal addressing mode." );
  438.      END; (* CASE *)
  439.   END; (* CASE *)
  440.  END SingleAddressDecode;
  441.  PROCEDURE Format1( op, mode, reg, size : INTEGER );
  442.  (* ORI, ANDI, EORI, ADDI, SUBI, CMPI *)
  443.   VAR immData : INTEGER;
  444.     longImmData : LONGINT;
  445.  BEGIN (* Format1 *)
  446.   CASE op OF
  447.    ORI : WriteString( "ORI" );
  448.    | ANDI : WriteString( "ANDI" );
  449.    | EORI : WriteString( "EORI" );
  450.    | SUBI : WriteString( "SUBI" );
  451.    | ADDI : WriteString( "ADDI" );
  452.    | CMPI : WriteString( "CMPI" );
  453.   ELSE
  454.    WriteString( "Illegal instruction." );
  455.   END; (* CASE *)
  456.   CASE size OF
  457.       0 : WriteString( ".B #$" );
  458.      ReadInt( immData );
  459.      WriteHex( immData );
  460.      WriteString( ", " );
  461.      IF ( mode = 7 ) & ( reg = 4 ) THEN
  462.       WriteString( "CCR" );
  463.      ELSE
  464.       SingleAddressDecode( mode, reg, byte );
  465.      END; (* IF *)
  466.    | 1 : WriteString( ".W #$" );
  467.      ReadInt( immData );
  468.      WriteHex( immData );
  469.      WriteString( ", " );
  470.      IF ( mode = 7 ) & ( reg = 4 ) THEN
  471.       WriteString( "SR" );
  472.      ELSE
  473.       SingleAddressDecode( mode, reg, word );
  474.      END; (* IF *)
  475.    | 2 : WriteString( ".L #$" );
  476.      ReadLongint( longImmData );
  477.      WriteHex( longImmData );
  478.      WriteString( ", " );
  479.      SingleAddressDecode( mode, reg, long );
  480.    | 3 : WriteString( "illegal operand size." );
  481.   END; (* CASE *)
  482.  END Format1;
  483.  PROCEDURE Format2( mode, reg : INTEGER );
  484.  (* BFINS *)
  485.   VAR instr2 : INTEGER;
  486.  BEGIN (* Format2 *)
  487.   WriteString( "BFINS " );
  488.   ReadInt( instr2 );
  489.   Write( "D" );
  490.   WriteInt( Getbits( instr2, 14, 12 ) );
  491.   WriteString( ", " );
  492.   SingleAddressDecode( mode, reg, DUMMY );
  493.   WriteString( " {" );
  494.   IF Getbits( instr2, 11, 11 ) = 0 THEN
  495.    WriteInt( Getbits( instr2, 10, 6 ) );
  496.   ELSE
  497.    Write( "D" );
  498.    WriteInt( Getbits( instr2, 8, 6 ) );
  499.   END; (* IF *)
  500.   Write( ":" );
  501.   IF Getbits( instr2, 5, 5 ) = 0 THEN
  502.    WriteInt( Getbits( instr2, 4, 0 ) );
  503.   ELSE
  504.    Write( "D" );
  505.    WriteInt( Getbits( instr2, 2, 0 ) );
  506.   END; (* IF *)
  507.   Write( "}" );
  508.  END Format2;
  509.  PROCEDURE Format3( mode, reg, size : INTEGER );
  510.  (* CHK2, CMP2 *)
  511.   VAR instr2 : INTEGER;
  512.  BEGIN (* Format3 *)
  513.   ReadInt( instr2 );
  514.   IF Getbits( instr2, 10, 0 ) = 0 THEN
  515.    IF Getbits( instr2, 11, 11 ) = 0 THEN
  516.     WriteString( "CMP2" );
  517.    ELSE
  518.     WriteString( "CHK2" );
  519.    END; (* IF *)
  520.    WriteSize( size );
  521.    SingleAddressDecode( mode, reg, byte );
  522.    WriteString( ", " );
  523.    WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
  524.   ELSE
  525.    WriteString( "illegal instruction." );
  526.   END; (* IF *)
  527.  END Format3;
  528.  PROCEDURE Format4( op, mode, reg : INTEGER );
  529.  (* BCHG, BCLR, BSET, BTST, static bit number. *)
  530.   VAR bitNr : INTEGER;
  531.  BEGIN (* Format4 *)
  532.   CASE op OF
  533.       0 : WriteString( "BTST #" );
  534.    | 1 : WriteString( "BCHG #" );
  535.    | 2 : WriteString( "BCLR #" );
  536.    | 3 : WriteString( "BSET #" );
  537.   END; (* CASE *)
  538.   ReadInt( bitNr );
  539.   WriteInt( bitNr );
  540.   WriteString( ", " );
  541.   SingleAddressDecode( mode, reg, DUMMY );
  542.  END Format4;
  543.  PROCEDURE Format5( mode, reg, size : INTEGER );
  544.  (* CAS, CAS2 *)
  545.   VAR instr2, instr3 : INTEGER;
  546.  BEGIN (* Format5 *)
  547.   ReadInt( instr2 );
  548.   IF ( mode = 7 ) & ( reg = 4 ) THEN (* CAS2 *)
  549.    ReadInt( instr3 );
  550.    WriteString( "CAS2" );
  551.    CASE size OF
  552.     0, 1 : WriteString( "illegal operand size." );
  553.     | 2 : WriteString( ".W D" );
  554.     | 3 : WriteString( ".L D" );
  555.    END; (* CASE *)
  556.    WriteInt( Getbits( instr2, 2, 0 ) );
  557.    WriteString( ":D" );
  558.    WriteInt( Getbits( instr3, 2, 0 ) );
  559.    WriteString( ", D" );
  560.    WriteInt( Getbits( instr2, 8, 6 ) );
  561.    WriteString( ":D" );
  562.    WriteInt( Getbits( instr3, 8, 6 ) );
  563.    WriteString( ", (" );
  564.    WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
  565.    WriteString( "):(" );
  566.    WriteRegister( Getbits( instr3, 15, 15 ), Getbits( instr3, 14, 12 ) );
  567.    Write( ")" );
  568.   ELSE (* CAS *)
  569.    WriteString( "CAS" );
  570.    CASE size OF
  571.        0 : WriteString( "illegal operand size." );
  572.     | 1 : WriteString( ".B D" );
  573.     | 2 : WriteString( ".W D" );
  574.     | 3 : WriteString( ".L D" );
  575.    END; (* CASE *)
  576.    WriteInt( Getbits( instr2, 2, 0 ) );
  577.    WriteString( ", D" );
  578.    WriteInt( Getbits( instr2, 8, 6 ) );
  579.    WriteString( ", " );
  580.    SingleAddressDecode( mode, reg, DUMMY );
  581.   END; (* IF *)
  582.  END Format5;
  583.  PROCEDURE Format6( mode, reg, size : INTEGER );
  584.  (* MOVES *)
  585.   VAR instr2 : INTEGER;
  586.  BEGIN (* Format6 *)
  587.   ReadInt( instr2 );
  588.   WriteString( "MOVES" );
  589.   WriteSize( size );
  590.   IF Getbits( instr2, 11, 11 ) = 0 THEN
  591.    SingleAddressDecode( mode, reg, DUMMY );
  592.    WriteString( ", " );
  593.    WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
  594.   ELSE
  595.    WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
  596.    WriteString( ", " );
  597.    SingleAddressDecode( mode, reg, DUMMY );
  598.   END; (* IF *)
  599.  END Format6;
  600.  PROCEDURE Format7( da, reg : INTEGER );
  601.  (* RTM *)
  602.  BEGIN (* Format7 *)
  603.   WriteString( "RTM " );
  604.   WriteRegister( da, reg );
  605.  END Format7;
  606.  PROCEDURE Format8( mode, reg : INTEGER );
  607.  (* CALLM *)
  608.   VAR instr2 : INTEGER;
  609.  BEGIN (* Format8 *)
  610.   WriteString( "CALLM #" );
  611.   ReadInt( instr2 );
  612.   WriteInt( instr2 );
  613.   WriteString( ", " );
  614.   SingleAddressDecode( mode, reg, DUMMY );
  615.  END Format8;
  616.  PROCEDURE Format9( dataReg, direction, size, addrReg : INTEGER );
  617.  (* MOVEP *)
  618.   VAR displacement : INTEGER;
  619.  BEGIN (* Format9 *)
  620.   WriteString( "MOVEP" );
  621.   IF size = 0 THEN
  622.    WriteString( ".W " );
  623.   ELSE
  624.    WriteString( ".L " );
  625.   END;
  626.   ReadInt( displacement );
  627.   IF direction = 0 THEN
  628.    Write( "(" );
  629.    WriteInt( displacement );
  630.    WriteString( ", A" );
  631.    WriteInt( addrReg );
  632.    WriteString( "), D" );
  633.    WriteInt( dataReg );
  634.   ELSE
  635.    Write( "D" );
  636.    WriteInt( dataReg );
  637.    WriteString( ", (" );
  638.    WriteInt( displacement );
  639.    WriteString( ", A" );
  640.    WriteInt( addrReg );
  641.    Write( ")" );
  642.   END; (* IF *)
  643.  END Format9;
  644.  PROCEDURE Format10( op, dataReg, mode, reg : INTEGER );
  645.  (* BCHG, BCLR, BSET, BTST, dynamic bit number. *)
  646.  BEGIN (* Format10 *)
  647.   CASE op OF
  648.       0 : WriteString( "BTST D" );
  649.    | 1 : WriteString( "BCHG D" );
  650.    | 2 : WriteString( "BCLR D" );
  651.    | 3 : WriteString( "BSET D" );
  652.   END; (* CASE *)
  653.   WriteInt( dataReg );
  654.   WriteString( ", " );
  655.   SingleAddressDecode( mode, reg, DUMMY );
  656.  END Format10;
  657.  PROCEDURE Format11( size, sourceMode, sourceReg, destMode, destReg : INTEGER );
  658.  (* MOVE, MOVEA *)
  659.  BEGIN (* Format11 *)
  660.   WriteString( "MOVE" );
  661.   IF destMode = 1 THEN
  662.    Write( "A" );
  663.   END; (* IF *)
  664.   CASE size OF
  665.       0 : WriteString( "illegal operand size." );
  666.    | 1 : WriteString( ".B " );
  667.      SingleAddressDecode( sourceMode, sourceReg, byte );
  668.    | 2 : WriteString( ".L " );
  669.      SingleAddressDecode( sourceMode, sourceReg, long );
  670.    | 3 : WriteString( ".W " );
  671.      SingleAddressDecode( sourceMode, sourceReg, word );
  672.   END; (* CASE *)
  673.   WriteString( ", " );
  674.   SingleAddressDecode( destMode, destReg, DUMMY );
  675.  END Format11;
  676.  PROCEDURE Format12( op, size, mode, reg : INTEGER );
  677.  (* CLR, NEG, NEGX, NOT, TST *)
  678.  BEGIN (* Format12 *)
  679.   CASE op OF
  680.        0 : WriteString( "NEGX" );
  681.    |  1 : WriteString( "CLR" );
  682.    |  2 : WriteString( "NEG" );
  683.    |  3 : WriteString( "NOT" );
  684.    |  5 : WriteString( "TST" );
  685.   ELSE
  686.    WriteString( "illegal instruction." );
  687.   END; (* CASE *)
  688.   WriteSize( size );
  689.   SingleAddressDecode( mode, reg, DUMMY );
  690.  END Format12;
  691.  PROCEDURE Format13( size, reg : INTEGER );
  692.  (* LINK *)
  693.   VAR disp : INTEGER;
  694.     longDisp : LONGINT;
  695.  BEGIN (* Format13 *)
  696.   WriteString( "LINK" );
  697.   IF size = 0 THEN
  698.    WriteString( ".W A" );
  699.    WriteInt( reg );
  700.    WriteString( ", #" );
  701.    ReadInt( disp );
  702.    WriteInt( disp );
  703.   ELSE
  704.    WriteString( ".L A" );
  705.    WriteInt( reg );
  706.    WriteString( ", #" );
  707.    ReadLongint( longDisp );
  708.    WriteInt( longDisp );
  709.   END; (* IF *)
  710.  END Format13;
  711.  PROCEDURE Format14( op, mode, reg : INTEGER );
  712.  (* JMP, JSR, PEA, NBCD, TAS, ASL, ASR, LSL, LSR, ROL, ROR, ROXL, ROXR *)
  713.  BEGIN (* Format14 *)
  714.   CASE op OF
  715.    JMP : WriteString( "JMP " );
  716.    | JSR : WriteString( "JSR " );
  717.    | PEA : WriteString( "PEA.L " );
  718.    | NBCD : WriteString( "NBCD.B " );
  719.    | TAS : WriteString( "TAS.B " );
  720.    | ASL : WriteString( "ASL.W " );
  721.    | ASR : WriteString( "ASR.W " );
  722.    | LSL : WriteString( "LSL.W " );
  723.    | LSR : WriteString( "LSR.W " );
  724.    | ROL : WriteString( "ROL.W " );
  725.    | ROR : WriteString( "ROR.W " );
  726.    | ROXL : WriteString( "ROXL.W " );
  727.    | ROXR : WriteString( "ROXR.W " );
  728.   END; (* CASE *)
  729.   SingleAddressDecode( mode, reg, DUMMY );
  730.  END Format14;
  731.  PROCEDURE Format15( op, data : INTEGER );
  732.  (* SWAP, BKPT, TRAP, UNLK, MOVE from USP, RTD, EXT.W, EXT.L, EXTB.L *)
  733.  BEGIN (* Format15 *)
  734.   CASE op OF
  735.    0 : WriteString( "SWAP.W D" );
  736.    | 1 : WriteString( "BKPT #" );
  737.    | 2 : WriteString( "TRAP #" );
  738.    | 3 : WriteString( "UNLK A" );
  739.    | 4 : WriteString( "MOVE.L USP, A" );
  740.    | 5 : WriteString( "EXT.W D" );
  741.    | 6 : WriteString( "EXT.L D" );
  742.    | 7 : WriteString( "EXTB.L D" );
  743.   END; (* CASE *)
  744.   WriteInt( data );
  745.  END Format15;
  746.  PROCEDURE Format16( reg : INTEGER );
  747.  (* MOVE to USP *)
  748.  BEGIN (* Format16 *)
  749.   WriteString( "MOVE.L A" );
  750.   WriteInt( reg );
  751.   WriteString( ", USP" );
  752.  END Format16;
  753.  PROCEDURE Format17( direction : INTEGER );
  754.  (* MOVEC *)
  755.   VAR instr2 : INTEGER;
  756.  BEGIN (* Format17 *)
  757.   ReadInt( instr2 );
  758.   IF direction = 0 THEN
  759.    WriteString( "MOVEC.L Control Register #" );
  760.    WriteInt( Getbits( instr2, 11, 0 ) );
  761.    WriteString( ", " );
  762.    WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
  763.   ELSE
  764.    WriteString( "MOVEC.L " );
  765.    WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
  766.    WriteString( ", Control Register #" );
  767.    WriteInt( Getbits( instr2, 11, 0 ) );
  768.   END; (* IF *)
  769.  END Format17;
  770.  PROCEDURE Format18( op : INTEGER );
  771.  (* RTD, STOP *)
  772.   VAR data : INTEGER;
  773.  BEGIN (* Format18 *)
  774.   CASE op OF
  775.    RTD : WriteString( "RTD #" );
  776.    | STOP : WriteString( "STOP #" );
  777.   END; (* CASE *)
  778.   ReadInt( data );
  779.   WriteInt( data );
  780.  END Format18;
  781.  PROCEDURE Format19( direction, size, mode, reg : INTEGER );
  782.  (* MOVEM *)
  783.   VAR regList : INTEGER;
  784.  BEGIN (* Format19 *)
  785.   IF size = 0 THEN
  786.    WriteString( "MOVEM.W " );
  787.   ELSE
  788.    WriteString( "MOVEM.L " );
  789.   END; (* IF *)
  790.   ReadInt( regList );
  791.   IF direction = 0 THEN
  792.    WriteString( "#$" );
  793.    WriteHex( regList );
  794.    WriteString( ", " );
  795.    SingleAddressDecode( mode, reg, DUMMY );
  796.   ELSE
  797.    SingleAddressDecode( mode, reg, DUMMY );
  798.    WriteString( ", #$" );
  799.    WriteHex( regList );
  800.   END; (* IF *)
  801.  END Format19;
  802.  PROCEDURE Format20( op, mode, reg : INTEGER );
  803.  (* MOVE CCR, MOVE SR *)
  804.  BEGIN (* Format20 *)
  805.   CASE op OF
  806.       0 : (*  MOVE from SR *)
  807.      WriteString( "MOVE.W SR, " );
  808.      SingleAddressDecode( mode, reg, DUMMY );
  809.    | 1 : (* MOVE from CCR *)
  810.      WriteString( "MOVE.W CCR, " );
  811.      SingleAddressDecode( mode, reg, DUMMY );
  812.    | 2 : (* MOVE to CCR *)
  813.      WriteString( "MOVE.W " );
  814.      SingleAddressDecode( mode, reg, word );
  815.      WriteString( ", SR" );
  816.    | 3 : (* MOVE to SR *)
  817.      WriteString( "MOVE.W " );
  818.      SingleAddressDecode( mode, reg, word );
  819.      WriteString( ", CCR" );
  820.   END; (* CASE *)
  821.  END Format20;
  822.  PROCEDURE Format21( size, dataReg, mode, reg : INTEGER );
  823.  (* CHK *)
  824.  BEGIN (* Format21 *)
  825.   WriteString( "CHK" );
  826.   IF size = 1 THEN
  827.    WriteString( ".W " );
  828.   ELSE
  829.    WriteString( ".L " );
  830.   END; (* IF *)
  831.   SingleAddressDecode( mode, reg, size );
  832.   WriteString( ", D" );
  833.   WriteInt( dataReg );
  834.  END Format21;
  835.  PROCEDURE Format22( addrReg, mode, reg : INTEGER );
  836.  (* LEA *)
  837.  BEGIN (* Format22 *)
  838.   WriteString( "LEA " );
  839.   SingleAddressDecode( mode, reg, DUMMY );
  840.   WriteString( ", A" );
  841.   WriteInt( addrReg );
  842.  END Format22;
  843.  PROCEDURE Format23( condition, reg : INTEGER );
  844.  (* DBcc *)
  845.   VAR disp : INTEGER;
  846.  BEGIN (* Format23 *)
  847.   WriteString( "DB" );
  848.   WriteCondition( condition );
  849.   WriteString( " D" );
  850.   WriteInt( reg );
  851.   WriteString( ", " );
  852.   ReadInt( disp );
  853.   WriteInt( pc - 2 + disp );
  854.  END Format23;
  855.  PROCEDURE Format24( condition, mode, reg : INTEGER );
  856.  (* Scc *)
  857.  BEGIN (* Format24 *)
  858.   Write( "S" );
  859.   WriteCondition( condition );
  860.   WriteString( ".B " );
  861.   SingleAddressDecode( mode, reg, DUMMY );
  862.  END Format24;
  863.  PROCEDURE Format25( condition, opmode : INTEGER );
  864.  (* TRAPcc *)
  865.   VAR data : INTEGER;
  866.     longData : LONGINT;
  867.  BEGIN (* Format25 *)
  868.   WriteString( "TRAP" );
  869.   WriteCondition( condition );
  870.   CASE opmode OF
  871.       2 : WriteString( ".W #" );
  872.      ReadInt( data );
  873.      WriteInt( data );
  874.    | 3 : WriteString( ".L #" );
  875.      ReadLongint( longData );
  876.      WriteInt( longData );
  877.    | 4 :
  878.   END; (* CASE *)
  879.  END Format25;
  880.  PROCEDURE Format26( op, data, size, mode, reg : INTEGER );
  881.  (* ADDQ, SUBQ *)
  882.  BEGIN (* Format26 *)
  883.   IF op = 0 THEN
  884.    WriteString( "ADDQ" );
  885.   ELSE
  886.    WriteString( "SUBQ" );
  887.   END; (* IF *)
  888.   WriteSize( size );
  889.   Write( "#" );
  890.   IF data = 0 THEN WriteInt( 8 );
  891.   ELSE WriteInt( data );
  892.   END; (* IF *)
  893.   WriteString( ", " );
  894.   SingleAddressDecode( mode, reg, DUMMY );
  895.  END Format26;
  896.  PROCEDURE Format27( condition, displacement : INTEGER );
  897.  (* Bcc, BRA, BSR *)
  898.   VAR wordDisplacement : INTEGER;
  899.     longDisplacement : LONGINT;
  900.  BEGIN (* Format27 *)
  901.   CASE condition OF
  902.       0 : WriteString( "BRA" );
  903.    | 1 : WriteString( "BSR" );
  904.   ELSE
  905.    Write( "B" );
  906.    WriteCondition( condition );
  907.   END;
  908.   CASE displacement OF
  909.       0 : WriteString( ".W " );
  910.      ReadInt( wordDisplacement );
  911.      WriteInt( pc - 2 + wordDisplacement );
  912.    | 255 : WriteString( ".L " );
  913.      ReadLongint( longDisplacement );
  914.      WriteInt( pc - 2 + longDisplacement );
  915.   ELSE
  916.    WriteString( ".B " );
  917.    IF displacement > 127 THEN
  918.     WriteInt( pc - 2 + displacement - 256 );
  919.    ELSE
  920.     WriteInt( pc - 2 + displacement );
  921.    END; (* IF *)
  922.   END; (* CASE *)
  923.  END Format27;
  924.  PROCEDURE Format28( reg, data : INTEGER );
  925.  (* MOVEQ *)
  926.  BEGIN (* Format28 *)
  927.   WriteString( "MOVEQ.L #" );
  928.   IF data > 127 THEN
  929.    WriteInt( data-256 );
  930.   ELSE
  931.    WriteInt( data );
  932.   END; (* IF *)
  933.   WriteString( ", D" );
  934.   WriteInt( reg );
  935.  END Format28;
  936.  PROCEDURE Format29( op, mode, reg : INTEGER );
  937.  (* MULS, MULU, DIVS, DIVSL, DIVU, DIVUL, long form *)
  938.   VAR instr2, size, qReg, rReg : INTEGER;
  939.  BEGIN (* Format29 *)
  940.   ReadInt( instr2 );
  941.   size := Getbits( instr2, 10, 10 );
  942.   qReg := Getbits( instr2, 14, 12 );
  943.   rReg := Getbits( instr2, 2, 0 );
  944.   IF op = MUL THEN
  945.    WriteString( "MUL" );
  946.   ELSE
  947.    WriteString( "DIV" );
  948.   END; (* IF *)
  949.   IF Getbits( instr2, 11, 11 ) = 0 THEN
  950.    Write( "U" );
  951.   ELSE
  952.    Write( "S" );
  953.   END; (* IF *)
  954.   IF ( op = dIV ) & ( size = 0 ) & ( rReg # qReg ) THEN
  955.    Write( "L" );
  956.   END; (* IF *)
  957.   WriteString( ".L " );
  958.   SingleAddressDecode( mode, reg, long );
  959.   WriteString( ", " );
  960.   IF qReg # rReg THEN
  961.    Write( "D" );
  962.    WriteInt( rReg );
  963.    Write( ":" );
  964.   END; (* IF *)
  965.   Write( "D" );
  966.   WriteInt( qReg );
  967.  END Format29;
  968.  PROCEDURE Format30( op, signed, dataReg, mode, reg : INTEGER );
  969.  (* MULS, MULU, DIVS, DIVU, short form *)
  970.  BEGIN (* Format30 *)
  971.   IF op = MUL THEN
  972.    IF signed = 0 THEN
  973.     WriteString( "MULU.W " );
  974.    ELSE
  975.     WriteString( "MULS.W " );
  976.    END;
  977.   ELSE
  978.    IF signed = 0 THEN
  979.     WriteString( "DIVU.W " );
  980.    ELSE
  981.     WriteString( "DIVS.W " );
  982.    END;
  983.   END;
  984.   SingleAddressDecode( mode, reg, word );
  985.   WriteString( ", D" );
  986.   WriteInt( dataReg );
  987.  END Format30;
  988.  PROCEDURE Format31( op, direction, dataReg, size, mode, reg : INTEGER );
  989.  (* ADD, AND, CMP, EOR, OR, SUB *)
  990.  BEGIN (* Format31 *)
  991.   CASE op OF
  992.    ADD : WriteString( "ADD" );
  993.    | AND : WriteString( "AND" );
  994.    | CMP : WriteString( "CMP" );
  995.    | EOR : WriteString( "EOR" );
  996.    | oR : WriteString( "OR" );
  997.    | SUB : WriteString( "SUB" );
  998.   END; (* CASE *)
  999.   WriteSize( size );
  1000.   IF direction = 0 THEN
  1001.    SingleAddressDecode( mode, reg, size );
  1002.    WriteString( ", D" );
  1003.    WriteInt( dataReg );
  1004.   ELSE
  1005.    Write( "D" );
  1006.    WriteInt( dataReg );
  1007.    WriteString( ", " );
  1008.    SingleAddressDecode( mode, reg, size );
  1009.   END; (* IF *)
  1010.  END Format31;
  1011.  PROCEDURE Format32( op, size, rm, xReg, yReg : INTEGER );
  1012.  (* ABCD, SBCD, ADDX, SUBX *)
  1013.  BEGIN (* Format32 *)
  1014.   CASE op OF
  1015.    ABCD : WriteString( "ABCD" );
  1016.    | SBCD : WriteString( "SBCD" );
  1017.    | ADDX : WriteString( "ADDX" );
  1018.    | SUBX : WriteString( "SUBX" );
  1019.   END; (* CASE *)
  1020.   WriteSize( size );
  1021.   IF rm = 0 THEN
  1022.    Write( "D" );
  1023.    WriteInt( xReg );
  1024.    WriteString( ", D" );
  1025.    WriteInt( yReg );
  1026.   ELSE
  1027.    WriteString( "-(A" );
  1028.    WriteInt( xReg );
  1029.    WriteString( "), -(A" );
  1030.    WriteInt( yReg );
  1031.    Write( ")" );
  1032.   END; (* IF *)
  1033.  END Format32;
  1034.  PROCEDURE Format33( op, rm, xReg, yReg : INTEGER );
  1035.  (* PACK, UNPK *)
  1036.   VAR adjustment : INTEGER;
  1037.  BEGIN (* Format33 *)
  1038.   IF op = PACK THEN
  1039.    WriteString( "PACK " );
  1040.   ELSE
  1041.    WriteString( "UNPK " );
  1042.   END; (* IF *)
  1043.   IF rm = 0 THEN
  1044.    Write( "D" );
  1045.    WriteInt(  xReg );
  1046.    WriteString( ", D" );
  1047.    WriteInt( yReg );
  1048.   ELSE
  1049.    WriteString( "-(A" );
  1050.    WriteInt( xReg );
  1051.    WriteString( "), -(A" );
  1052.    WriteInt( yReg );
  1053.    Write( ")" );
  1054.   END; (* IF *)
  1055.   WriteString( ", #" );
  1056.   ReadInt( adjustment );
  1057.   WriteInt( adjustment );
  1058.  END Format33;
  1059.  PROCEDURE Format34( op, size, addrReg, mode, reg : INTEGER );
  1060.  (* ADDA, CMPA, SUBA *)
  1061.  BEGIN (* Format34 *)
  1062.   CASE op OF
  1063.    ADDA : WriteString( "ADDA" );
  1064.    | CMPA : WriteString( "CMPA" );
  1065.    | SUBA : WriteString( "SUBA" );
  1066.   END; (* CASE *)
  1067.   IF size = 0 THEN
  1068.    WriteString( ".W " );
  1069.   ELSE
  1070.    WriteString( ".L " );
  1071.   END; (* IF *)
  1072.   SingleAddressDecode( mode, reg, size+1 );
  1073.   WriteString( ", A" );
  1074.   WriteInt( addrReg );
  1075.  END Format34;
  1076.  PROCEDURE Format35( size, xReg, yReg : INTEGER );
  1077.  (* CMPM *)
  1078.  BEGIN (* Format35 *)
  1079.   WriteString( "CMPM" );
  1080.   WriteSize( size );
  1081.   WriteString( "(A" );
  1082.   WriteInt( yReg );
  1083.   WriteString( ")+, (A" );
  1084.   WriteInt( xReg );
  1085.   WriteString( ")+" );
  1086.  END Format35;
  1087.  PROCEDURE Format36( opmode, xReg, yReg : INTEGER );
  1088.  (* EXG *)
  1089.  BEGIN (* Format36 *)
  1090.   WriteString( "EXG.L " );
  1091.   CASE opmode OF
  1092.       16 :   Write( "D" );
  1093.       WriteInt( xReg );
  1094.       WriteString( ", D" );
  1095.       WriteInt( yReg );
  1096.    | 17 :   Write( "A" );
  1097.       WriteInt( xReg );
  1098.       WriteString( ", A" );
  1099.       WriteInt( yReg );
  1100.    | 33 :   Write( "D" );
  1101.       WriteInt( xReg );
  1102.       WriteString( ", A" );
  1103.       WriteInt( yReg );
  1104.   ELSE
  1105.    WriteString( "illegal instruction." );
  1106.   END; (* CASE *)
  1107.  END Format36;
  1108.  PROCEDURE Format37( op, mode, reg : INTEGER );
  1109.  (* BFCHG, BFCLR, BFSET, BTST *)
  1110.   VAR instr2 : INTEGER;
  1111.  BEGIN (* Format37 *)
  1112.   CASE op OF
  1113.    BFCHG : WriteString( "BFCHG " );
  1114.    | BFCLR : WriteString( "BFCLR " );
  1115.    | BFSET : WriteString( "BFSET " );
  1116.    | BFTST : WriteString( "BFTST " );
  1117.   END; (* CASE *)
  1118.   ReadInt( instr2 );
  1119.   SingleAddressDecode( mode, reg, DUMMY );
  1120.   WriteString( " {" );
  1121.   IF Getbits( instr2, 11, 11 ) = 0 THEN
  1122.    WriteInt( Getbits( instr2, 10, 6 ) );
  1123.   ELSE
  1124.    Write( "D" );
  1125.    WriteInt( Getbits( instr2, 8, 6 ) );
  1126.   END; (* IF *)
  1127.   Write( ":" );
  1128.   IF Getbits( instr2, 5, 5 ) = 0 THEN
  1129.    WriteInt( Getbits( instr2, 4, 0 ) );
  1130.   ELSE
  1131.    Write( "D" );
  1132.    WriteInt( Getbits( instr2, 2, 0 ) );
  1133.   END; (* IF *)
  1134.   Write( "}" );
  1135.  END Format37;
  1136.  PROCEDURE Format38( op, mode, reg : INTEGER );
  1137.  (* BFEXTS, BFEXTU, BFFFO *)
  1138.   VAR instr2 : INTEGER;
  1139.  BEGIN (* Format38 *)
  1140.   CASE op OF
  1141.    BFEXTS : WriteString( "BFEXTS " );
  1142.    | BFEXTU : WriteString( "BFEXTU " );
  1143.    | BFFFO : WriteString( "BFFFO " );
  1144.   END; (* CASE *)
  1145.   ReadInt( instr2 );
  1146.   SingleAddressDecode( mode, reg, DUMMY );
  1147.   WriteString( " {" );
  1148.   IF Getbits( instr2, 11, 11 ) = 0 THEN
  1149.    WriteInt( Getbits( instr2, 10, 6 ) );
  1150.   ELSE
  1151.    Write( "D" );
  1152.    WriteInt( Getbits( instr2, 8, 6 ) );
  1153.   END; (* IF *)
  1154.   Write( ":" );
  1155.   IF Getbits( instr2, 5, 5 ) = 0 THEN
  1156.    WriteInt( Getbits( instr2, 4, 0 ) );
  1157.   ELSE
  1158.    Write( "D" );
  1159.    WriteInt( Getbits( instr2, 2, 0 ) );
  1160.   END; (* IF *)
  1161.   WriteString( "}, D" );
  1162.   WriteInt( Getbits( instr2, 14, 12 ) );
  1163.  END Format38;
  1164.  PROCEDURE Format39( op, cntReg, direction, size, ir, reg : INTEGER );
  1165.  (* ASL, ASR, LSL, ROXL, ROXR, ROL, ROR *)
  1166.  BEGIN (* Format39 *)
  1167.   CASE op OF
  1168.       0 : WriteString( "AS" );
  1169.    | 1 : WriteString( "LS" );
  1170.    | 2 : WriteString( "ROX" );
  1171.    | 3 : WriteString( "RO" );
  1172.   END; (* CASE *)
  1173.   IF direction = 0 THEN
  1174.    Write( "R" );
  1175.   ELSE
  1176.    Write( "L" );
  1177.   END; (* IF *)
  1178.   WriteSize( size );
  1179.   IF ir = 0 THEN
  1180.    Write( "#" );
  1181.    IF cntReg = 0 THEN
  1182.     Write( "8" );
  1183.    ELSE
  1184.     WriteInt( cntReg );
  1185.    END; (* IF *)
  1186.   ELSE
  1187.    Write( "D" );
  1188.    WriteInt( cntReg );
  1189.   END; (* IF *)
  1190.   WriteString( ", D" );
  1191.   WriteInt( reg );
  1192.  END Format39;
  1193.  PROCEDURE Format40( destReg, romoffs : INTEGER );
  1194.  (* FMOVECR *)
  1195.  BEGIN (* Format40 *)
  1196.   WriteString( "FMOVECR.X $" );
  1197.   WriteHex( romoffs );
  1198.   WriteString( ", FP" );
  1199.   WriteInt( destReg );
  1200.  END Format40;
  1201.  PROCEDURE Format41( opcode, mode, reg, rm, sourceSpec, destReg : INTEGER );
  1202.  (* normal coprocessor operation *)
  1203.   VAR size : INTEGER;
  1204.  BEGIN (* Format41 *)
  1205.   CASE opcode OF
  1206.    FABS : WriteString( "FABS." );
  1207.    | FACOS : WriteString( "FACOS." );
  1208.    | FADD : WriteString( "FADD." );
  1209.    | FASIN : WriteString( "FASIN." );
  1210.    | FATAN : WriteString( "FATAN." );
  1211.    | FATANH : WriteString( "FATANH." );
  1212.    | FCMP : WriteString( "FCMP." );
  1213.    | FCOS : WriteString( "FCOS." );
  1214.    | FCOSH : WriteString( "FCOSH." );
  1215.    | FDIV : WriteString( "FDIV." );
  1216.    | FETOX : WriteString( "FETOX." );
  1217.    | FETOXM1 : WriteString( "FETOXM1." );
  1218.    | FGETEXP : WriteString( "FGETEXP." );
  1219.    | FGETMAN : WriteString( "FGETMAN." );
  1220.    | FINT : WriteString(  "FINT." );
  1221.    | FINTRZ : WriteString( "FINTRZ." );
  1222.    | FLOG10 : WriteString( "FLOG10." );
  1223.    | FLOG2 : WriteString( "FLOG2." );
  1224.    | FLOGN : WriteString( "FLOGN." );
  1225.    | FLOGNP1 : WriteString( "FLOGNP1." );
  1226.    | FMOD : WriteString( "FMOD." );
  1227.    | FMOVE : WriteString( "FMOVE." );
  1228.    | FMUL : WriteString( "FMUL." );
  1229.    | FNEG : WriteString( "FNEG." );
  1230.    | FREM : WriteString( "FREM." );
  1231.    | FSCALE : WriteString( "FSCALE." );
  1232.    | FSGLDIV : WriteString( "FSGLDIV." );
  1233.    | FSGLMUL : WriteString( "FSGLMUL." );
  1234.    | FSIN : WriteString( "FSIN." );
  1235.    | FSINH : WriteString( "FSINH." );
  1236.    | FSQRT : WriteString( "FSQRT." );
  1237.    | FSUB : WriteString( "FSUB." );
  1238.    | FTAN : WriteString( "FTAN." );
  1239.    | FTANH : WriteString( "FTANH." );
  1240.    | FTENTOX : WriteString( "FTENTOX." );
  1241.    | FTST : WriteString( "FTST." );
  1242.    | FTWOTOX : WriteString( "FTWOTOX." );
  1243.   ELSE
  1244.    WriteString( "illegal coprocessor instruction." );
  1245.   END; (* CASE *)
  1246.   IF rm = 0 THEN
  1247.    WriteString( "X FP" );
  1248.    WriteInt( sourceSpec );
  1249.   ELSE
  1250.    WriteFloatFormat( sourceSpec, size );
  1251.    SingleAddressDecode( mode, reg, size );
  1252.   END; (* IF *)
  1253.   WriteString( ", FP" );
  1254.   WriteInt( destReg );
  1255.  END Format41;
  1256.  PROCEDURE Format42( mode, reg, rm, sourceSpec, destRegSin, destRegCos : INTEGER );
  1257.  (* FSINCOS *)
  1258.   VAR size : INTEGER;
  1259.  BEGIN (* Format42 *)
  1260.   WriteString( "FSINCOS." );
  1261.   IF rm = 0 THEN
  1262.    WriteString( "X FP" );
  1263.    WriteInt( sourceSpec );
  1264.   ELSE
  1265.    WriteFloatFormat( sourceSpec, size );
  1266.    SingleAddressDecode( mode, reg, size );
  1267.   END; (* IF *)
  1268.   WriteString( ", FP" );
  1269.   WriteInt( destRegCos );
  1270.   WriteString( ":FP" );
  1271.   WriteInt( destRegSin );
  1272.  END Format42;
  1273.  PROCEDURE Format43( mode, reg, dr, regList : INTEGER );
  1274.  (* FMOVE(M) FPcr *)
  1275.   PROCEDURE WriteControlRegs( fpcr, fpsr, fpiar : INTEGER );
  1276.   (* Writes a list of floating point control registers. *)
  1277.    VAR comma : BOOLEAN;
  1278.   BEGIN (* WriteControlRegs *)
  1279.    comma := FALSE;
  1280.    IF fpcr = 1 THEN
  1281.     WriteString( "FPCR" );
  1282.     comma := TRUE;
  1283.    END;
  1284.    IF fpsr = 1 THEN
  1285.     IF comma THEN WriteString( ", " ); END;
  1286.     WriteString( "FPSR" );
  1287.     comma := TRUE;
  1288.    END;
  1289.    IF fpiar = 1 THEN
  1290.     IF comma THEN WriteString( ", " ); END;
  1291.     WriteString( "FPIAR" );
  1292.    END;
  1293.   END WriteControlRegs;
  1294.  BEGIN (* Format43 *)
  1295.   WriteString( "FMOVEM.L " );
  1296.   IF dr = 0 THEN
  1297.    SingleAddressDecode( mode, reg, long );
  1298.    WriteString( ", " );
  1299.    WriteControlRegs( Getbits( regList, 2, 2 ), Getbits( regList, 1, 1 ), Getbits( regList, 0, 0 ) );
  1300.   ELSE
  1301.    WriteControlRegs( Getbits( regList, 2, 2 ), Getbits( regList, 1, 1 ), Getbits( regList, 0, 0 ) );
  1302.    WriteString( ", " );
  1303.    SingleAddressDecode( mode, reg, long );
  1304.   END; (* IF *)
  1305.  END Format43;
  1306.  PROCEDURE Format44( mode, reg, dr, statdyn, regList : INTEGER );
  1307.  (* FMOVEM FPn *)
  1308.  BEGIN (* Format44 *)
  1309.   WriteString( "FMOVEM.X " );
  1310.   IF dr = 0 THEN
  1311.    SingleAddressDecode( mode, reg, byte );
  1312.    IF statdyn = 0 THEN (* static *)
  1313.     WriteString( ", #" );
  1314.     WriteHex( regList );
  1315.    ELSE (* dynamic *)
  1316.     WriteString( ", D" );
  1317.     WriteInt( Getbits( regList, 6, 4 ) );
  1318.    END; (* IF *)
  1319.   ELSE
  1320.    IF statdyn = 0 THEN (* static *)
  1321.     Write( "#" );
  1322.     WriteHex( regList );
  1323.    ELSE (* dynamic *)
  1324.     Write( "D" );
  1325.     WriteInt( Getbits( regList, 6, 4 ) );
  1326.    END; (* IF *)
  1327.    WriteString( ", " );
  1328.    SingleAddressDecode( mode, reg, DUMMY );
  1329.   END; (* IF *)
  1330.  END Format44;
  1331.  PROCEDURE Format45( mode, reg, sourceReg, destFormat, kfactor : INTEGER );
  1332.  (* FMOVE from FPn *)
  1333.   VAR size : INTEGER;
  1334.  BEGIN (* Format45 *)
  1335.   WriteString( "FMOVE." );
  1336.   WriteFloatFormat( destFormat, size );
  1337.   WriteString( "FP" );
  1338.   WriteInt( sourceReg );
  1339.   WriteString( ", " );
  1340.   SingleAddressDecode( mode, reg, size );
  1341.   IF destFormat = 3 THEN (* static k-factor *)
  1342.    WriteString( "{#" );
  1343.    WriteInt( kfactor );
  1344.    Write( "}" );
  1345.   ELSIF destFormat = 7 THEN (* dynamic k-factor *)
  1346.    WriteString( "{D" );
  1347.    WriteInt( Getbits( kfactor, 6, 4 ) );
  1348.    Write( "}" );
  1349.   END;
  1350.  END Format45;
  1351.  PROCEDURE Format46( reg, condition : INTEGER );
  1352.  (* FDBcc *)
  1353.   VAR disp : INTEGER;
  1354.  BEGIN (* Format46 *)
  1355.   WriteString( "FDB" );
  1356.   WriteFloatCondition( condition );
  1357.   WriteString( " D" );
  1358.   WriteInt( reg );
  1359.   WriteString( ", " );
  1360.   ReadInt( disp );
  1361.   WriteInt( pc - 2 + disp );
  1362.  END Format46;
  1363.  PROCEDURE Format47( mode, reg, condition : INTEGER );
  1364.  (* FScc *)
  1365.  BEGIN (* Format47 *)
  1366.   WriteString( "FS" );
  1367.   WriteFloatCondition( condition );
  1368.   WriteString( ".B " );
  1369.   SingleAddressDecode( mode, reg, byte );
  1370.  END Format47;
  1371.  PROCEDURE Format48( mode, condition : INTEGER );
  1372.  (* FTRAPcc *)
  1373.   VAR data : INTEGER;
  1374.     longdata : LONGINT;
  1375.  BEGIN (* Format48 *)
  1376.   WriteString( "FTRAP" );
  1377.   WriteFloatCondition( condition );
  1378.   CASE mode OF
  1379.    2 :
  1380.     ReadInt( data );
  1381.     WriteString( ".W #" );
  1382.     WriteInt( data );
  1383.    | 3 :
  1384.     ReadLongint( longdata );
  1385.     WriteString( ".L #" );
  1386.     WriteInt( longdata );
  1387.    | 4 : (* nothing *)
  1388.   ELSE
  1389.    WriteString( "illegal operand mode." );
  1390.   END; (* CASE *)
  1391.  END Format48;
  1392.  PROCEDURE Format49( size, condition : INTEGER );
  1393.  (* FBcc *)
  1394.   VAR disp : INTEGER;
  1395.     longdisp : LONGINT;
  1396.  BEGIN (* Format49 *)
  1397.   WriteString( "FB" );
  1398.   WriteFloatCondition( condition );
  1399.   IF size = 0 THEN
  1400.    WriteString( ".W " );
  1401.    ReadInt( disp );
  1402.    WriteInt( pc - 2 + disp );
  1403.   ELSE
  1404.    WriteString( ".L " );
  1405.    ReadLongint( longdisp );
  1406.    WriteInt( pc - 2 + longdisp );
  1407.   END; (* IF *)
  1408.  END Format49;
  1409.  PROCEDURE Format50( opcode, mode, reg : INTEGER );
  1410.  (* FSAVE, FRESTORE *)
  1411.  BEGIN (* Format50 *)
  1412.   CASE opcode OF
  1413.    4 : WriteString( "FSAVE " );
  1414.    | 5 : WriteString( "FRESTORE " );
  1415.   ELSE
  1416.    WriteString( "illegal coprocessor instruction." );
  1417.   END; (* CASE *)
  1418.   SingleAddressDecode( mode, reg, long );
  1419.  END Format50;
  1420.  PROCEDURE Format51( nr : INTEGER );
  1421.  (* TRAP *)
  1422.  BEGIN (* Format51 *)
  1423.   WriteString( "TRAP #" );
  1424.   WriteInt( nr );
  1425.  END Format51;
  1426.  PROCEDURE CoprocessorDecode( instruction, mode, reg : INTEGER );
  1427.  (* Decodes a coprocessor instruction. *)
  1428.   VAR cpinstruction : INTEGER;
  1429.  BEGIN (* CoprocessorDecode *)
  1430.   IF Getbits( instruction, 11, 9 ) # 1 THEN
  1431.    WriteString( "wrong coprocessor." );
  1432.   ELSE
  1433.    CASE Getbits( instruction, 8, 6 ) OF
  1434.     0 :
  1435.      ReadInt( cpinstruction );
  1436.      IF ( Getbits( cpinstruction, 15, 15 ) = 0 ) & (  Getbits( cpinstruction, 13, 13 ) = 0 ) THEN
  1437.       IF Getbits( cpinstruction, 12, 10 ) = 7 THEN (* FMOVECR *)
  1438.        IF Getbits( instruction, 5, 0 ) = 0 THEN (* FMOVECR *)
  1439.         Format40( Getbits( cpinstruction, 9, 7 ), Getbits( cpinstruction, 6, 0 ) );
  1440.        ELSE
  1441.         WriteString( "illegal coprocessor instruction." );
  1442.        END; (* IF *)
  1443.       ELSE (* normal coprocessor operation *)
  1444.        IF Getbits( cpinstruction, 6, 3 ) = 6 THEN (* FSINCOS *)
  1445.         Format42( mode, reg, Getbits( cpinstruction, 14, 14 ), Getbits( cpinstruction, 12, 10 ),
  1446.             Getbits( cpinstruction, 9, 7 ),  Getbits( cpinstruction, 2, 0 ) );
  1447.        ELSE (* normal coprocessor operation *)
  1448.         Format41( Getbits( cpinstruction, 6, 0 ), mode, reg, Getbits( cpinstruction, 14, 14 ),
  1449.             Getbits( cpinstruction, 12, 10 ), Getbits( cpinstruction, 9, 7 ) );
  1450.        END; (* IF *)
  1451.       END; (* IF *)
  1452.      ELSE (* FMOVE from FPn, FMOVE FPcr, FMOVEM FPn, FMOVEM FPcr *)
  1453.       IF Getbits( cpinstruction, 15, 14 ) = 2 THEN (* FMOVE(M) FPcr *)
  1454.        Format43( mode, reg, Getbits( cpinstruction, 13, 13 ), Getbits( cpinstruction, 12, 10 ) );
  1455.         ELSIF Getbits( cpinstruction, 15, 14 ) = 3 THEN (* FMOVEM FPn *)
  1456.        Format44( mode, reg, Getbits( cpinstruction, 13, 13 ), Getbits( cpinstruction, 11, 11 ),
  1457.            Getbits( cpinstruction, 7, 0 ) );
  1458.       ELSIF Getbits( cpinstruction, 15, 13 ) = 3 THEN (* FMOVE from FPn *)
  1459.        Format45( mode, reg, Getbits( cpinstruction, 9, 7 ), Getbits( cpinstruction, 12, 10 ),
  1460.            Getbits( cpinstruction, 6, 0 ) );
  1461.       ELSE
  1462.        WriteString( "illegal coprocessor instruction." );
  1463.       END; (* IF *)
  1464.      END; (* IF *)
  1465.     | 1 : (* FDBcc, FScc, FTRAPcc *)
  1466.      ReadInt( cpinstruction );
  1467.      CASE mode OF
  1468.       1 : (* FDBcc *)
  1469.        Format46( reg, Getbits( cpinstruction, 5, 0 ) );
  1470.       | 7 : (* FTRAPcc, FScc *)
  1471.        IF reg <= 1 THEN (* FScc *)
  1472.         Format47( mode, reg, Getbits( cpinstruction, 5, 0 ) );
  1473.        ELSE (* FTRAPcc *)
  1474.         Format48( reg, Getbits( cpinstruction, 5, 0 ) );
  1475.        END; (* IF *)
  1476.      ELSE (* FScc *)
  1477.       Format47( mode, reg, Getbits( cpinstruction, 5, 0 ) );
  1478.      END; (* CASE *)
  1479.     | 2 : (* FBcc, FNOP *)
  1480.      IF Getbits( instruction, 5, 0 ) = 0 THEN (* FNOP *)
  1481.       ReadInt( cpinstruction );
  1482.       WriteString( "FNOP" );
  1483.      ELSE (* FBcc *)
  1484.       Format49( 0, Getbits( instruction, 5, 0 ) );
  1485.      END; (* IF *)
  1486.     | 3 : (* FBcc *)
  1487.      Format49( 1, Getbits( instruction, 5, 0 ) );
  1488.     | 4, 5 : (* FSAVE, FRESTORE *)
  1489.      Format50( Getbits( instruction, 8, 6 ), mode, reg );
  1490.     | 6, 7 :
  1491.      WriteString( "illegal coprocessor instruction." );
  1492.    END; (* CASE *)
  1493.   END; (* IF *)
  1494.  END CoprocessorDecode;
  1495.  PROCEDURE DecodeIns( instruction : INTEGER );
  1496.  (* Decodes the given instruction and reads extension words if necessary. *)
  1497.   VAR size, mode, reg, op2 : INTEGER;
  1498.  BEGIN (* DecodeIns *)
  1499.    op2 := Getbits( instruction, 11, 9 );
  1500.    size := Getbits( instruction, 7, 6 );
  1501.    mode := Getbits( instruction, 5, 3 );
  1502.    reg := Getbits( instruction, 2, 0 );
  1503.    CASE Getbits( instruction, 15, 12 ) OF
  1504.     0 : (* ADDI, ANDI, BCHG, BCLR, BSET, BTST, CALLM, CAS, CAS2, CHK2, CMPI, CMP2, EORI, MOVEP, MOVES,
  1505.       ORI, RTM, SUBI *)
  1506.      IF Getbits( instruction, 8, 8) = 0 THEN (* ADDI, ANDI, BCHG, BCLR, BSET, BTST, CALLM, CAS, CAS2, CHK2,
  1507.                      CMPI, CMP2, EORI, MOVES, ORI, RTM, SUBI *)
  1508.       CASE op2 OF
  1509.           0 : (* CHK2.B, CMP2.B, ORI *)
  1510.          IF size = 3 THEN (* CHK2.B, CMP2.B *)
  1511.           Format3( mode, reg, 0 );
  1512.          ELSE (* ORI *)
  1513.           Format1( ORI, mode, reg, size );
  1514.          END; (* IF *)
  1515.        | 1 : (* ANDI, CHK2.W, CMP2.W *)
  1516.          IF size = 3 THEN (* CHK2.W, CMP2.W *)
  1517.           Format3( mode, reg, 1 );
  1518.          ELSE (* ANDI *)
  1519.           Format1( ANDI, mode, reg, size );
  1520.          END; (* IF *)
  1521.        | 2 : (* CHK2.L, CMP2.L, SUBI *)
  1522.          IF size = other THEN (* CHK2.L, CMP2.L *)
  1523.           Format3( mode, reg, 2 );
  1524.          ELSE (* SUBI *)
  1525.           Format1( SUBI, mode, reg, size );
  1526.          END; (* IF *)
  1527.        | 3 : (* ADDI, CALLM, RTM *)
  1528.          IF size = other THEN (* CALLM, RTM *)
  1529.           IF Getbits( instruction, 5, 4 ) = 0 THEN (* RTM *)
  1530.            Format7( Getbits( instruction, 3, 3 ), reg );
  1531.           ELSE (* CALLM *)
  1532.            Format8( mode, reg );
  1533.           END; (* IF *)
  1534.          ELSE (* ADDI *)
  1535.           Format1( ADDI, mode, reg, size );
  1536.          END; (* IF *)
  1537.        | 4 : (* BCHG, BCLR, BSET, BTST *)
  1538.          Format4( Getbits( instruction, 8, 6 ), mode, reg );
  1539.        | 5 : (* CAS.B, EORI *)
  1540.          IF size = other THEN (* CAS.B *)
  1541.           Format5( mode, reg, 1 );
  1542.          ELSE (* EORI *)
  1543.           Format1( EORI, mode, reg, size );
  1544.          END; (* IF *)
  1545.        | 6 : (* CAS.W, CAS2.W, CMPI *)
  1546.          IF size = other THEN (* CAS.W, CAS2.W *)
  1547.           Format5( mode, reg, 2 );
  1548.          ELSE (* CMPI *)
  1549.           Format1( CMPI, mode, reg, size );
  1550.          END; (* IF *)
  1551.        | 7 : (* CAS.L, CAS2.L, MOVES *)
  1552.          IF size = other THEN (* CAS.L, CAS2.L *)
  1553.           Format5( mode, reg, 3 );
  1554.          ELSE (* CMPI *)
  1555.           Format6( mode, reg, size );
  1556.          END; (* IF *)
  1557.       END; (* CASE *)
  1558.      ELSE (* Bit 8 = 1: BCHG, BCLR, BSET, BTST, MOVEP *)
  1559.       IF mode = 1 THEN (* MOVEP *)
  1560.        Format9( op2, Getbits( instruction, 7, 7 ), Getbits( instruction, 6, 6 ), reg );
  1561.       ELSE (* BCHG, BCLR, BSET, BTST *)
  1562.        Format10( size, op2, mode, reg );
  1563.       END; (* IF *)
  1564.      END; (* IF *)
  1565.     | 1, 2, 3 : (* MOVE, MOVEA *)
  1566.      Format11( Getbits( instruction, 13, 12 ), mode, reg, Getbits( instruction, 8, 6 ), op2 );
  1567.     | 4 : (* BKPT, CHK, CLR, DIVS, DIVSL, DIVU, DIVUL, EXT, EXTB, ILLEGAL, JMP, JSR, LEA, LINK, special MOVE,
  1568.        MOVEC, MOVEM, MULS, MULU, NBCD, NEG, NEGX, NOP, NOT, PEA, RESET, RTD, RTE, RTR, RTS, STOP,
  1569.        SWAP, TAS, TRAP, TRAPV, TST, UNLK *)
  1570.      CASE Getbits( instruction, 8, 6 ) OF
  1571.       0 : (* CLR.B, LINK.L, MULS, MULU, NBCD, NEG.B, NEGX.B, NOT.B, TST.B *)
  1572.        CASE op2 OF
  1573.         0, 1, 2, 3, 5 : (* NEGX.B, CLR.B, NEG.B, NOT.B, TST.B *)
  1574.          Format12( op2, 0, mode, reg );
  1575.         | 4 : (* LINK.L, NBCD *)
  1576.          IF Getbits( instruction, 5, 3 ) = 1 THEN (* LINK.L *)
  1577.           Format13( 1, Getbits( instruction, 2, 0 ) );
  1578.          ELSE (* NBCD *)
  1579.           Format14( NBCD, mode, reg );
  1580.          END; (* IF *)
  1581.         | 6 : (* MULS, MULU *)
  1582.          Format29( MUL, mode, reg );
  1583.         | 7 : WriteString( "illegal instruction." );
  1584.        END; (* CASE *)
  1585.       | 1 : (* BKPT, CLR.W, DIVS, DIVSL, DIVU, DIVUL, LINK.W, MOVE USP, MOVEC, NEG.W, NEGX.W, NOP,
  1586.          NOT.W, PEA, RESET, RTD, RTE, RTR, RTS, STOP, SWAP, TRAP, TRAPV, TST.W, UNLK *)
  1587.        CASE op2 OF
  1588.         0, 1, 2, 3, 5 : (* NEGX.W, CLR.W, NEG.W, NOT.W, TST.W *)
  1589.          Format12( op2, 1, mode, reg );
  1590.         | 4 : (* BKPT, PEA, SWAP *)
  1591.          IF Getbits( instruction, 5, 3 ) <= 1 THEN (* SWAP, BKPT *)
  1592.           Format15( mode, reg );
  1593.          ELSE (* PEA *)
  1594.           Format14( PEA, mode, reg );
  1595.          END; (* IF *)
  1596.         | 6 : (* DIVS, DIVSL, DIVU, DIVUL *)
  1597.          Format29( dIV, mode, reg );
  1598.         | 7 : (* LINK.W, MOVE USP, MOVEC, NOP, RESET, RTD, RTE, RTR, RTS, STOP, TRAP, TRAPV, UNLK *)
  1599.          CASE Getbits( instruction, 5, 3 ) OF
  1600.           0, 1 : (* TRAP *)
  1601.            Format51( Getbits( instruction, 3, 0 ) );
  1602.           | 2 : (* LINK.W *)
  1603.            Format13( 0, reg );
  1604.           | 3 : (* UNLK *)
  1605.            Format15( 3, reg );
  1606.           | 4 : (* MOVE to USP *)
  1607.            Format16( reg );
  1608.           | 5 : (* MOVE from USP *)
  1609.            Format15( 4, reg );
  1610.           | 6 : (* NOP, RESET, RTD, RTE, RTR, RTS, STOP, TRAPV *)
  1611.            CASE reg OF
  1612.             0 : WriteString( "RESET" );
  1613.             | 1 : WriteString( "NOP" );
  1614.             | 2 : Format18( STOP );
  1615.             | 3 : WriteString( "RTE" );
  1616.             | 4 : Format18( RTD );
  1617.             | 5 : WriteString( "RTS" );
  1618.             | 6 : WriteString( "TRAPV" );
  1619.             | 7 : WriteString( "RTR" );
  1620.            END; (* CASE *)
  1621.           | 7 : (* MOVEC *)
  1622.            Format17( Getbits( instruction, 0, 0 ) );
  1623.          END; (* CASE *)
  1624.        END; (* CASE *)
  1625.       | 2 : (* CLR.L, EXT.W, JSR, MOVEM.W, NEG.L, NEGX.L, NOT.L, TST.L *)
  1626.        CASE op2 OF
  1627.         0, 1, 2, 3, 5 : (* NEGX.L, CLR.L, NEG.L, NOT.L, TST.L *)
  1628.          Format12( op2, size, mode, reg );
  1629.         | 4 : (* EXT.W, MOVEM.W *)
  1630.          IF mode = 0 THEN (* EXT.W *)
  1631.           Format15( 5, reg );
  1632.          ELSE (* MOVEM.W *)
  1633.           Format19( 0, 0, mode, reg );
  1634.          END; (* IF *)
  1635.         | 6 : (* MOVEM.W *)
  1636.          Format19( 1, 0, mode, reg );
  1637.         | 7 : (* JSR *)
  1638.          Format14( JSR, mode, reg );
  1639.        END; (* CASE *)
  1640.       | 3 : (* EXT.L, ILLEGAL, JMP, MOVE CCR, MOVE SR, MOVEM.L, TAS *)
  1641.        CASE op2 OF
  1642.         0, 1, 2, 3 : (* MOVE CCR, MOVE SR *)
  1643.          Format20( op2, mode, reg );
  1644.         | 4 : (* EXT.L, MOVEM.L *)
  1645.          IF mode = 0 THEN (* EXT.L *)
  1646.           Format15( 6, reg );
  1647.          ELSE (* MOVEM.L *)
  1648.           Format19( 0, 1, mode, reg );
  1649.          END; (* IF *)
  1650.         | 5 : (* ILLEGAL, TAS *)
  1651.          IF Getbits( instruction, 5, 0 ) = 60 THEN (* ILLEGAL *)
  1652.           WriteString( "ILLEGAL" );
  1653.          ELSE (* TAS *)
  1654.           Format14( TAS, mode, reg );
  1655.          END; (* IF *)
  1656.         | 6 : (* MOVEM.L *)
  1657.          Format19( 1, 1, mode, reg );
  1658.         | 7 : (* JMP *)
  1659.          Format14( JMP, mode, reg );
  1660.        END; (* CASE *)
  1661.       | 4 : (* CHK.L *)
  1662.        Format21( 2, op2, mode, reg );
  1663.       | 5 : WriteString( "illegal instruction." );
  1664.       | 6 : (* CHK.W *)
  1665.        Format21( 1, op2, mode, reg );
  1666.       | 7 : (* EXTB.L, LEA *)
  1667.        IF mode = 0 THEN (* EXTB.L *)
  1668.         Format15( 7, reg );
  1669.        ELSE (* LEA *)
  1670.         Format22( op2, mode, reg );
  1671.        END; (* IF *)
  1672.      END; (* CASE *)
  1673.     | 5 : (* ADDQ, DBcc, Scc, SUBQ, TRAPcc *)
  1674.      IF size = other THEN (* DBcc, Scc, TRAPcc *)
  1675.       CASE mode OF
  1676.        1 : (* DBcc *)
  1677.         Format23( Getbits( instruction, 11, 8 ), reg );
  1678.        | 7 : (* Scc, TRAPcc *)
  1679.         IF reg <= 1 THEN (* Scc *)
  1680.          Format24( Getbits( instruction, 11, 8 ), mode, reg );
  1681.         ELSE (* TRAPcc *)
  1682.          Format25( Getbits( instruction, 11, 8 ), reg );
  1683.         END; (* IF *)
  1684.       ELSE (* Scc *)
  1685.        Format24( Getbits( instruction, 11, 8 ), mode, reg );
  1686.       END; (* CASE *)
  1687.      ELSE (* ADDQ, SUBQ *)
  1688.       Format26( Getbits( instruction, 8, 8 ), op2, size, mode, reg );
  1689.      END; (* IF *)
  1690.     | 6 : (* Bcc, BRA, BSR *)
  1691.      Format27( Getbits( instruction, 11, 8 ), Getbits( instruction, 7, 0 ) );
  1692.     | 7 : (* MOVEQ *)
  1693.      Format28( op2, Getbits( instruction, 7, 0 ) );
  1694.     | 8 : (* DIVS, DIVU, OR, PACK, SBCD, UNPK *)
  1695.      CASE Getbits( instruction, 8, 6 ) OF
  1696.       0, 1, 2 : (* OR *)
  1697.         Format31( oR, 0, op2, size, mode, reg );
  1698.       | 3 : (* DIVU *)
  1699.        Format30( dIV, 0, op2, mode, reg );
  1700.       | 4 : (* OR, SBCD *)
  1701.        IF Getbits( instruction, 5, 4 ) = 0 THEN (* SBCD *)
  1702.         Format32( SBCD, 0, Getbits( instruction, 3, 3 ), reg, op2 );
  1703.        ELSE (* OR *)
  1704.         Format31( oR, 1, op2, 0, mode, reg );
  1705.        END; (* IF *)
  1706.       | 5 : (* OR, PACK *)
  1707.        IF Getbits( instruction, 5, 4 ) = 0 THEN (* PACK *)
  1708.         Format33( PACK, Getbits( instruction, 3, 3 ), reg, op2 );
  1709.        ELSE (* OR *)
  1710.         Format31( oR, 1, op2, 1, mode, reg );
  1711.        END; (* IF *)
  1712.       | 6 : (* OR, UNPK *)
  1713.        IF Getbits( instruction, 5, 4 ) = 0 THEN (* UNPK *)
  1714.         Format33( UNPK, Getbits( instruction, 3, 3 ), reg, op2 );
  1715.        ELSE (* OR *)
  1716.         Format31( oR, 1, op2, 2, mode, reg );
  1717.        END; (* IF *)
  1718.       | 7 : (* DIVS *)
  1719.        Format30( dIV, 1, op2, mode, reg );
  1720.      END; (* CASE *)
  1721.     | 9 : (* SUB, SUBA, SUBX *)
  1722.      IF size = 3 THEN (* SUBA *)
  1723.       Format34( SUBA, Getbits( instruction, 8, 8 ), op2, mode, reg );
  1724.      ELSE (* SUB, SUBX *)
  1725.       IF ( Getbits( instruction, 8, 8 ) = 1 ) & ( Getbits( instruction, 5, 4 ) = 0 ) THEN (* SUBX *)
  1726.        Format32( SUBX, size, Getbits( instruction, 3, 3 ), reg, op2 );
  1727.       ELSE (* SUB *)
  1728.        Format31( SUB, Getbits( instruction, 8, 8 ), op2, size, mode, reg );
  1729.       END; (* IF *)
  1730.      END; (* IF *)
  1731.     | 10 : WriteString( "illegal instruction." );
  1732.     | 11 : (* CMP, CMPA, CMPM, EOR *)
  1733.      CASE Getbits( instruction, 8, 6 ) OF
  1734.       0, 1, 2 : (* CMP *)
  1735.        Format31( CMP, 0, op2, size, mode, reg );
  1736.       | 3, 7 : (* CMPA *)
  1737.        Format34( CMPA, Getbits( instruction, 8, 8 ), op2, mode, reg );
  1738.       | 4, 5, 6 : (* CMPM, EOR *)
  1739.        IF Getbits( instruction, 5, 3 ) = 1 THEN (* CMPM *)
  1740.         Format35( size, op2, reg );
  1741.        ELSE (* EOR *)
  1742.         Format31( EOR, 1, op2, size, mode, reg );
  1743.        END; (* IF *)
  1744.      END; (* CASE *)
  1745.     | 12 : (* ABCD, AND, EXG, MULS, MULU *)
  1746.      CASE Getbits( instruction, 8, 6 ) OF
  1747.       0, 1, 2 : (* AND *)
  1748.        Format31( AND, 0, op2, size, mode, reg );
  1749.       | 3 : (* MULU *)
  1750.        Format30( MUL, 0, op2, mode, reg );
  1751.       | 4 : (* ABCD, AND.B *)
  1752.        IF Getbits( instruction, 5, 4 ) = 0 THEN (* ABCD *)
  1753.         Format32( ABCD, 0, Getbits( instruction, 3, 3 ), reg, op2 );
  1754.        ELSE (* AND.B *)
  1755.         Format31( AND, 1, op2, 0, mode, reg );
  1756.        END; (* IF *)
  1757.       | 5 : (* AND.W, EXG *)
  1758.        IF Getbits( instruction, 5, 4 ) = 0 THEN (* EXG *)
  1759.         Format36( Getbits( instruction, 7, 3 ), op2, reg );
  1760.        ELSE (* AND.W *)
  1761.         Format31( AND, 1, op2, 1, mode, reg );
  1762.        END; (* IF *)
  1763.       | 6 : (* AND.L, EXG *)
  1764.        IF Getbits( instruction, 5, 4 ) = 0 THEN (* EXG *)
  1765.         Format36( Getbits( instruction, 7, 3 ), op2, reg );
  1766.        ELSE (* AND.L *)
  1767.         Format31( AND, 1, op2, 2, mode, reg );
  1768.        END; (* IF *)
  1769.       | 7 : (* MULS *)
  1770.        Format30( MUL, 1, op2, mode, reg );
  1771.      END; (* CASE *)
  1772.     | 13 : (* ADD, ADDA, ADDX *)
  1773.      IF size = other THEN (* ADDA *)
  1774.       Format34( ADDA, Getbits( instruction, 8, 8 ), op2, mode, reg );
  1775.      ELSE (* ADD, ADDX *)
  1776.       IF ( Getbits( instruction, 8, 8 ) = 1 ) & ( Getbits( instruction, 5, 4 ) = 0 ) THEN (* ADDX *)
  1777.        Format32( ADDX, size, Getbits( instruction, 3, 3 ), reg, op2 );
  1778.       ELSE (* ADD *)
  1779.        Format31( ADD, Getbits( instruction, 8, 8 ), op2, size, mode, reg );
  1780.       END; (* IF *)
  1781.      END; (* IF *)
  1782.     | 14 : (* ASL, ASR, BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, LSL, LSR, ROL, ROR, ROXL,
  1783.         ROXR *)
  1784.      IF size = other THEN (* bit field operations, memory shifts and rotates *)
  1785.       CASE Getbits( instruction, 11, 8 ) OF
  1786.           0 : (* ASR *) Format14( ASR, mode, reg );
  1787.        | 1 : (* ASL *) Format14( ASL, mode, reg );
  1788.        | 2 : (* LSR *) Format14( LSR, mode, reg );
  1789.        | 3 : (* LSL *) Format14( LSL, mode, reg );
  1790.        | 4 : (* ROXR *) Format14( ROXR, mode, reg );
  1791.        | 5 : (* ROXL *) Format14( ROXL, mode, reg );
  1792.        | 6 : (* ROR *) Format14( ROR, mode, reg );
  1793.        | 7 : (* ROL *) Format14( ROL, mode, reg );
  1794.        | 8 : (* BFTST *) Format37( BFTST, mode, reg );
  1795.        | 9 : (* BFEXTU *) Format38( BFEXTU, mode, reg );
  1796.        | 10 : (* BFCHG *) Format37( BFCHG, mode, reg );
  1797.        | 11 : (* BFEXTS *) Format38( BFEXTS, mode, reg );
  1798.        | 12 : (* BFCLR *) Format37( BFCLR, mode, reg );
  1799.        | 13 : (* BFFFO *) Format38( BFFFO,  mode, reg);
  1800.        | 14 : (* BFSET *) Format37( BFSET, mode, reg );
  1801.        | 15 : (* BFINS *) Format2( mode, reg );
  1802.       END; (* CASE *)
  1803.      ELSE (* register shifts and rotates *)
  1804.       Format39( Getbits( instruction, 4, 3 ), op2, Getbits( instruction, 8, 8 ), size,
  1805.           Getbits( instruction, 5, 5 ), reg );
  1806.      END; (* IF *)
  1807.     | 15 : (* coprocessor *)
  1808.      CoprocessorDecode( instruction, mode, reg );
  1809.    END; (* CASE *)
  1810.  END DecodeIns;
  1811.  PROCEDURE ReadHeader( VAR entries, commands, pointers, imports : INTEGER;
  1812.             VAR constSize, codeSize, refLen : LONGINT; VAR error : BOOLEAN );
  1813.  (* Reads the header block and writes the information to the output. *)
  1814.   VAR ch : CHAR;
  1815.     link : INTEGER;
  1816.     modName : ARRAY 24 OF CHAR;
  1817.     key, dsize, refPos : LONGINT;
  1818.  BEGIN (* ReadHeader *)
  1819.   Read( ch );
  1820.   IF ch # 0F1X THEN
  1821.    WriteString( "No object file." );
  1822.    error := TRUE;
  1823.   ELSE
  1824.    Read( ch );
  1825.    ReadLongint( refPos );
  1826.    ReadLongint( refLen );
  1827.    ReadInt( entries );
  1828.    ReadInt( commands );
  1829.    ReadInt( pointers );
  1830.    ReadInt( imports );
  1831.    ReadInt( link );
  1832.    ReadLongint( dsize );
  1833.    ReadLongint( constSize );
  1834.    ReadLongint( codeSize );
  1835.    ReadLongint( key );
  1836.    ReadString( modName, 24 );
  1837.    WriteString( "Module: " );
  1838.    WriteString( modName );
  1839.    WriteLn;
  1840.    WriteString( "Key: " );
  1841.    WriteInt( key );
  1842.    WriteLn; WriteLn;
  1843.    WriteString( "Link: " );
  1844.    WriteInt( link );
  1845.    WriteLn; WriteLn;
  1846.    WriteString( "Data size: " );
  1847.    WriteInt( dsize );
  1848.    WriteLn; WriteLn;
  1849.    Texts.Append( output, writer.buf );
  1850.   END; (* IF *)
  1851.  END ReadHeader;
  1852.  PROCEDURE ReadEntries( entries : INTEGER; VAR error : BOOLEAN );
  1853.  (* Reads the enties from the file and writes them to the output. *)
  1854.   VAR i : INTEGER;
  1855.     ch : CHAR;
  1856.     entry : LONGINT;
  1857.  BEGIN (* ReadEntries *)
  1858.   IF ~ error THEN
  1859.    WriteString( "Entries: " );
  1860.    Read( ch );
  1861.    IF ch # 82X THEN
  1862.     WriteString( BlockMisaligned );
  1863.     WriteLn;
  1864.     error := TRUE;
  1865.    ELSE
  1866.     WriteInt( entries );
  1867.     WriteLn;
  1868.     FOR i := 0 TO entries - 1 DO
  1869.      ReadLongint( entry );
  1870.      WriteInt( entry );
  1871.      WriteLn;
  1872.     END; (* FOR *)
  1873.     WriteLn;
  1874.    END; (* IF *)
  1875.   END; (* IF *)
  1876.   Texts.Append( output, writer.buf );
  1877.  END ReadEntries;
  1878.  PROCEDURE ReadCommands( commands : INTEGER; VAR error : BOOLEAN );
  1879.  (* Reads the commands from the file and writes them to the output. *)
  1880.   VAR i : INTEGER;
  1881.     ch : CHAR;
  1882.     name : ARRAY 100 OF CHAR;
  1883.     entry : LONGINT;
  1884.  BEGIN (* ReadCommands *)
  1885.   IF ~ error THEN
  1886.    WriteString( "Commands: " );
  1887.    Read( ch );
  1888.    IF ch # 83X THEN
  1889.     WriteString( BlockMisaligned );
  1890.     WriteLn;
  1891.     error := TRUE;
  1892.    ELSE
  1893.     WriteInt( commands );
  1894.     WriteLn;
  1895.     FOR i := 0 TO commands - 1 DO
  1896.      ReadString( name, 0 );
  1897.      WriteString( name );
  1898.      WriteString( ": " );
  1899.      ReadLongint( entry );
  1900.      WriteInt( entry );
  1901.      WriteLn;
  1902.     END; (* FOR *)
  1903.     WriteLn;
  1904.    END; (* IF *)
  1905.   END; (* IF *)
  1906.   Texts.Append( output, writer.buf );
  1907.  END ReadCommands;
  1908.  PROCEDURE ReadPointers( pointers : INTEGER; VAR error : BOOLEAN );
  1909.  (* Reads the global pointers from the file and writes them to the output. *)
  1910.   VAR i : INTEGER;
  1911.     ch : CHAR;
  1912.     adr : LONGINT;
  1913.  BEGIN (* ReadPointers *)
  1914.   IF ~ error THEN
  1915.    WriteString( "Pointers: " );
  1916.    Read( ch );
  1917.    IF ch # 84X THEN
  1918.     WriteString( BlockMisaligned );
  1919.     WriteLn;
  1920.     error := TRUE;
  1921.    ELSE
  1922.     WriteInt( pointers );
  1923.     WriteLn;
  1924.     FOR i := 0 TO pointers - 1 DO
  1925.      ReadLongint( adr );
  1926.      WriteInt( adr );
  1927.      WriteLn;
  1928.     END; (* FOR *)
  1929.     WriteLn;
  1930.    END; (* IF *)
  1931.   END; (* IF *)
  1932.   Texts.Append( output, writer.buf );
  1933.  END ReadPointers;
  1934.  PROCEDURE ReadImports( imports : INTEGER; VAR error : BOOLEAN );
  1935.  (* Reads the imports from the file and writes them to the output. *)
  1936.   VAR i : INTEGER;
  1937.     ch : CHAR;
  1938.     name : ARRAY 30 OF CHAR;
  1939.     adr : LONGINT;
  1940.  BEGIN (* ReadImports *)
  1941.   IF ~ error THEN
  1942.    WriteString( "Imports: " );
  1943.    Read( ch );
  1944.    IF ch # 85X THEN
  1945.     WriteString( BlockMisaligned );
  1946.     WriteLn;
  1947.     error := TRUE;
  1948.    ELSE
  1949.     WriteInt( imports );
  1950.     WriteLn;
  1951.     FOR i := 0 TO imports - 1 DO
  1952.      ReadLongint( adr );
  1953.      ReadString( name, 0 );
  1954.      WriteString( name );
  1955.      WriteString( ": " );
  1956.      WriteInt( adr );
  1957.      WriteLn;
  1958.     END; (* FOR *)
  1959.     WriteLn;
  1960.    END; (* IF *)
  1961.   END; (* IF *)
  1962.   Texts.Append( output, writer.buf );
  1963.  END ReadImports;
  1964.  PROCEDURE ReadConst( size : LONGINT; VAR error : BOOLEAN );
  1965.  (* Reads the constants from the file and writes them in decimal format to the output. *)
  1966.   VAR i : LONGINT;
  1967.     ch : CHAR;
  1968.  BEGIN (* ReadConst *)
  1969.   IF ~ error THEN
  1970.    WriteString( "Constants: " );
  1971.    Read( ch );
  1972.    IF ch # 86X THEN
  1973.     WriteString( BlockMisaligned );
  1974.     WriteLn;
  1975.     error := TRUE;
  1976.    ELSE
  1977.     WriteInt( size );
  1978.     WriteLn;
  1979.     FOR i := 0 TO size - 1 DO
  1980.      Read( ch );
  1981.      WriteInt( ORD( ch ) );
  1982.      Write( " " );
  1983.      IF i MOD 20 = 19 THEN WriteLn; END;
  1984.     END; (* FOR *)
  1985.     WriteLn;
  1986.     WriteLn;
  1987.    END; (* IF *)
  1988.   END; (* IF *)
  1989.   Texts.Append( output, writer.buf );
  1990.  END ReadConst;
  1991.  PROCEDURE ReadCode( size : LONGINT; VAR error : BOOLEAN );
  1992.  (* Reads the code from the file and decodes it to the output. *)
  1993.   VAR ch : CHAR;
  1994.     instruction : INTEGER;
  1995.  BEGIN (* ReadCode *)
  1996.   IF ~ error THEN
  1997.    WriteString( "Code: " );
  1998.    Read( ch );
  1999.    IF ch # 87X THEN
  2000.     WriteString( BlockMisaligned );
  2001.     WriteLn;
  2002.     error := TRUE;
  2003.    ELSE
  2004.     WriteInt( size );
  2005.     WriteLn;
  2006.     pc := 0;
  2007.     REPEAT
  2008.      WriteInt( pc );
  2009.      WriteString( "    " );
  2010.      ReadInt( instruction );
  2011.      DecodeIns( instruction );
  2012.      WriteLn;
  2013.      Texts.Append( output, writer.buf );
  2014.     UNTIL pc >= size;
  2015.     WriteLn;
  2016.    END; (* IF *)
  2017.   END; (* IF *)
  2018.   Texts.Append( output, writer.buf );
  2019.  END ReadCode;
  2020.  PROCEDURE ReadRef( VAR error : BOOLEAN );
  2021.  (* Reads the reference information from the file. *)
  2022.   VAR adr : LONGINT;
  2023.     ch : CHAR;
  2024.     name : ARRAY 256 OF CHAR;
  2025.  BEGIN (* ReadRef *)
  2026.   IF ~ error THEN
  2027.    WriteString( "References: " );
  2028.    Read( ch );
  2029.    IF ch # 88X THEN
  2030.     WriteString( BlockMisaligned );
  2031.     WriteLn;
  2032.     error := TRUE;
  2033.    ELSE
  2034.     WriteLn;
  2035.     Read( ch );
  2036.     ReadDynint( adr );
  2037.     WHILE ~rider.eof DO
  2038.      WriteString( "Procedure: " );
  2039.      ReadString( name, 0 );
  2040.      WriteString( name );
  2041.      WriteString( "    " );
  2042.      WriteInt( adr );
  2043.      WriteLn;
  2044.      Read( ch );
  2045.      WHILE ( ~rider.eof ) & ( ch # 0F8X ) DO
  2046.       IF ch = 1X THEN WriteString( "    Variable: " );
  2047.       ELSE WriteString( "    Var-Parameter: " );
  2048.       END;
  2049.       Read( ch );
  2050.       ReadDynint( adr );
  2051.       ReadString( name, 0 );
  2052.       WriteString( name );
  2053.       WriteType( ch );
  2054.       WriteInt( adr );
  2055.       WriteLn;
  2056.       Read( ch );
  2057.      END; (* WHILE *)
  2058.      ReadDynint( adr );
  2059.     END; (* WHILE *)
  2060.    END; (* IF *)
  2061.   END; (* IF *)
  2062.   Texts.Append( output, writer.buf );
  2063.  END ReadRef;
  2064.  PROCEDURE Decode*;
  2065.  (* Translates the code in the file after the call into a viewer. *)
  2066.   VAR vx, vy : INTEGER;
  2067.     entries, commands, pointers, imports : INTEGER;
  2068.     constSize, codeSize, refLen : LONGINT;
  2069.     error : BOOLEAN;
  2070.     beg, end, time: LONGINT;
  2071.     text : Texts.Text;
  2072.  BEGIN (* Disassemble *)
  2073.   Texts.OpenScanner( scanner, Oberon.Par.text, Oberon.Par.pos );
  2074.   Texts.Scan( scanner );
  2075.   IF ( scanner.class = Texts.Char ) & ( scanner.c = "^" ) OR ( scanner.line # 0 ) THEN
  2076.    Oberon.GetSelection( text, beg, end, time );
  2077.    IF time >= 0 THEN Texts.OpenScanner( scanner, text, beg ); Texts.Scan( scanner ) END
  2078.   END;
  2079.   IF scanner.class = Texts.Name THEN
  2080.    file := Files.Old( scanner.s );
  2081.    IF file = NIL THEN
  2082.     Texts.OpenWriter( writer );
  2083.     Texts.WriteString( writer, "File not found: '" );
  2084.     Texts.WriteString( writer, scanner.s );
  2085.     Texts.Write( writer, "'" );
  2086.     Texts.WriteLn( writer );
  2087.     Texts.Append( Oberon.Log, writer.buf );
  2088.    ELSE
  2089.     Files.Set( rider, file, 0 );
  2090.     NEW( output );
  2091.     Texts.Open( output, "" );
  2092.     output.notify := TextFrames.NotifyDisplay;
  2093.     frame := TextFrames.NewText( output, 0 );
  2094.     Oberon.AllocateUserViewer( Oberon.Par.vwr.X, vx, vy );
  2095.     NEW( viewer );
  2096.     viewer := MenuViewers.New( TextFrames.NewMenu( "AsmCode",
  2097.         "System.Close System.Copy System.Grow Edit.Search Edit.Store" ), frame, TextFrames.menuH, vx, vy );
  2098.     Texts.OpenWriter( writer );
  2099.     error := FALSE;
  2100.     ReadHeader( entries, commands, pointers, imports, constSize, codeSize, refLen, error );
  2101.     ReadEntries( entries, error );
  2102.     ReadCommands( commands, error );
  2103.     ReadPointers( pointers, error );
  2104.     ReadImports( imports, error );
  2105.     ReadConst( constSize, error );
  2106.     ReadCode( codeSize, error );
  2107.     ReadRef( error );
  2108.    END; (* IF *)
  2109.   END; (* IF *)
  2110.  END Decode;
  2111. END Decoder.
  2112.