; Z80-Disassembler fuer Sharp PC-E220 ; ORG 0100H ENTRY: PUSH AF PUSH BC PUSH DE PUSH HL PUSH IY PUSH IX LD IY,(DATA) LD IX,(INST) PUSH IY ; Ausgabe-Adresse in HL kopieren POP HL LD B,48 ; Laenge des Ausgabespeichers = 48 bytes CLEAR: LD (HL),' ' ; Ausgabespeicher mit Leerzeichen initialisieren INC HL DJNZ CLEAR PUSH IY ; Ausgabe-Adresse in HL kopieren POP HL LD BC,30 ; die Ausgabe der zweiten Zeile erfolgt 30 bytes weiter ADD HL,BC ; besagte 30 auf HL drauf addiern PUSH HL ; und auf den Stack schieben CALL ADDR ; Adresse ausgeben CALL BYTE ; Byte ausgeben EX (SP),IY ; Zeiger auf zweite Zeile laden, erste Zeile sichern LD A,(IX+0) AND 0C0H ; Bit 7 und 6 entscheiden, welche Art Befehl das ist RLCA ; diese Bits rotieren wir in Bit 2 und 1 RLCA RLCA LD B,0 ; und errechnen damit nen Index in JPTBL LD C,A LD HL,JPTBL ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ; Befehl disassemblieren EXIT: INC IX ; wir erhoehen noch die Eingabe-Adresse LD (INST),IX ; und geben die naechste Adresse aus POP HL ; und entfernen noch den alten Zeiger vom Stack POP IY POP IX POP HL POP DE POP BC POP AF RET ; und kehren zurueck ; ; ZERO - disassembliert einen Befehl, dessen hoechste zwei Bits 0 ergeben ; ZERO: LD A,(IX+0) ; Eingabe-Wert einlesen AND 07H ; Befehl dekodieren RLCA ; *2 fuer Index in ZRTBL LD C,A LD HL,ZRTBL ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ; Befehl disassemblieren ZR000: LD HL,JRTBL LD A,(IX+0) AND 38H ; Befehl dekodieren RRCA RRCA LD C,A ADD HL,BC ; Index in JRTBL berechnen LD C,11 LD E,(HL) ; Adresse des Befehls-Strings in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden CALL SNCPY LD A,(IX+0) AND 30H ; evtl. Argumente? JR Z,EXIT ; Nee. INC IX PUSH IX ; IX in HL laden POP HL ; INC HL LD A,(IX+0) ; Argument laden AND A ; Flags setzen JP P,ZRPOS ; positiv? LD B,0FFH ZRPOS: LD C,A ADD HL,BC ; Adresse + 2 + Argument LD A,H ; ausgeben des Sprungziels CALL UHEX LD A,L CALL UHEX EX (SP),IY ; Zeiger auf erste Zeile laden CALL BYTE ; und das Argument ausgeben JR EXIT ; und raus ZR001: LD A,(IX+0) BIT 3,A ; ADD oder LD? JR Z,ZRLD16 LD HL,ADDSTR JR ZR001A ZRLD16: LD HL,LDSTR ZR001A: LD C,8 CALL SNCPY LD HL,DRTBL AND 30H ; Register dekodieren RRCA ; Schieben, um Index in DRTBL zu erhalten RRCA RRCA LD C,A ADD HL,BC ; und Adresse der Adresse errechnen LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,2 CALL SNCPY ; und das Register ausgeben LD A,(IX+0) BIT 3,A ; evtl. Argumente? JP NZ,EXIT ; Nee. LD (IY+0),',' INC IY INC IX CALL WORD ; 16bit Argument ausgeben EX (SP),IY ; Zeiger auf die erste Zeile laden CALL BYTE ; erstes Byte ausgeben INC IX CALL BYTE ; zweites Byte ausgeben JP EXIT ; und raus ZR010: LD A,(IX+0) LD HL,LDSTR ; LD ausgeben LD C,5 CALL SNCPY BIT 5,A ; evtl. Argumente? JR NZ,ZR010A BIT 4,A ; Registerpaar dekodieren JR NZ,ZR010B LD HL,DRBC JR ZR010C ZR010B: LD HL,DRDE ZR010C: BIT 3,A ; (r),A oder A,(r)? JR Z,ZR010D ; bei 0 zur Mitte, bei 1 grade durch ZR010F: LD (IY+0),'A' INC IY LD (IY+0),',' INC IY JR Z,ZR010E ; bei 0 nach unten, bei 1 grade durch ZR010D: LD (IY+0),'(' INC IY CALL SNCPY LD (IY+0),')' INC IY LD (IY+0),',' INC IY JR Z,ZR010F ; bei 0 nach wieder nach oben, bei 1 grade durch ZR010E: LD (IY-1),' ' ; dort liegt in jedem Fall ein Komma zuviel JP EXIT ; und raus ZR010A: BIT 4,A ; Register dekodieren JR NZ,ZR010G LD HL,DRHL JR ZR010H ZR010G: LD HL,SRA ZR010H: BIT 3,A ; (16bit),r oder r,(16bit)? JR Z,ZR010I ; bei 0 zur Mitte, bei 1 grade durch ZR010K: CALL SNCPY LD (IY+0),',' INC IY JR Z,ZR010J ; bei 0 nach unten, bei 1 grade durch ZR010I: LD (IY+0),'(' INC IY INC IX ; aufs Argument zeigen CALL WORD ; und das Argument ausgeben LD (IY+0),')' INC IY LD (IY+0),',' INC IY JR Z,ZR010K ; bei 0 wieder nach oben, bei 1 grade durch ZR010J: LD (IY-1),' ' ; dort liegt in jedem Fall ein Komma zuviel DEC IY EX (SP),IY ; Zeiger auf erste Zeile laden CALL BYTE ; erstes Byte ausgeben INC IX CALL BYTE ; zweites Byte ausgeben JP EXIT ; und raus ZR011: LD A,(IX+0) BIT 3,A ; INC oder DEC? JR NZ,ZR011A LD HL,INCSTR JR ZR011B ZR011A: LD HL,DECSTR ZR011B: LD C,5 CALL SNCPY LD HL,DRTBL AND 30H ; Register dekodieren RRCA ; Schieben, um Index in DRTBL zu erhalten RRCA RRCA LD C,A ADD HL,BC ; und Adresse der Adresse errechnen LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,2 CALL SNCPY ; und ausgeben JP EXIT ; und raus ZR100: ZR101: LD A,(IX+0) BIT 0,A ; INC oder DEC? JR NZ,ZR100A LD HL,INCSTR JR ZR100B ZR100A: LD HL,DECSTR ZR100B: LD C,5 CALL SNCPY LD HL,SRTBL AND 38H ; nur die Nummer des Zielregisters bleibt RRCA ; und wird zweimal nach rechts geschoben, so dass RRCA ; A = Nummer des Register * 2 LD C,A ADD HL,BC ; das wird jetzt auf die Adresse der SR-Tabelle addiert LD E,(HL) ; und die Adresse des Register-Strings in DE geladen INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,4 ; und der Registername wird in die Ausgabekopiert CALL SNCPY JP EXIT ; und raus ZR110: LD A,(IX+0) LD C,5 ; alles LD, und genau das LD HL,LDSTR ; schreiben wir jetzt in die Ausgabe CALL SNCPY LD HL,SRTBL AND 38H ; nur die Nummer des Zielregisters bleibt RRCA ; und wird zweimal nach rechts geschoben, so dass RRCA ; A = Nummer des Register * 2 LD C,A ADD HL,BC ; das wird jetzt auf die Adresse der SR-Tabelle addiert LD E,(HL) ; und die Adresse des Register-Strings in DE geladen INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,4 ; und der Registername wird in die Ausgabekopiert CALL SNCPY LD (IY+0),',' ; gefolgt von einem Komma INC IY INC IX CALL BYTE ; Argument ausgeben EX (SP),IY ; Zeiger auf erste Zeile laden CALL BYTE ; und auch dort das Argument ausgeben JP EXIT ; und raus ZR111: LD A,(IX+0) LD HL,ROTBL AND 38H ; Befehl dekodieren RRCA RRCA LD C,A ADD HL,BC ; Index in ROTBL errechnen LD E,(HL) ; Adresse aus ROTBL laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,4 CALL SNCPY ; ausgeben und raus JP EXIT ; ; ONE - disassembliert einen Befehl, dessen hoechste zwei Bits 1 ergeben ; ONE: LD A,(IX+0) ; Eingabe-Wert einlesen CP 76H ; Sonderfall: 76H ist HALT JR Z,HLT LD C,5 ; alle anderen Befehle sind LD, und genau das LD HL,LDSTR ; schreiben wir jetzt in die Ausgabe CALL SNCPY LD HL,SRTBL AND 38H ; nur die Nummer des Zielregisters bleibt RRCA ; und wird zweimal nach rechts geschoben, so dass RRCA ; A = Nummer des Register * 2 LD C,A ADD HL,BC ; das wird jetzt auf die Adresse der SR-Tabelle addiert LD E,(HL) ; und die Adresse des Register-Strings in DE geladen INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,4 ; und der Registername wird in die Ausgabekopiert CALL SNCPY LD (IY+0),',' ; gefolgt von einem Komma INC IY LD HL,SRTBL ; gleiches Spiel wie oben, jetzt das Eingabe-Register LD A,(IX+0) AND 07H RLCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,4 CALL SNCPY JR EXIT ; wir sind fertig, also ab zum Ende HLT: LD C,4 LD HL,HLTSTR CALL SNCPY JP EXIT ; ; TWO - disassembliert einen Befehl, dessen hoechste 2 Bits 2 ergeben ; TWO: LD HL,COTBL LD A,(IX+0) ; Eingabe-Wert einlesen AND 38H ; Was fuern Befehl ist das? RRCA ; Index in COTBL errechnen RRCA LD C,A ADD HL,BC LD E,(HL) ; und den Inhalt von COTBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,5 CALL SNCPY LD HL,SRTBL ; gleiches Spiel wie oben, jetzt das Eingabe-Register LD A,(IX+0) AND 07H RLCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,4 CALL SNCPY JP EXIT ; ; THREE - disassembliert einen Befehl, dessen hoechste zwei Bits 3 ergeben ; THREE: LD A,(IX+0) ; Eingabe-Wert einlesen AND 07H ; Befehl dekodieren RLCA ; *2 fuer Index in ZRTBL LD C,A LD HL,THRTBL ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ; Befehl disassemblieren TH000: TH010: TH100: LD HL,RJCTBL LD A,(IX+0) AND 06H ; Index in RJCTBL LD C,A ADD HL,BC LD E,(HL) ; und den Inhalt von RJCTBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,5 CALL SNCPY ; und den Befehl in die Ausgabe kopieren LD HL,CCTBL LD A,(IX+0) ; Eingabe-Wert einlesen AND 38H ; Was fuern Befehl ist das? RRCA ; Index in CCTBL errechnen RRCA LD C,A ADD HL,BC LD E,(HL) ; und den Inhalt von CCTBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,5 CALL SNCPY ; und den condition code ausgeben LD A,(IX+0) AND 06H JP Z,EXIT ; keine Argumente LD (IY+0),',' INC IY INC IX ; aufs Argument zeigen CALL WORD ; und das Argument ausgeben EX (SP),IY ; Zeiger auf erste Zeile laden CALL BYTE ; und auch dort das Argument ausgeben INC IX CALL BYTE JP EXIT TH001: LD HL,TH1TBL LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) ; Inhalt von TH1TBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,10 CALL SNCPY ; und in die Ausgabe kopieren JP EXIT TH011: LD A,(IX+0) CP 0CBH ; Sonderfall JP Z,SHIFT BIT 5,A JR Z,TH011A ; hat Argumente LD HL,TH2TBL AND 18H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,12 CALL SNCPY JP EXIT TH011A: AND 38H JR NZ,TH011B LD HL,RJCJP LD C,5 CALL SNCPY INC IX CALL WORD EX (SP),IY CALL BYTE INC IX CALL BYTE JP EXIT TH011B: BIT 4,A JR NZ,TH011C LD HL,OUTSTR LD C,6 CALL SNCPY INC IX CALL BYTE LD (IY+0),',' LD (IY+1),'A' EX (SP),IY CALL BYTE JP EXIT TH011C: LD HL,INSTR LD C,8 CALL SNCPY INC IX CALL BYTE LD (IY+0),')' EX (SP),IY CALL BYTE JP EXIT TH101: LD A,(IX+0) BIT 3,A JR NZ,TH101A LD HL,TH5TBL AND 38H RRCA RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,7 CALL SNCPY JP EXIT TH101A: AND 30H JR NZ,SHIFT ; Sonderfall LD HL,RJCALL LD C,5 CALL SNCPY INC IX CALL WORD EX (SP),IY CALL BYTE INC IX CALL BYTE JP EXIT TH110: LD A,(IX+0) LD HL,COTBL AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) ; und den Inhalt von COTBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,5 CALL SNCPY INC IX CALL BYTE EX (SP),IY CALL BYTE JP EXIT TH111: LD A,(IX+0) LD HL,RSTSTR LD C,5 CALL SNCPY AND 38H CALL UHEX JP EXIT ; ; SHIFT - disassembliert einen geshifteten Befehl ; SHIFT: INC IX ; das zweite Byte enthaelt den eigentlichen EX (SP),IY ; Befehl, deshalb geben wir das zuerst mal aus CALL BYTE EX (SP),IY LD A,(IX-1) ; um welche Art geshifteten Befehl handelt es sich? CP 0CBH JP Z,SHCB ; shift/rotate/bit BIT 4,A JP Z,SHED ; block/io/... BIT 5,A JR Z,SHDD ; index LD HL,IYSTR ; IY (FD) JR SHDD1 SHDD: LD HL,IXSTR ; IX (DD) SHDD1: PUSH IY ; die Adresse des normalen Ausgabebereichs wird LD IY,TMPSTR ; gesichert, dann bauen wir das Argument in einem LD (IY+0),'(' ; temporaeren Speicher zusammen INC IY LD C,2 CALL SNCPY ; erst den Namen des Indexregisters... LD A,(IX+1) CALL SHEX ; dann das Displacement mit Vorzeichen LD (IY+0),')' POP IY ; weiter gehts im normalen Ausgabebereich LD A,(IX+0) ; was fuern Befehl ist das? CP 0CBH JP Z,DDCB ; shift/rotate/bit AND 0C0H JP Z,DDIFF CP 0C0H JP Z,DDIFF2 BIT 7,A JP NZ,DDCO DDLD: ; hier gibts nen fall-through LD A,(IX+0) CP 76H JP Z,ILLEG ; geshiftetes HALT? EX (SP),IY INC IX CALL BYTE ; das Displacement im TMPSTR wird ausgegeben EX (SP),IY LD HL,LDSTR LD C,5 CALL SNCPY AND 07H XOR 06H JR Z,DDLD1 DDLD2: LD HL,TMPSTR LD C,7 CALL SNCPY ; zuerst Index+d LD (IY+0),',' INC IY LD HL,SRTBL LD A,(IX-1) AND 07H RLCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,4 CALL SNCPY ; dann das Register JP EXIT DDLD1: LD HL,SRTBL ; umgekehrt: erst das Register LD A,(IX-1) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,4 CALL SNCPY LD (IY+0),',' INC IY LD HL,TMPSTR LD C,7 CALL SNCPY ; dann Index+d JP EXIT DDCO: LD A,(IX+0) AND 07H CP 06H JP NZ,ILLEG LD HL,COTBL LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,5 CALL SNCPY ; erst den Befehl LD HL,TMPSTR LD C,7 CALL SNCPY ; dann Index+d EX (SP),IY INC IX CALL BYTE ; das Displacement im TMPSTR wird ausgegeben JP EXIT DDIFF2: EX DE,HL ; Zeiger auf Indexregisternamen sichern LD A,(IX+0) ; Opcode erneut laden CP 0E1H ; POP? JR NZ,DDIF2A LD HL,TH1BC LD C,5 CALL SNCPY JR DDIF2E ; und weiter DDIF2A: CP 0E3H ; EX (SP)? JR NZ,DDIF2B LD HL,TH2EX1 LD C,10 CALL SNCPY JR DDIF2E ; und weiter DDIF2B: CP 0E5H ; PUSH? JR NZ,DDIF2C LD HL,TH5BC LD C,5 CALL SNCPY JR DDIF2E ; und weiter DDIF2C: CP 0E9H ; JP (index)? JR NZ,DDIF2D LD HL,TH1JP LD C,9 CALL SNCPY DEC IY ; Ausgabe-Zeiger muss drei Zeichen zurueckgesetzt werden DEC IY DEC IY JR DDIF2E ; und weiter DDIF2D: CP 0F9H ; LD SP,? JP NZ,ILLEG LD HL,TH1LD LD C,8 CALL SNCPY DDIF2E: EX DE,HL LD C,2 CALL SNCPY JP EXIT DDIFF: LD A,(IX+0) ; Opcode erneut laden AND 0FH CP 09H ; ADD JR NZ,DDIFFA EX DE,HL ; Zeiger auf Indexregisternamen sichern LD HL,COADD LD C,5 CALL SNCPY EX DE,HL ; Indexregisternamen ausgeben LD C,2 CALL SNCPY LD (IY+0),',' INC IY LD A,(IX+0) CP 29H CALL Z,SNCPY JP Z,EXIT LD HL,DRTBL AND 30H ; Register dekodieren RRCA ; Schieben, um Index in DRTBL zu erhalten RRCA RRCA LD C,A ADD HL,BC ; und Adresse der Adresse errechnen LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,2 CALL SNCPY JP EXIT DDIFFA: LD A,(IX+0) CP 21H JR NZ,DDIFFB EX DE,HL LD HL,LDSTR LD C,5 CALL SNCPY EX DE,HL LD C,2 CALL SNCPY LD (IY+0),',' INC IY INC IX CALL WORD EX (SP),IY CALL BYTE INC IX CALL BYTE JP EXIT DDIFFB: CP 22H JR NZ,DDIFFC EX DE,HL LD HL,LDSTR LD C,5 CALL SNCPY LD (IY+0),'(' INC IY INC IX CALL WORD LD (IY+0),')' INC IY LD (IY+0),',' INC IY EX DE,HL LD C,2 CALL SNCPY EX (SP),IY CALL BYTE INC IX CALL BYTE JP EXIT DDIFFC: CP 23H JR NZ,DDIFFD EX DE,HL LD HL,INCSTR LD C,5 CALL SNCPY EX DE,HL LD C,2 CALL SNCPY JP EXIT DDIFFD: CP 2AH JR NZ,DDIFFE EX DE,HL LD HL,LDSTR LD C,5 CALL SNCPY EX DE,HL LD C,2 CALL SNCPY LD (IY+0),',' INC IY LD (IY+0),'(' INC IY INC IX CALL WORD LD (IY+0),')' EX (SP),IY CALL BYTE INC IX CALL BYTE JP EXIT DDIFFE: CP 2BH JR NZ,DDIFFF EX DE,HL LD HL,DECSTR LD C,5 CALL SNCPY EX DE,HL LD C,2 CALL SNCPY JP EXIT DDIFFF: CP 34H JR NZ,DDIFFG EX DE,HL LD HL,INCSTR LD C,5 CALL SNCPY LD HL,TMPSTR LD C,7 CALL SNCPY EX (SP),IY INC IX CALL BYTE JP EXIT DDIFFG: CP 35H JR NZ,DDIFFH EX DE,HL LD HL,DECSTR LD C,5 CALL SNCPY LD HL,TMPSTR LD C,7 CALL SNCPY EX (SP),IY INC IX CALL BYTE JP EXIT DDIFFH: CP 36H JP NZ,ILLEG EX DE,HL LD HL,LDSTR LD C,5 CALL SNCPY LD HL,TMPSTR LD C,7 CALL SNCPY EX (SP),IY INC IX CALL BYTE EX (SP),IY LD (IY+0),',' INC IY INC IX CALL BYTE EX (SP),IY CALL BYTE JP EXIT DDCB: INC IX INC IX LD A,(IX+0) AND 0C0H JR NZ,DDCB1 LD HL,CBTBL ; rotate/shift LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) ; und den Inhalt von COTBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,5 CALL SNCPY JR DDCBC ; weiter zur Ausgabe von Index+d DDCB1: BIT 7,A JR NZ,DDCB2 LD HL,BITSTR ; BIT JR DDCB4 DDCB2: BIT 6,A JR NZ,DDCB3 LD HL,RESSTR ; RES JR DDCB4 DDCB3: LD HL,SETSTR ; SET DDCB4: LD C,5 CALL SNCPY ; nun wird der Befehl ausgegeben LD A,(IX+0) AND 38H RRCA RRCA RRCA ADD A,'0' LD (IY+0),A INC IY LD (IY+0),',' INC IY DDCBC: LD HL,TMPSTR LD C,7 CALL SNCPY ; Index+d wird ausgegeben EX (SP),IY DEC IX CALL BYTE INC IX CALL BYTE JP EXIT SHED: LD A,(IX+0) BIT 7,A JP NZ,BLOCK ; MSB gesetzt -> BLOCK BIT 6,A JP Z,ILLEG ; Opcodes < 40H gibts nicht AND 07H RLCA ; *2 fuer Index in EDTBL LD C,A LD HL,EDTBL ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL JP (HL) ; Befehl disassemblieren ED000: ; IN sr,(C) LD HL,INSTR LD C,5 CALL SNCPY LD HL,SRTBL LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL CALL SNCPY LD (IY+0),',' LD (IY+1),'(' LD (IY+2),'C' LD (IY+3),')' JP EXIT ED001: ; OUT (C),sr LD HL,OUTSTR LD C,6 CALL SNCPY LD (IY+0),'C' LD (IY+1),')' LD (IY+2),',' INC IY INC IY INC IY LD HL,SRTBL LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL CALL SNCPY JP EXIT ED010: ; 16bit ADC/SBC LD A,(IX+0) BIT 3,A JR NZ,ED010A LD HL,COSBC ; SBC JR ED010B ED010A: LD HL,COADC ; ADC ED010B: LD C,5 CALL SNCPY LD HL,DRHL ; Zeiger auf "HL" LD C,2 CALL SNCPY LD (IY+0),',' INC IY LD HL,DRTBL ; Index in DRTBL usw. AND 30H RRCA RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,2 CALL SNCPY JP EXIT ED011: ; 16 bit LD LD HL,LDSTR LD C,5 CALL SNCPY LD HL,DRTBL LD A,(IX+0) AND 30H RRCA RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,2 LD A,(IX+0) ED011H: BIT 3,A ; (16bit),r oder r,(16bit)? JR Z,ED011I ; bei 0 zur Mitte, bei 1 grade durch ED011K: CALL SNCPY LD (IY+0),',' INC IY JR Z,ED011J ; bei 0 nach unten, bei 1 grade durch ED011I: LD (IY+0),'(' INC IY INC IX ; aufs Argument zeigen CALL WORD ; und das Argument ausgeben LD (IY+0),')' INC IY LD (IY+0),',' INC IY JR Z,ED011K ; bei 0 wieder nach oben, bei 1 grade durch ED011J: LD (IY-1),' ' ; dort liegt in jedem Fall ein Komma zuviel DEC IY EX (SP),IY ; Zeiger auf erste Zeile laden CALL BYTE ; erstes Byte ausgeben INC IX CALL BYTE ; zweites Byte ausgeben JP EXIT ED100: LD A,(IX+0) ; Opcode nochmal einlesen CP 44H ; ist das auch wirklich ein NEG? JP NZ,ILLEG ; wenn nicht -> illegal LD HL,NEGSTR LD C,3 CALL SNCPY JP EXIT ED101: LD A,(IX+0) ; Opcode nochmal einlesen AND 0F0H ; ist das auch wirklich RETN/RETI? CP 40H JP NZ,ILLEG ; wenn nicht -> illegal LD HL,TH1RET LD C,3 CALL SNCPY LD A,(IX+0) BIT 3,A ; RETN oder RETI? JR NZ,ED101A LD (IY+0),'N' JP EXIT ED101A: LD (IY+0),'I' JP EXIT ED110: ; Interrupt Mode LD A,(IX+0) AND 0F0H CP 40H JR NZ,ED110B LD A,(IX+0) BIT 3,A JP NZ,ILLEG ; nur 46H erlaubt JR ED110C ED110B: CP 50H JP NZ,ILLEG ; nur 56H und 5EH erlaubt ED110C: LD HL,IMSTR LD C,5 CALL SNCPY LD A,(IX+0) AND 18H JR NZ,ED110A LD (IY+0),'0' JP EXIT ED110A: ; IM 1/2 BIT 3,A JR NZ,ED110D LD (IY+0),'1' JP EXIT ED110D: LD (IY+0),'2' JP EXIT ED111: ; LD I/R, RRD, RLD LD HL,ED7TBL LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,8 CALL SNCPY JP EXIT BLOCK: ; block LD/CP/IN/OUT BIT 2,A JP NZ,ILLEG BIT 6,A JP NZ,ILLEG BIT 5,A JP Z,ILLEG LD HL,BLTBLX ; Index in BLTBLX errechnen AND 18H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD A,(IX+0) AND 03H ; und jetzt Index in den Index in BLTBLX errechnen RLCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,4 CALL SNCPY ; und kopieren, was immer dort steht JP EXIT SHCB: LD A,(IX+0) AND 0C0H JR NZ,SHCB1 LD HL,CBTBL LD A,(IX+0) AND 38H RRCA RRCA LD C,A ADD HL,BC LD E,(HL) ; und den Inhalt von COTBL+Index in DE laden INC HL LD D,(HL) EX DE,HL ; DE in HL laden LD C,5 CALL SNCPY JR SHCBC SHCB1: BIT 7,A JR NZ,SHCB2 LD HL,BITSTR JR SHCB4 SHCB2: BIT 6,A JR NZ,SHCB3 LD HL,RESSTR JR SHCB4 SHCB3: LD HL,SETSTR SHCB4: LD C,5 CALL SNCPY LD A,(IX+0) AND 38H RRCA RRCA RRCA ADD A,'0' LD (IY+0),A INC IY LD (IY+0),',' INC IY SHCBC: LD HL,SRTBL LD A,(IX+0) AND 07H RLCA LD C,A ADD HL,BC LD E,(HL) INC HL LD D,(HL) EX DE,HL LD C,4 CALL SNCPY JP EXIT ILLEG: LD HL,ILLSTR LD C,7 CALL SNCPY JP EXIT ; ; ADDR - schreibt den Inhalt von IX als ASCII Hex-String an die Stelle, auf die ; IY zeigt, gefolgt von einem Doppelpunkt. IY zeigt beim RET auf das ; zweite Zeichen nach dem Doppelpunkt ; ADDR: PUSH AF PUSH BC PUSH IX ; Eingabe-Adresse in BC laden POP BC LD A,B ; das Hi-Byte der Eingabe-Adresse als Hex-String im CALL UHEX ; Ausgabe-Speicher speichern LD A,C ; selbiges noch fuer das Lo-Byte CALL UHEX LD (IY+0),':' ; Doppelpunkt als Abschluss und eins weiter INC IY INC IY POP BC POP AF RET ; ; BYTE - schreibt das Byte an der Stelle IX als ASCII Hex-String an die Stelle, ; auf die IY zeigt. IY zeigt beim RET auf das zweite Zeichen nach dem ; Ende des Hex-Strings ; BYTE: PUSH AF LD A,(IX+0) ; Eingabe-Wert als Hex-String speichern CALL UHEX INC IY ; eins weiter (Leerstelle) POP AF RET ; ; WORD - schreibt das Word an der Stelle IX als ASCII Hex-String an die Stelle, ; auf die IY zeigt. IY zeigt beim RET auf das Zeichen nach dem Ende des ; des Hex-Strings ; WORD: PUSH AF LD A,(IX+1) CALL UHEX LD A,(IX+0) CALL UHEX POP AF RET ; ; SNCPY - kopiert einen String von der Adresse in HL ; an die Adresse in IY, BC enthaelt die max. ; Anzahl der zu kopierenden Zeichen, Abbruch ; beim Auftreten eines Nullbytes, welches nicht ; kopiert wird ; IY zeigt beim RET auf die Stelle hinter dem ; Ende des Strings ; SNCPY: PUSH AF PUSH BC PUSH DE PUSH HL PUSH IY ; Zieladresse in DE speichern fuer LDI POP DE XOR A ; A = 0, fuer Vergleich LCPY: CP (HL) ; A = (HL)? JR Z,ECPY ; Abbrechen, wenn A = (HL) LDI ; kopieren JP PE,LCPY ; wenns noch nicht vorbei ist, weitermachen. ECPY: PUSH DE ; DE wieder in IY kopieren POP IY POP HL POP DE POP BC POP AF RET ; ; SHEX - konvertiert das signed Byte in A in einen ASCII Hex-String ; und speichert diesen an der Stelle, die in IY steht ; nach dem RET steht in IY die Adresse direkt nach dem String ; SHEX: PUSH AF AND A ; Flags entsprechend dem Wert in A setzen JP P,PHEX ; Wenn A = positiv, dann PHEX LD (IY+0),'-' ; ansonsten schreiben wir ein "-" in die Ausgabe NEG ; und bilden das Zweierkomplement in A JR CHEX ; und weiter gehts... PHEX: LD (IY+0),'+' ; positiv, also schreiben wir ein "+" CHEX: INC IY ; Ausgabe-Zeiger um 1 erhoehen CALL UHEX ; und UHEX aufrufen, dass Betrag des Bytes ausgibt POP AF RET ; ; UHEX - konvertiert das unsigned Byte in A in einen ASCII Hex-String ; und speichert diesen an der Stelle, die in IY steht ; nach dem RET steht in IY die Adresse direkt nach dem String ; UHEX: PUSH AF PUSH BC PUSH DE PUSH HL LD D,0 ; D = 0 LD B,A ; A in B sichern LD HL,HXTBL AND 0FH ; Hi-Nibble ausmaskieren LD E,A ; Lo-Nibble in DE speichern ADD HL,DE ; Index in die Hex-Tabelle berechnen LD C,(HL) ; damit haben wir eine Adresse auf das ASCII Hex-Zeichen LD (IY+1),C ; welches wir im zweiten Byte der Ausgabe speichern LD A,B LD HL,HXTBL RLCA ; wir schieben A um 4 bit nach rechts RLCA ; damit ist das Hi-Nibble jetzt das Lo-Nibble RLCA RLCA AND 0FH ; und maskieren das Hi-Nibble aus, nur zur Sicherheit LD E,A ADD HL,DE ; gleiches Spiel wie oben LD C,(HL) LD (IY+0),C INC IY ; den Ausgabe-Zeiger noch entsprechend erhoehen INC IY POP HL POP DE POP BC POP AF RET ; ; Konstante Daten: ; JPTBL: ; Sprungtabelle fuer Hauptprogramm DW ZERO DW ONE DW TWO DW THREE ZRTBL: ; Sprungtabelle fuer ZERO DW ZR000 DW ZR001 DW ZR010 DW ZR011 DW ZR100 DW ZR101 DW ZR110 DW ZR111 THRTBL: ; Sprungtabelle fuer THREE DW TH000 DW TH001 DW TH010 DW TH011 DW TH100 DW TH101 DW TH110 EDTBL: ; Sprungtabelle fuer SHED DW ED000 DW ED001 DW ED010 DW ED011 DW ED100 DW ED101 DW ED110 DW ED111 DW TH111 ED7TBL: ; LD I/R, RRD, RLD DW EDLDIA DW EDLDRA DW EDLDAI DW EDLDAR DW EDRRD DW EDRLD DW ILLSTR DW ILLSTR BLTBLX: ; Tabelle der Tabellen der Block-Befehle DW BLTBL1 DW BLTBL2 DW BLTBL3 DW BLTBL4 BLTBL1: ; Block increment DW BLLDI DW BLCPI DW BLINI DW BLOUTI BLTBL2: ; Block decrement DW BLLDD DW BLCPD DW BLIND DW BLOUTD BLTBL3: ; Block increment, repeat DW BLLDIR DW BLCPIR DW BLINIR DW BLOTIR BLTBL4: ; Block decrement, repeat DW BLLDDR DW BLCPDR DW BLINDR DW BLOTDR CBTBL: ; mit CB geshiftete Befehle DW CBRLC DW CBRRC DW CBRL DW CBRR DW CBSLA DW CBSLR DW CBSLL DW CBSRL TH1TBL: ; TH001 DW TH1BC DW TH1RET DW TH1DE DW TH1EXX DW TH1HL DW TH1JP DW TH1AF DW TH1LD TH2TBL: ; TH010 DW TH2EX1 DW TH2EX2 DW TH2DI DW TH2EI TH5TBL: ; TH101 DW TH5BC DW TH5DE DW TH5HL DW TH5AF CCTBL: ; condition codes DW CCNZ DW CCZ DW CCNC DW CCC DW CCPO DW CCPE DW CCP DW CCM RJCTBL: ; RET, JP, CALL DW RJCRET DW RJCJP DW RJCALL ROTBL: ; Tabelle der Adressen der Rotate-Befehle DW RORLCA DW RORRCA DW RORLA DW RORRA DW RODAA ; eigentlich kein Rotate-Befehl DW ROCPL ; dito DW ROSCF ; dito DW ROCCF ; dito JRTBL: ; Tabelle der Adressen der relativen Spruenge DW JRNOP ; eigentlich kein relativer Sprung DW JREX ; auch kein relativer Sprung DW JRDJNZ DW JRNOCC DW JRNZ DW JRZ DW JRNC DW JRC COTBL: ; Tabelle der Adressen der 8bit-Arithmetik Mnemonics DW COADD DW COADC DW COSUB DW COSBC DW COAND DW COXOR DW COOR DW COCP DRTBL: ; Tabelle der Adressen der Registerpaare DW DRBC DW DRDE DW DRHL DW DRSP SRTBL: ; Tabelle der Adressen der Registernamen DW SRB DW SRC DW SRD DW SRE DW SRH DW SRL DW SRHL DW SRA EDLDIA: DM 'LD I,A',0 EDLDRA: DM 'LD R,A',0 EDLDAI: DM 'LD A,I',0 EDLDAR: DM 'LD A,R',0 EDRRD: DM 'RRD',0 EDRLD: DM 'RLD',0 BLLDI: DM 'LDI',0 BLCPI: DM 'CPI',0 BLINI: DM 'INI',0 BLOUTI: DM 'OUTI',0 BLLDD: DM 'LDD',0 BLCPD: DM 'CPD',0 BLIND: DM 'IND',0 BLOUTD: DM 'OUTD',0 BLLDIR: DM 'LDIR',0 BLCPIR: DM 'CPIR',0 BLINIR: DM 'INIR',0 BLOTIR: DM 'OTIR',0 BLLDDR: DM 'LDDR',0 BLCPDR: DM 'CPDR',0 BLINDR: DM 'INDR',0 BLOTDR: DM 'OTDR',0 CBRLC: DM 'RLC ',0 CBRRC: DM 'RRC ',0 CBRL: DM 'RL ',0 CBRR: DM 'RR ',0 CBSLA: DM 'SLA ',0 CBSLR: DM 'SLR ',0 CBSLL: DM 'SLL ',0 CBSRL: DM 'SRL ',0 TH1BC: DM 'POP BC',0 TH1DE: DM 'POP DE',0 TH1HL: DM 'POP HL',0 TH1AF: DM 'POP AF',0 TH1RET: DM 'RET',0 TH1EXX: DM 'EXX',0 TH1JP: DM 'JP (HL)',0 TH1LD: DM 'LD SP,HL',0 TH2EX1: DM 'EX (SP),HL',0 TH2EX2: DM 'EX DE,HL',0 TH2DI: DM 'DI',0 TH2EI: DM 'EI',0 TH5BC: DM 'PUSH BC',0 TH5DE: DM 'PUSH DE',0 TH5HL: DM 'PUSH HL',0 TH5AF: DM 'PUSH AF',0 CCNZ: DM 'NZ',0 CCZ: DM 'Z',0 CCNC: DM 'NC',0 CCC: DM 'C',0 CCPO: DM 'PO',0 CCPE: DM 'PE',0 CCP: DM 'P',0 CCM: DM 'M',0 RJCRET: DM 'RET ',0 RJCJP: DM 'JP ',0 RJCALL: DM 'CALL ',0 RORLCA: DM 'RLCA',0 RORRCA: DM 'RRCA',0 RORLA: DM 'RLA',0 RORRA: DM 'RRA',0 RODAA: DM 'DAA',0 ROCPL: DM 'CPL',0 ROSCF: DM 'SCF',0 ROCCF: DM 'CCF',0 JRNOP: DM 'NOP',0 JREX: DM 'EX AF,AF''',0 JRDJNZ: DM 'DJNZ ',0 JRNOCC: DM 'JR ',0 JRNZ: DM 'JR NZ,',0 JRZ: DM 'JR Z,',0 JRNC: DM 'JR NC,',0 JRC: DM 'JR C,',0 COADD: DM 'ADD ',0 COADC: DM 'ADC ',0 COSUB: DM 'SUB ',0 COSBC: DM 'SBC ',0 COAND: DM 'AND ',0 COXOR: DM 'XOR ',0 COOR: DM 'OR ',0 COCP: DM 'CP ',0 DRBC: DM 'BC',0 DRDE: DM 'DE,'0 DRHL: DM 'HL',0 DRSP: DM 'SP',0 SRA: DM 'A',0 SRB: DM 'B',0 SRC: DM 'C',0 SRD: DM 'D',0 SRE: DM 'E',0 SRH: DM 'H',0 SRL: DM 'L',0 SRHL: DM '(HL)',0 ADDSTR: DM 'ADD HL,',0 BITSTR: DM 'BIT ',0 DECSTR: DM 'DEC ',0 HLTSTR: DM 'HALT',0 ILLSTR: DM 'illegal',0 IMSTR: DM 'IM ',0 INCSTR: DM 'INC ',0 INSTR: DM 'IN A,(',0 IXSTR: DM 'IX',0 IYSTR: DM 'IY',0 NEGSTR: DM 'NEG',0 LDSTR: DM 'LD ',0 OUTSTR: DM 'OUT (',0 RESSTR: DM 'RES ',0 RSTSTR: DM 'RST ',0 SETSTR: DM 'SET ',0 TMPSTR: ; keine konstanten Daten, vielmehr DM '(IX+00)',0 ; Speicherplatz fuer Index+d HXTBL: DM '0123456799ABCDEF' DATA: DW 77D0H ; Adr. der BASIC-Variable fuer Ausgabe INST: DW 0000H END