home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1988 / 01 / disz80.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-10-12  |  23.6 KB  |  478 lines

  1. (* ----------------------------------------------------------------------- *)
  2. (*                                 DISZ80.PAS                              *)
  3. (* Version: 1.0,  Autor: Born B.,  Prog. Spr.: Turbo Pascal V3.x,          *)
  4. (* Betr. Sys.:  MSDOS, CP/M 80, CP/M 86                                    *)
  5. (* Baumorientierter Disassembler fuer den Z80 Prozessor.Der Hauptspeicher- *)
  6. (* bereich zwischen Startadresse und Endadresse wird disassembliert und    *)
  7. (* auf der Standardausgabe ausgegeben. Start- und Endadresse werden ent-   *)
  8. (* weder als Dezimal- oder als Hexadezimalzahl ($xxxx) ueber die Standard- *)
  9. (* eingabe eingegeben.                                                     *)
  10. (* Implementierungshinweis:                                                *)
  11. (* Der Typ Integer ist in Turbo Pascal als 2 Byte mit Vorzeichen imple-    *)
  12. (* mentiert. Ganzzahlen > 32767 werden als negativ aufgefasst. Deshalb     *)
  13. (* sind alle Operationen auf 16 Bit Werte unter diesem Aspekt vorzunehmen. *)
  14. PROGRAM DisasmZ80 (Input,Output);
  15. CONST
  16.   Bytelen = 1;  Wordlen = 2;
  17.   Condition : ARRAY [0..7] OF STRING [2]
  18.                = ('NZ','Z ','NC','C ','PO','PE','P ','M ');
  19.   Register1 : ARRAY [0..7] OF STRING [1] = ('B','C','D','E','H','L',' ','A');
  20.   Register2 : ARRAY [0..7] OF STRING [4]
  21.                = ('B   ','C   ','D   ','E   ','H   ','L   ','(HL)','A   ');
  22.   Register3 : ARRAY [0..3] OF STRING [2] = ('BC','DE','HL','SP');
  23.   Register4 : ARRAY [0..3] OF STRING [2] = ('BC','DE','HL','AF');
  24.   Befehl1 : ARRAY [0..7] OF STRING [3]
  25.                = ('ADD','ADC','SUB','SBC','AND','XOR','OR ','CP ');
  26.   Befehl2 : ARRAY [0..7] OF STRING [4]
  27.                = ('RLCA','RRCA','RLA ','RRA ','DAA ','CPL ','SCF ','CCF ');
  28. TYPE
  29.   bitfield = ARRAY [1..3] OF INTEGER;
  30. VAR
  31.   Startadr, Endadr, Currentadr,
  32.   Column, Opcode, SecOpcode,
  33.   Thirdopcode, k              : INTEGER;
  34.   Bitfeld                     : bitfield;
  35. (* ----------------------------------------------------------------------- *)
  36. (* Ausgabe eines Wertes als Hexzahl auf der Standardausgabe. Durch "len"   *)
  37. (* wird festgelegt, ob ein Byte (len = 1) oder Worte (len = 2) ausgegeben  *)
  38. (* werden sollen.                                                          *)
  39. PROCEDURE WriteHex (len, value : INTEGER);
  40. CONST HexZif : ARRAY [0..15] OF CHAR = '0123456789ABCDEF';
  41. VAR  temp, i : INTEGER;
  42. BEGIN
  43.   FOR i := len DOWNTO 1 DO BEGIN                        (* 1 oder 2 bytes  *)
  44.     IF i = 2 THEN temp := Swap(value) AND $0FF          (* high byte holen *)
  45.     ELSE temp := value AND $0FF;                        (* low byte holen  *)
  46.     Write(HexZif[temp DIV 16]:1,HexZif[temp MOD 16]:1);
  47.   END;
  48. END;
  49. (* ----------------------------------------------------------------------- *)
  50. (* Lese 1 oder 2 Bytes aus dem Speicher ab "adr" und gebe das Ergebnis an  *)
  51. (* "GetVal" zurueck. Die gelesenen Bytes werden als Hexziffern auf der     *)
  52. (* Standardausgabe angezeigt. Fuer CP/M 80 muss der Zugriff auf den Spei-  *)
  53. (* cher mit "Mem[adr]" erfolgen, die Spezifizierung des Segments kann ent- *)
  54. (* fallen. Fuer die 8088 etc. ist dagegen das Segment anzugeben.           *)
  55. FUNCTION GetVal (VAR adr : INTEGER; len : INTEGER) : INTEGER;
  56. VAR temp : INTEGER;
  57. BEGIN
  58.   temp := Mem[0:adr];                                     (* lese low Byte *)
  59.   WriteHex(1,temp);  Write (' ');   adr := Succ(adr);     (* Hex Ausgabe   *)
  60.   IF len = 2 THEN BEGIN                                   (* Wort einlesen *)
  61.     temp := temp OR 256 * Mem[0:adr];
  62.     WriteHex (1,Mem[0:adr]);  Write (' ');                (* Hex Ausgabe   *)
  63.     adr := Succ(adr);
  64.   END;
  65.   GetVal := temp;
  66. END;
  67. (* ----------------------------------------------------------------------- *)
  68. (* vergleiche, ob Wert1 < Wert2 ist, beachte die Implementierung des Typs  *)
  69. (* Integer in Turbo Pascal                                                 *)
  70. FUNCTION Greather (Wert1,Wert2 : INTEGER) : BOOLEAN;
  71. BEGIN
  72.   IF Hi(Wert1) < Hi(Wert2) THEN Greather := TRUE       (* high Byte vergl. *)
  73.   ELSE IF Lo(Wert1) < Lo(Wert2) THEN Greather := TRUE  (* low Byte vergl.  *)
  74.   ELSE  Greather := FALSE;
  75. END;
  76. (* ----------------------------------------------------------------------- *)
  77. (* decodiere das Opcodebyte in einzelne Bitfelder. Die Ergebnisbits werden *)
  78. (* rechtsbuendig geschoben:                                                *)
  79. (* Bit(1) = bbxx xxxx, Bit(2) = xxbb bxxx, Bit(3) = xxxx xbbb              *)
  80. PROCEDURE Decode (VAR Bitfeld : bitfield; Opcode : INTEGER);
  81. BEGIN
  82.   Bitfeld [1] := Opcode DIV 64;
  83.   Bitfeld [2] := (Opcode AND $38) DIV 8;
  84.   Bitfeld [3] := Opcode AND $07;
  85. END;
  86. (* ----------------------------------------------------------------------- *)
  87. (* Modul zur Implementierung der erweiterten Opcodes: CB xx xx             *)
  88. PROCEDURE ExtendCB;
  89. CONST
  90.   Befehl3 : ARRAY [0..7] OF STRING [3]
  91.               = ('RLC','RRC','RL ','RR ','SLA','SRA','***','SRL');
  92.   Befehl4 : ARRAY [1..3] OF STRING [3]
  93.               = ('BIT','RES','SET');
  94. BEGIN
  95.   Opcode := GetVal (Currentadr,Bytelen);              (* lese 2. Opcode    *)
  96.   Decode (Bitfeld,Opcode);                            (* decode Bitsfelder *)
  97.   Write ('        ');
  98.   IF Bitfeld[1] = 0 THEN
  99.     BEGIN
  100.       IF Bitfeld[2] <> 6 THEN
  101.         Write (Befehl3[Bitfeld[2]],'  ',Register2[Bitfeld[3]]);
  102.     END
  103.   ELSE
  104.     Write (Befehl4[Bitfeld[1]],'  ',Bitfeld[2]:1,',',Register2[Bitfeld[3]]);
  105. END;
  106. (* ----------------------------------------------------------------------- *)
  107. (* Modul zur Implementierung der erweiterten Opcodes: ED                   *)
  108. PROCEDURE ExtendED;
  109. CONST
  110.   Befehl5 : ARRAY [0..7] OF STRING [8]
  111.              = ('LD   I,A','LD   R,A','LD   A,I','LD   A,R ',
  112.                 'RRD     ','RLD     ','********','********');
  113.   Befehl6 : ARRAY [0..3,4..7] OF STRING [4]
  114.              = (('LDI ','LDD ','LDIR','LDDR'),('CPI ','CPD ','CPIR','CPDR'),
  115.                 ('INI ','IND ','INIR','INDR'),('OUTI','OUTD','OTIR','OTDR'));
  116. BEGIN
  117.   Opcode := GetVal (Currentadr,Bytelen);              (* lese 2. Opcode    *)
  118.   Decode (Bitfeld,Opcode);                            (* decode bits       *)
  119.   IF Bitfeld[1] = 1 THEN                              (* 01 xxx xxx        *)
  120.     CASE Bitfeld [3] OF
  121.       0: IF Bitfeld [2] <> 6 THEN                 (* 01 xxx 000: IN  r,(C) *)
  122.            Write ('        ','IN   ',Register1[Bitfeld[2]],',(C)');
  123.       1: IF Bitfeld [2] <> 6 THEN                 (* 01 xxx 001: OUT (C),r *)
  124.            Write ('        ','OUT  (C),',Register1[Bitfeld[2]]);
  125.       2: IF Odd(Bitfeld [2]) THEN            (* 01 xxx 010: SBC HL,rp, ... *)
  126.            Write ('        ','ADC  HL,',Register3[Bitfeld[2] DIV 2])
  127.          ELSE
  128.            Write ('        ','SBC  HL,',Register3[Bitfeld[2] DIV 2]);
  129.       3: IF (Bitfeld [2] DIV 2) <> 2 THEN    (* 01 xxx 011: LD (NN),rp,... *)
  130.          BEGIN
  131.            SecOpcode := GetVal (Currentadr,Wordlen);  Write ('  ');
  132.            IF Odd (Bitfeld[2]) THEN
  133.              BEGIN
  134.                Write ('LD   ',Register3[Bitfeld[2] DIV 2],',(');
  135.                WriteHex (Wordlen,SecOpcode);  Write (')');
  136.              END
  137.            ELSE
  138.              BEGIN
  139.                Write ('LD   (');  WriteHex (Wordlen,SecOpcode);
  140.                Write ('),',Register3[Bitfeld[2] DIV 2]);
  141.              END;
  142.          END;
  143.       4: IF Bitfeld [2] = 0 THEN                 (* 01 xxx 100: NEG        *)
  144.            Write ('        ','NEG');
  145.       5: IF Bitfeld [2] = 0 THEN                 (* 01 xxx 101: RETN, RETI *)
  146.            Write ('        ','RETN')
  147.          ELSE IF Bitfeld [2] = 1 THEN
  148.            Write ('        ','RETI');
  149.       6: IF Bitfeld [2] IN [0,2,3] THEN          (* 01 xxx 110: IM0 .. IM2 *)
  150.            CASE Bitfeld [2] OF
  151.              0: Write ('        ','IM0');
  152.              2: Write ('        ','IM1');
  153.              3: Write ('        ','IM2');
  154.            END;
  155.       7: IF Bitfeld[2] < 6 THEN                  (* 01 xxx 1110: LD I,A .. *)
  156.            Write ('        ',Befehl5[Bitfeld[2]]);
  157.     END (* CASE *)
  158.   ELSE IF Bitfeld [1] = 2 THEN                              (* 10 xxx xxx: *)
  159.     IF (Bitfeld[3] IN [0..3]) AND (Bitfeld[2] IN [4..7]) THEN    (* LDI .. *)
  160.       Write ('        ', Befehl6[Bitfeld[3],Bitfeld[2]]);
  161. END;
  162. (* ----------------------------------------------------------------------- *)
  163. (* Modul zur Implementierung der erweiterten Opcodes: DD und FD            *)
  164. PROCEDURE Extendxx;
  165. VAR Praefix : STRING [2];
  166. BEGIN
  167.   IF Opcode = $DD THEN Praefix := 'IX'                (* setze Indexreg.   *)
  168.   ELSE Praefix := 'IY';
  169.   Opcode := GetVal (Currentadr,Bytelen);              (* lese 2. Opcode    *)
  170.   Decode (Bitfeld,Opcode);                            (* decode bits       *)
  171.   IF Opcode = $CB THEN
  172.     BEGIN                                             (* xD CB dd OP       *)
  173.       SecOpcode := GetVal (Currentadr,Bytelen);       (* hole dd           *)
  174.       Opcode := GetVal (Currentadr,Bytelen);          (* hole OP           *)
  175.       Decode (Bitfeld,Opcode);                        (* decodiere bits    *)
  176.       IF Bitfeld[3] = 6 THEN BEGIN
  177.         CASE Bitfeld[1] OF
  178.           0: BEGIN
  179.                Write ('  ');
  180.                CASE Bitfeld[2] OF
  181.                  0: Write ('RLC  ');     1: Write ('RRC  ');
  182.                  2: Write ('RL   ');     3: Write ('RR   ');
  183.                  4: Write ('SLA  ');     5: Write ('SRA  ');
  184.                  6: Exit;                7: Write ('SRL  ');
  185.                END;
  186.              END;
  187.           1: Write ('BIT  ',Bitfeld[2],',');
  188.           2: Write ('SET  ',Bitfeld[2],',');
  189.           3: Write ('RES  ',Bitfeld[2],',');
  190.         END;
  191.         Write ('(',Praefix,'+');
  192.         WriteHex (Bytelen,SecOpcode);  Write (')');   (* displ. dd         *)
  193.       END;
  194.     END
  195.   ELSE
  196.     CASE Bitfeld[1] OF
  197.       0: IF Bitfeld[3] IN [1..6] THEN
  198.            CASE Bitfeld[3] OF
  199.              1: BEGIN
  200.                   IF Bitfeld[2] = 4 THEN           (* 00 100 001: LD IX,nn *)
  201.                     BEGIN
  202.                       SecOpcode := GetVal (Currentadr,Wordlen);
  203.                       Write ('   ','LD   ',Praefix,',');
  204.                       WriteHex (Wordlen,SecOpcode);
  205.                     END
  206.                   ELSE IF Odd(Bitfeld[2]) THEN    (* 00 pp1 001: ADD IX,pp *)
  207.                     IF (Bitfeld[2] DIV 2) = 2 THEN
  208.                       Write ('          ','ADD  ',Praefix,',',Praefix)
  209.                     ELSE
  210.                       Write ('          ','ADD  ',Praefix,',',
  211.                   Register3[Bitfeld[2] DIV 2]);
  212.                 END;
  213.              2: IF Bitfeld[2] IN [4,5] THEN BEGIN
  214.                   SecOpcode := GetVal (Currentadr,Wordlen);
  215.                   IF Bitfeld[2] = 4 THEN
  216.                     BEGIN
  217.                       Write ('   ','LD   (');
  218.                       WriteHex (Wordlen,SecOpcode);  Write ('),',Praefix);
  219.                     END
  220.                   ELSE
  221.                     BEGIN
  222.                       Write ('   ','LD   ',Praefix,'(');
  223.                       WriteHex (Wordlen,SecOpcode);  Write (')');
  224.                     END;
  225.                 END;
  226.              3: IF Bitfeld[2] = 4 THEN Write ('         INC  ',Praefix)
  227.                 ELSE IF Bitfeld[2] = 5 THEN Write ('         DEC  ',Praefix);
  228.              4: IF Bitfeld[2] = 6 THEN BEGIN
  229.                   SecOpcode := GetVal (Currentadr,Bytelen);
  230.                   Write ('       INC  (',Praefix,'+');
  231.                   WriteHex (Bytelen,SecOpcode);  Write (')');
  232.                 END;
  233.              5: IF Bitfeld[2] = 6 THEN BEGIN
  234.                   SecOpcode := GetVal (Currentadr,Bytelen);
  235.                   Write ('       DEC  (',Praefix,'+');
  236.                   WriteHex (Bytelen,SecOpcode);  Write (')');
  237.                 END;
  238.              6: IF Bitfeld[2] = 6 THEN BEGIN
  239.                   SecOpcode := GetVal (Currentadr,Bytelen);
  240.                   Thirdopcode := GetVal (Currentadr,Bytelen);
  241.                   Write ('   LD   (',Praefix,'+');
  242.                   WriteHex (Bytelen,SecOpcode);  Write ('),');
  243.                   WriteHex (Bytelen,Thirdopcode);
  244.                 END;
  245.            END; (* CASE *)
  246.       1: IF (Bitfeld [3] = 6) AND (Bitfeld[2] <> 6) THEN    (* LD r,(IX+d) *)
  247.            BEGIN
  248.              SecOpcode := GetVal (Currentadr,Bytelen);
  249.              Write ('     LD   ',Register1[Bitfeld[2]],',(',Praefix,'+');
  250.              WriteHex (Bytelen,SecOpcode);  Write (')');
  251.            END
  252.          ELSE
  253.            IF (Bitfeld [3] <> 6) AND (Bitfeld[2] = 6) THEN  (* LD (IX+d),r *)
  254.            BEGIN
  255.              SecOpcode := GetVal (Currentadr,Bytelen);
  256.              Write ('     LD   (',Praefix,'+');
  257.              WriteHex (Bytelen,SecOpcode);
  258.              Write (')',',',Register1[Bitfeld[3]]);
  259.            END;
  260.         2: IF Bitfeld[3] = 6 THEN BEGIN       (* 10 000 110: ADD  A,(IX+d) *)
  261.              SecOpcode := GetVal (Currentadr,Bytelen);
  262.              Write ('       ', Befehl1[Bitfeld[2]],'  ');
  263.              IF Bitfeld[2] IN [0,1,3] THEN Write ('A,');
  264.              Write('(',Praefix,'+'); WriteHex(Bytelen,SecOpcode); Write(')');
  265.            END;
  266.         3: IF Bitfeld[3] IN [1,3,5] THEN
  267.              CASE Bitfeld[3] OF
  268.                1: IF Bitfeld[2] IN [4,5,7] THEN
  269.                     CASE Bitfeld[2] OF
  270.                       4: Write ('        POP  ',Praefix);
  271.                       5: Write ('        JP   (',Praefix,')');
  272.                       7: Write ('        LD   SP,',Praefix);
  273.                     END;
  274.                 3: IF Bitfeld[2] = 4 THEN
  275.                      Write ('        EX   (SP),',Praefix);
  276.                 5: IF Bitfeld[2] = 4 THEN
  277.                      Write ('        PUSH ',Praefix);
  278.              END;
  279.     END;
  280. END;
  281. (* ----------------------------------------------------------------------- *)
  282. (* Modul zur Implementierung der Opcodes 00 xxx xxx. Der Opcode wird nach  *)
  283. (* 7 Untergruppen entschluesselt -> 00 xxx bbb.   bbb = Bitfeld [3]        *)
  284. PROCEDURE Gruppe00;
  285. BEGIN
  286.   CASE Bitfeld [3] OF      (* Untergruppe 00 xxx 000 -> NOP, EX AF,AF' und *)
  287.     0: BEGIN               (* relative Spruenge DJNZ, JR, JRNZ, JRZ, ...   *)
  288.          IF Bitfeld [2] < 2 THEN
  289.            CASE Bitfeld [2] OF
  290.              0: Write ('           NOP');
  291.              1: Write ('           EX   AF,AF''');
  292.            END
  293.          ELSE                                    (* relative Sprungbefehle *)
  294.            BEGIN
  295.              SecOpcode := GetVal(Currentadr,Bytelen); (* lese Displacement *)
  296.              Write ('        ');
  297.              CASE Bitfeld [2] OF
  298.                2: Write ('DJNZ ');         3: Write ('JR   ');
  299.                4: Write ('JR   NZ,');      5: Write ('JR   Z,');
  300.                6: Write ('JR   NC,');      7: Write ('JR   C,');
  301.              END;
  302.              IF SecOpcode > 127 THEN             (* korrektes Displacement *)
  303.                WriteHex (Wordlen,(Currentadr - (256 - SecOpcode)))
  304.              ELSE                                (* ausgeben               *)
  305.                WriteHex (Wordlen,(Currentadr + SecOpcode));
  306.            END;
  307.        END;
  308.                                  (* Untergruppe 00 xxx 001    xxx = rpb    *)
  309.                                  (* b = 1 -> ADD HL,rp   b = 0 -> LD rp,NN *)
  310.     1: IF Odd(Bitfeld [2]) THEN
  311.          Write ('           ','ADD  HL,',Register3[Bitfeld [2] DIV 2])
  312.        ELSE
  313.          BEGIN
  314.            SecOpcode := GetVal (Currentadr,Wordlen);   (* lese Word        *)
  315.            Write ('     ','LD   ',Register3[Bitfeld[2] DIV 2],',');
  316.            WriteHex (Wordlen,SecOpcode);
  317.          END;
  318.                       (* Untergruppe 00 xxx 010                            *)
  319.                       (* xxx = 101 -> LD HL,(NN)   xxx = 100 -> LD (NN),HL *)
  320.                       (* xxx = rp0 -> LD (rp),A    xxx = rp0 -> LD A,(rp)  *)
  321.     2: IF Bitfeld [2] IN [4..7] THEN
  322.          BEGIN
  323.            SecOpcode := GetVal (Currentadr,Wordlen);   (* lese Word        *)
  324.            CASE Bitfeld[2] OF
  325.              4: BEGIN
  326.                   Write ('     ','LD   (');            (* LD  (NN),HL      *)
  327.                   WriteHex (Wordlen,SecOpcode);  Write ('),HL');
  328.                 END;
  329.              5: BEGIN
  330.                   Write ('     ','LD   HL,(');         (* LD  HL,(NN)      *)
  331.                   WriteHex (Wordlen,SecOpcode);  Write (')');
  332.                 END;
  333.              6: BEGIN
  334.                   Write ('     ','LD   (');            (* LD  (NN),A       *)
  335.                   WriteHex (Wordlen,SecOpcode);  Write ('),A');
  336.                 END;
  337.              7: BEGIN
  338.                   Write ('     ','LD   A,(');         (* LD   A,(NN)       *)
  339.                   WriteHex (Wordlen,SecOpcode);  Write (')');
  340.                 END;
  341.            END; (* case  *)
  342.          END
  343.        ELSE IF Odd(Bitfeld [2]) THEN
  344.          Write ('           ','LD   A,(',Register3[Bitfeld[2] DIV 2],')')
  345.        ELSE
  346.          Write ('           ','LD   (',Register3[Bitfeld[2] DIV 2],'),A');
  347.                             (* Untergruppe 00 xxx 011  -> INC rp   DEC rp  *)
  348.     3: IF Odd(Bitfeld [2]) THEN
  349.          Write ('           ','DEC  ',Register3[Bitfeld [2] DIV 2])
  350.        ELSE
  351.          Write ('           ','INC  ',Register3[Bitfeld [2] DIV 2]);
  352.                             (* Untergruppe 00 xxx 100  -> INC r            *)
  353.     4: Write ('           ','INC  ',Register2[Bitfeld [2]]);
  354.                             (* Untergruppe 00 xxx 101  -> DEC r            *)
  355.     5: Write ('           ','DEC  ',Register2[Bitfeld [2]]);
  356.     6: BEGIN                (* Untergruppe 00 xxx 110  -> LD r,N           *)
  357.          SecOpcode := GetVal (Currentadr,Bytelen);              (* lese N  *)
  358.          IF Bitfeld [2] = 6 THEN Write ('        ','LD   (HL),')
  359.          ELSE Write ('        ','LD   ',Register1[Bitfeld[2]],',');
  360.          WriteHex (Bytelen,SecOpcode);              (* N ausgeben *)
  361.        END;
  362.                             (* Untergruppe 00 xxx 111  -> DAA,...          *)
  363.     7: Write ('           ',Befehl2[Bitfeld[2]]);
  364.   END; (* CASE *)
  365. END;
  366. (* ----------------------------------------------------------------------- *)
  367. (* Modul zur Enschluesselung der Hauptgruppe 01 xxx xxx. Es handelt sich   *)
  368. (* hierbei um die LD r,r Befehle                                           *)
  369. PROCEDURE Gruppe01;
  370. BEGIN
  371.   Write ('           ');
  372.   IF Opcode = $76 THEN  Write ('HALT')              (* Ausnahme  Halt = 76 *)
  373.   ELSE IF Bitfeld [2] = 6 THEN Write ('LD   (HL),',Register2[Bitfeld[3]])
  374.   ELSE Write ('LD   ',Register1[Bitfeld[2]],',',Register2[Bitfeld[3]]);
  375. END;
  376. (* ----------------------------------------------------------------------- *)
  377. (* Modul zur Entschluesselung der Hauptgruppe 10 xxx xxx. Es handelt sich  *)
  378. (* um die Befehle ADD, ADC, SUB, ...                                       *)
  379. PROCEDURE Gruppe10;
  380. BEGIN
  381.   Write ('           ');  Write (Befehl1[Bitfeld[2]],'  ');
  382.   IF Bitfeld [2] IN [0,1,3] THEN Write ('A,');        (* ADD  A,r ...      *)
  383.   IF Bitfeld[3] = 6 THEN Write ('(HL)')
  384.   ELSE Write (Register1[Bitfeld[3]]);
  385. END;
  386. (* ----------------------------------------------------------------------- *)
  387. (* Modul zur Entschluesselung der Hauptgruppe 11 xxx xxx. Es werden 7      *)
  388. (* Untergruppen gebildet: 11 xxx bbb. Ausserdem werden die Praefix-Bytes   *)
  389. (* CB, DD, ED, FD abgefangen                                               *)
  390. PROCEDURE Gruppe11;
  391. BEGIN
  392.   CASE Bitfeld [3] OF            (* Untergruppe 11 xxx 000 -> RET CC       *)
  393.     0: Write ('           ','RET  ',Condition [Bitfeld[2]]);
  394.     1: BEGIN                     (* Untergruppe 11 xxx 001  -> RET, POP    *)
  395.          IF Odd(Bitfeld [2]) THEN
  396.            CASE (Bitfeld [2] DIV 2) OF
  397.              0: Write ('           ','RET');
  398.              1: Write ('           ','EXX');
  399.              2: Write ('           ','Jp   (HL)');
  400.              3: Write ('           ','LD   SP,HL');
  401.            END
  402.          ELSE  Write ('           ','POP  ',Register4[Bitfeld[2] DIV 2]);
  403.        END;
  404.     2: BEGIN                     (* Untergruppe 11 xxx 010  -> JP CC,NN    *)
  405.          SecOpcode := GetVal (Currentadr,Wordlen);    (* lese Word NN      *)
  406.          Write ('     ','Jp   ',Condition[Bitfeld[2]],',');
  407.          WriteHex (Wordlen,SecOpcode);                (* NN ausgeben       *)
  408.        END;
  409.     3: CASE Bitfeld [2] OF     (* Untergruppe 11 xxx 011  -> JP,  OUT,  IN *)
  410.          0: BEGIN                                        (* JP  NN         *)
  411.               SecOpcode := GetVal (Currentadr,Wordlen);  (* lese Adresse   *)
  412.               Write ('     ','Jp   ');
  413.               WriteHex (Wordlen,SecOpcode);              (* Adr ausgeben   *)
  414.             END;
  415.          1: ExtendCB;                                         (* Opcode CB *)
  416.          2: BEGIN                                       (* OUT (N),A       *)
  417.               SecOpcode := GetVal (Currentadr,Bytelen); (* lese N          *)
  418.               Write ('        ','OUT  (');
  419.               WriteHex (Bytelen,SecOpcode); Write(')'); (* N   ausgeben    *)
  420.               Write ('),A');
  421.             END;
  422.          3: BEGIN                                       (* IN  A,(N)       *)
  423.               SecOpcode := GetVal (Currentadr,Bytelen); (* lese N          *)
  424.               Write ('        ','IN   A,(');
  425.               WriteHex (Bytelen,SecOpcode); Write(')'); (* N   ausgeben    *)
  426.             END;
  427.          4: Write ('           ','EX   (SP),HL');
  428.          5: Write ('           ','EX   DE,HL');
  429.          6: Write ('           ','Di');
  430.          7: Write ('           ','Ei');
  431.        END;
  432.     4: BEGIN                     (* Untergruppe 11 xxx 100  -> CALL CC,NN  *)
  433.          SecOpcode := GetVal (Currentadr,Wordlen);    (* lese Word NN      *)
  434.          Write ('     ','CALL ',Condition[Bitfeld[2]],',');
  435.          WriteHex (Wordlen,SecOpcode);                (* NN ausgeben       *)
  436.        END;
  437.     5: IF Odd(Bitfeld [2]) THEN (* Untergruppe 11 xxx 101  -> PUSH   CALL  *)
  438.          CASE (Bitfeld [2] DIV 2) OF
  439.            0: BEGIN
  440.                 SecOpcode := GetVal (Currentadr,Wordlen);  (* lese NN      *)
  441.                 Write ('     ','CALL ');  WriteHex (Wordlen,SecOpcode);
  442.               END;
  443.            1: Extendxx;                                       (* Opcode DD *)
  444.            2: ExtendED;                                       (* Opcode DE *)
  445.            3: Extendxx;                                       (* Opcode FD *)
  446.          END
  447.        ELSE  Write ('           ','PUSH ',Register4[Bitfeld[2] DIV 2]);
  448.     6: BEGIN                 (* Untergruppe 11 xxx 110  -> ADD  A,N  ...   *)
  449.          SecOpcode := GetVal (Currentadr,Bytelen);     (* lese N           *)
  450.          Write ('        ',Befehl1[Bitfeld[2]],'  ');
  451.          IF Bitfeld[2] IN [0,1,3] THEN  Write ('A,');  (* ADD  A,N ..      *)
  452.          WriteHex (Bytelen,SecOpcode);                 (* N ausgeben       *)
  453.        END;
  454.                                      (* Untergruppe 11 xxx 111  -> RST n   *)
  455.     7: Write ('           ','RST  ',Bitfeld[2]*8);
  456.   END; (* CASE *)
  457. END;
  458. (* ----------------------------------------------------------------------- *)
  459. BEGIN (* Disasmz80 *)
  460.   WriteLn;  WriteLn;  WriteLn;
  461.   WriteLn('Z80 Disassembler v1.0   (C) 1987  b.Born & PASCAL Int.');
  462.   WriteLn;
  463.   REPEAT                         (* Programmende, wenn StartAdr > EndAdr ! *)
  464.     Write('Start Adresse (Hex = $XXXX) :');  ReadLn(Startadr);
  465.     Write('End Adresse   (Hex = $XXXX) :');  ReadLn(Endadr);
  466.     Currentadr := Startadr;
  467.     WHILE Greather(Currentadr,Endadr) DO BEGIN        (* Disassembler loop *)
  468.       WriteHex (Wordlen,Currentadr);  Write (' ');    (* Adresse ausgeben  *)
  469.       Opcode := GetVal (Currentadr,Bytelen);          (* lese Opcodebyte   *)
  470.       Decode (Bitfeld,Opcode);                        (* sep. Bitfelder    *)
  471.       CASE Bitfeld [1] OF    (* Opcodes werden in 4 Hauptgruppen decodiert *)
  472.         0: Gruppe00;  1: Gruppe01;  2: Gruppe10;   3: Gruppe11;
  473.       END;
  474.       WriteLn;
  475.     END;
  476.   UNTIL Greather(Endadr,Startadr);
  477. END.
  478.