copy all local files to repo

cp/m files, sprites, circuit design
This commit is contained in:
Amber
2020-05-15 09:07:45 -04:00
parent 8353edd599
commit 783d32a495
461 changed files with 80153 additions and 0 deletions

View File

@@ -0,0 +1,837 @@
;
; this is a Z80 floating point package from an ancient german computer magazine
; I'm not going to translate this into english
; assemble this source with z80asm and run it under z80sim, if everything
; is working it should print the numbers below
;
; *******************************
; * Fliesskomma-Arithmetik fuer *
; * den Z80-Mikroprozessor *
; * (mc 12/88, Seite 100 *
; *******************************
; ********************************************************
; * Die folgende Testroutine liefert die Ausgabe:
; * 40400000
; * 00700000
; * 7F800000
; * 35BFFFFF
; * 00400000
; * 7F7FFFFF
; * 7F800000
; * 406DB6DB
; * 15400001
START:
LD SP,STACK
LD BC,3F80H ; Aufruf der Additionsroutine
LD DE,0000H ; mit verschiedenen Parametern
PUSH BC ; entspricht 1 + 2
PUSH DE
LD BC,4000H
LD DE,0000H
PUSH BC
PUSH DE
CALL F_ADD
CALL HEXOUT ; anschliessend Ausgabe
LD BC,00F0H ; eine kleine, gerade noch normalisierte
LD DE,0000H ; Zahl, dazu die kleinste normalisierte
PUSH BC ; Zahl mit negativem Vorzeichen addieren
PUSH DE
LD BC,8080H
LD DE,0000H
PUSH BC
PUSH DE
CALL F_ADD
CALL HEXOUT
LD BC,7F00H ; die Summe dieser beiden Zahlen
LD DE,0000H ; ergibt unendlich. Setzt man
PUSH BC ; fuer die zweite Zahl den Wert
PUSH DE ; 7EFFFFFE, so ist das Ergebnis
LD BC,7EFFH ; gerade MAXFLOAT
LD DE,0FFFFH
PUSH BC
PUSH DE
CALL F_ADD
CALL HEXOUT
LD BC,0000H ; Multiplikation testen
LD DE,0003H ; MAXFLOAT * <denormalisierte Zahl>
PUSH BC
PUSH DE
LD BC,7F7FH
LD DE,0FFFFH
PUSH BC
PUSH DE
CALL F_MUL
CALL HEXOUT
LD BC,0080H ; die kleinste normalisierte Zahl
LD DE,0000H ; mit 0.5 multiplizieren
PUSH BC ; (ergibt eine denormalisierte Zahl)
PUSH DE
LD BC,3F00H
LD DE,0000H
PUSH BC
PUSH DE
CALL F_MUL
CALL HEXOUT
LD BC,4000H ; eine sehr grosse Zahl mit zwei
LD DE,0000H ; multiplizieren. Das Ergebnis
PUSH BC ; ist genau MAXFLOAT
PUSH DE
LD BC,7EFFH
LD DE,0FFFFH
PUSH BC
PUSH DE
CALL F_MUL
CALL HEXOUT
LD BC,0000H ; Test der Divisionsroutine
LD DE,0000H ; hier 1 / 0 (ergibt unendlich)
PUSH BC
PUSH DE
LD BC,3F80H
LD DE,0000H
PUSH BC
PUSH DE
CALL F_DIV
CALL HEXOUT
LD BC,40E0H ; jetzt 26 / 7 berechnen
LD DE,0000H
PUSH BC
PUSH DE
LD BC,41D0H
LD DE,0000H
PUSH BC
PUSH DE
CALL F_DIV
CALL HEXOUT
LD BC,1FFFH ; jetzt eine sehr kleine
LD DE,0FFFFH ; denormalisierte Zahl durch
PUSH BC ; eine kleine normalisierte
PUSH DE ; Zahl dividieren
LD BC,0000H
LD DE,0003H
PUSH BC
PUSH DE
CALL F_DIV
CALL HEXOUT
HALT ; Ende des Tests
DEFS 100
STACK:
; ************************************************
; * Zahl in BC-DE in 8 Hexadezimalziffern drucken.
; * Dazu werden nacheinander die Nibble-Paare in
; * B, C, D und E ausgedruckt.
; *
HEXOUT:
LD A,B ; Nacheinander die einzelnen
CALL DIG2 ; Nibble-Paare in A laden
LD A,C ; und ausdrucken
CALL DIG2
LD A,D
CALL DIG2
LD A,E
CALL DIG2
LD A,10
CALL OUTCHAR
LD A,13
CALL OUTCHAR
RET
DIG2:
PUSH AF ; Nibble-Paar ausdrucken
RRCA ; unterstes Nibble retten
RRCA ; oberes Nibble rechtsbuendig
RRCA ; positionieren
RRCA
AND 00001111B
ADD A,90H ; binaer in ASCII (hex)
DAA
ADC A,40H
DAA
CALL OUTCHAR ; Zeichen ausgeben
POP AF ; jetzt unteres Nibble verarbeiten
AND 00001111B ; Nibble maskieren
ADD A,90H ; binaer in ASCII (hex)
DAA
ADC A,40H
DAA
CALL OUTCHAR
RET
OUTCHAR: ; Zeichen auf Console ausgeben
OUT (0),A
RET
; **********************************
; * Globale Konstanten-Definitionen
; * fuer das Fliesskommapaket
; *
MAXEXPO EQU 255 ; Maximal zulaessiger Exponent
BIAS EQU 127 ; Bias des Exponenten
; *************************************************
; * Fliesskomma-Addition in Single-Precision
; * Parameter: Operand 1 und Operand 2 ueber Stack
; * Ergebnis: in BC-DE: MSB in B, LSB in E
; *
; * Es folgen Offset-Definitionen fuer Stack-relativen Zugriff
FHL_ALT EQU 0 ; Top of Stack liegt HL
FADR EQU 2 ; dann die Ruecksprungadresse
OP1 EQU 4 ; jetzt Offset-Definitionen fuer
OP2 EQU 8 ; Parameter-Uebergabe
OPSIZE EQU 4 ; Groesse eines Operanden
F_ADD:
PUSH HL ; alten Basepointer retten
LD (F_STACK),SP ; aktuellen Stackpointer abspeichern
LD HL,(F_STACK) ; und in HL laden (= Basepointer)
PUSH AF ; benoetigte Register retten
PUSH IX
PUSH IY
LD BC,OP1 ; jeztz die Zeiger auf die
ADD HL,BC ; Operanden initialisieren
PUSH HL
POP IX ; IX zeigt auf Operand 1
LD BC,OPSIZE
ADD HL,BC
PUSH HL
POP IY ; IY zeigt auf Operand 2
F_ADSUB:
ADD HL,BC ; HL zeigt jetzt hinter die Operanden!
LD (F_STACK),HL ; diese Adresse fuer's Ende merken
LD A,(IX+3) ; Vorzeichen von Operand 1 laden
LD E,A ; Ergebnisvorzeichen in E, Bit 7
XOR (IY+3) ; mit Vorzeichen von OP2 verknuepfen
LD D,A ; Subtraktionsflag in D, Bit 7
RES 7,(IX+3) ; Vorzeichen in Mantisse 1 loeschen
RES 7,(IY+3) ; Vorzeichen in Mantisse 2 loeschen
; Die Operanden sind jetzt in der Form: 0EEE EEEE EFFF ... FFFF
LD A,(IX+0) ; Differenz OP1 - OP2 bilden
SUB (IY+0)
LD A,(IX+1)
SBC A,(IY+1)
LD A,(IX+2)
SBC A,(IY+2)
LD A,(IX+3)
SBC A,(IY+3)
JR NC,FAD_1 ; Sprung falls OP1 groesser als OP2
PUSH IX ; ansonsten Operanden vertauschen
EX (SP),IY ; (eigentlich nur die Pointer), so
POP IX ; dass IY den Kleineren adressiert
LD A,E ; Ergebnisvorzeichen neu berechnen
XOR D
LD E,A
FAD_1:
LD A,(IX+2)
LD C,(IX+3) ; Exponent der groesseren Zahl laden
SLA A
RL C
JR Z,AD_DN1
SET 7,(IX+2) ; implizite Eins erzeugen
AD_DN1:
LD A,(IY+2)
LD B,(IY+3) ; Exponent der kleineren Zahl laden
SLA A
RL B
JR Z,AD_DN2
SET 7,(IY+2) ; implizite Eins erzeugen
AD_DN2:
PUSH BC ; Jetzt die Register fuer den
PUSH DE ; Blocktransferbefehl retten
LD BC,(OPSIZE*2)-1 ; beide Operanden verschieben
DEC HL ; HL zeigt auf letztes Byte
PUSH HL ; HL nach DE kopieren
POP DE
DEC HL ; HL zeigt auf vorletztes Byte
LDDR ; Verschiebung beider Mantissen
POP DE ; um 8 Bit nach links
POP BC
XOR A
LD (IX+0),A ; Form: FFFF ... FFFF 0000 0000
LD (IY+0),A
LD A,C ; Differenz der Exponenten berechnen
SUB B
LD B,A ; Differenz nach B fuer Loop-Befehl
JR Z,AD_NAP ; falls Null, dann keine Anpassung
CP 25 ; mehr als 24? (Abfrage mit Carry
JP NC,AD_RND ; erfordert Vergleich mit 25)
AD_ANP:
SRL (IY+3) ; Anpassung der zweiten Mantisse
RR (IY+2) ; durch Verschiebung nach rechts
RR (IY+1)
RR (IY+0)
DJNZ AD_ANP ; Loop-Befehl bis B = 0
AD_NAP:
BIT 7,D ; Subtraktion oder Addition?
JR NZ,SUBTR ; ggf. zur Subtraktion springen
LD A,(IX+0) ; jetzt werden die beiden Mantissen
ADD A,(IY+0) ; zueinander addiert
LD (IX+0),A
LD A,(IX+1)
ADC A,(IY+1)
LD (IX+1),A
LD A,(IX+2)
ADC A,(IY+2)
LD (IX+2),A
LD A,(IX+3)
ADC A,(IY+3)
LD (IX+3),A
JR NC,AD_RND ; kein Ueberlauf --> zum Runden
RR (IX+3) ; Ueberlauf einschieben
RR (IX+2) ; und Exponent erhoehen
RR (IX+1) ; durch die Vorgeschichte ist
RR (IX+0) ; gesichert, dass B Null ist; BC
INC BC ; enthaelt den 16-Bit-Exponent
JR AD_RND ; und zum Runden
SUBTR:
LD A,(IX+0) ; Die beiden Mantissen werden
SUB (IY+0) ; voneinander subtrahiert
LD (IX+0),A
LD A,(IX+1)
SBC A,(IY+1)
LD (IX+1),A
LD A,(IX+2)
SBC A,(IY+2)
LD (IX+2),A
LD A,(IX+3)
SBC A,(IY+3)
LD (IX+3),A
JP M,AD_RND ; bei fuehrender Eins zum Runden
JR NZ,AD_NRM ; ungleich Null: Normalisieren
CP (IX+2) ; Rest der Mantisse auch Null?
JR NZ,AD_NRM
CP (IX+1)
JR NZ,AD_NRM
CP (IX+0)
JR Z,AD_ZERO ; alles Null --> Ergebnis ist Null
AD_NRM:
XOR A ; A = 0
AD_NR1:
CP C ; Exponent ist Null?
JR NZ,AD_NR2 ; nein, Normierung moeglich
CP B ; oberes Byte auch Null?
JR Z,AD_RND ; dann ist Ergebnis denormalisiert
AD_NR2:
DEC BC ; Exponent erniedrigen
SLA (IX+0) ; Mantisse normalisieren bis
RL (IX+1) ; fuehrende Eins auftaucht
RL (IX+2)
RL (IX+3)
JP P,AD_NR1 ; weiter bis fuehrende Eins auftaucht
AD_RND:
LD A,(IX+0) ; jetzt Runden auf Bit hinter
ADD A,80H ; Mantisse
JR NC,AD_NOV ; kein Uebertrag?
INC (IX+1) ; doch, naechstes Mantissenbyte
JR NZ,AD_NOV ; behandeln, jetzt auf Null pruefen,
INC (IX+2) ; da der INC-Befehl kein Carry liefert
JR NZ,AD_NOV
INC (IX+3)
JR NZ,AD_NOV
SCF ; Eins erzeugen
RR (IX+3) ; bei Ueberlauf Mantisse durch
RR (IX+2) ; Rechtsschieben wieder normalisieren
RR (IX+1) ; (nur noch 24 Bit noetig)
INC BC ; und Exponent korrigieren
AD_NOV:
XOR A ; A = 0
CP (IX+3) ; Mantisse auf Null pruefen
JR NZ,AD_NOZ
CP (IX+2)
JR NZ,AD_NOZ
CP (IX+1) ; alle Mantissenbytes Null?
JR NZ,AD_NOZ ; dann ist auch das Ergebnis Null
AD_ZERO: ; Null Ergebnis aufbauen
LD B,A
LD C,A
LD D,A
LD E,A
JR AD_EXIT ; dann Routine verlassen
AD_NOZ:
CP B ; A ist 0
LD A,MAXEXPO ; Exponent oberstes Byte ungleich Null?
JR NZ,AD_OVR ; dann ist Ueberlauf eingetreten
CP C ; oder genau maxexpo erreicht?
JR NZ,AD_NUE ; nein, --> kein Ueberlauf
AD_OVR:
LD C,A ; Exponent auf maxexpo setzen
XOR A ; und Mantisse auf Null
LD (IX+3),A ; fuer unendlich
LD (IX+2),A
LD (IX+1),A
JR AD_DEN
AD_NUE:
XOR A ; A = 0
CP C ; Exponent Null (Zahl denormalisiert)?
JR Z,AD_DEN ; ja, -->
SLA (IX+1) ; fuehrendes Bit wird nicht gespeichert
RL (IX+2) ; daher Mantisse um 1 Bit nach links
RL (IX+3)
AD_DEN:
LD B,C ; Ergebnis aufbauen: Exponent in B
LD C,(IX+3) ; Mantisse oberstes Byte
LD D,(IX+2)
SLA E ; Vorzeichen aus E in Carry schieben
LD E,(IX+1)
RR B ; Vorzeichen in Ergebnis einschieben
RR C
RR D
RR E
AD_EXIT:
POP IY ; Register restaurieren
POP IX
POP AF
POP HL
LD (F_HL),HL ; HL zwischenspeichern
EX (SP),HL ; alte Ruecksprungadresse in HL
LD SP,(F_STACK) ; Stack zuruecksetzen
PUSH HL ; Ruecksprungadresse ablegen
LD HL,(F_HL) ; HL wieder laden
RET ; Ende des Unterprogramms
; *************************************************
; * Fliesskomma-Subtraktion in Single-Precision
; * Parameter: Operand 1 und Operand 2 ueber Stack
; * Ergebnis: in BC-DE: MSB in B, LSB in E
; *
F_SUB:
PUSH HL ; alten Basepointer retten
LD (F_STACK),SP ; aktuellen Stackpointer abspeichern
LD HL,(F_STACK) ; und in HL laden (= Basepointer)
PUSH AF ; benoetigte Register retten
PUSH IX
PUSH IY
LD BC,OP1
ADD HL,BC
PUSH HL
POP IX ; IX zeigt auf Operand 1
LD BC,OPSIZE
ADD HL,BC
PUSH HL
POP IY ; IY zeigt auf Operand 2
LD A,80H
XOR (IY+3) ; Vorzeichenbit von Operand 2 umdrehen
LD (IY+3),A ; wieder abspeichern
JP F_ADSUB ; jetzt weiter bei Additionsroutine
; *************************************************
; * Fliesskomma-Multiplikation in Single-Precision
; * Parameter: Operand 1 und Operand 2 ueber Stack
; * Ergebnis: in BC-DE: MSB in B, LSB in E
; *
TEMP EQU -10 ; Offset lokale Variable (6 Byte)
F_MUL:
PUSH HL ; alten Basepointer retten
LD (F_STACK),SP ; aktuellen Stackpointer abspeichern
LD HL,(F_STACK) ; und in HL laden (= Basepointer)
PUSH AF ; benoetigte Register retten
PUSH IX
PUSH IY
LD BC,OP1
ADD HL,BC
PUSH HL
EX (SP),IX ; IX zeigt auf Operand 1
; 2 Dummy-Byte auf Stack fuer lokale
LD BC,OPSIZE ; Variable bleiben stehen
ADD HL,BC
PUSH HL
EX (SP),IY ; IY zeigt auf Operand 2
PUSH HL ; insgesamt 6 Byte fuer lokale Variable
ADD HL,BC ; HL zeigt jetzt hinter die Operanden!
LD (F_STACK),HL
LD A,(IX+3) ; Ergebnisvorzeichen bestimmen
XOR (IY+3)
LD C,A ; Vorzeichen in C Bit 7 merken
LD D,0 ; Exponent 1 laden
LD E,(IX+3)
LD A,(IX+2) ; Operand um 8 Bit nach links schieben
LD (IX+3),A
RES 7,(IX+3) ; implizite Null vorbesetzen
SLA A ; Exponent unterstes Bit in Carry
RL E ; und in E einschieben
JR Z,MU_DN1 ; falls Null, dann OP1 denormalisieren
SET 7,(IX+3) ; implizite Eins erzeugen
DEC DE ; Bias kompensieren
MU_DN1:
LD A,(IX+1) ; jetzt restliche Bytes verschieben
LD (IX+2),A
LD A,(IX+0)
LD (IX+1),A
XOR A ; unterste Mantissenbits loeschen
LD (IX+0),A ; Form: FFFF ... FFFF 0000 0000
LD (IX+TEMP+5),A ; lokale Variable mit Null vorbesetzen
LD (IX+TEMP+4),A
LD (IX+TEMP+3),A
LD (IX+TEMP+2),A
LD (IX+TEMP+1),A
LD (IX+TEMP+0),A
LD H,A ; Exponent 2 in HL aufbauen
LD L,(IY+3)
LD A,(IY+2)
RES 7,(IY+2) ; implizite Null vorbesetzen
SLA A
RL L
JR Z,MU_DN2 ; gleich Null, dann Op2 denormalisieren
SET 7,(IY+2) ; implizite Eins erzeugen
DEC HL ; Bias kompensieren
MU_DN2:
ADD HL,DE ; Exponenten aufaddieren
LD DE,3-BIAS ; Bias-3 subtrahieren
ADD HL,DE ; bzw. 3-Bias addieren
JP P,MU_NOZ
LD A,L ; Exponent kleiner als -24?
CP -24
JR NC,MU_NOZ
JP MU_ZERO ; ja, dann ist das Ergebnis Null
MU_NOZ:
LD B,24 ; Multiplikationsschleifenzaehler
LD DE,0 ; Hilfsregister fuer Multiplikand
MU_MUL:
SRL (IX+3) ; Multiplikand nach rechts schieben
RR (IX+2)
RR (IX+1)
RR (IX+0)
RR D ; DE als Verlaengerung von Operand 1
RR E
SLA (IY+0) ; Multiplikator nach links schieben
RL (IY+1)
RL (IY+2) ; falls fuehrendes Bit Null ist, dann
JR NC,MU_NAD ; muss nicht addiert werden
LD A,(IX+TEMP+0) ; sonst Multiplikand aufaddieren
ADD A,E
LD (IX+TEMP+0),A
LD A,(IX+TEMP+1)
ADC A,D
LD (IX+TEMP+1),A
LD A,(IX+TEMP+2)
ADC A,(IX+0)
LD (IX+TEMP+2),A
LD A,(IX+TEMP+3)
ADC A,(IX+1)
LD (IX+TEMP+3),A
LD A,(IX+TEMP+4)
ADC A,(IX+2)
LD (IX+TEMP+4),A
LD A,(IX+TEMP+5)
ADC A,(IX+3)
LD (IX+TEMP+5),A
MU_NAD:
DJNZ MU_MUL ; Schleife durchlaufen
LD A,(IX+TEMP+5)
OR A ; Flags setzen
JP M,MU_RND ; bei fuerender Eins zum Runden
JR NZ,MU_NOR ; ungleich Null --> normalisieren
CP (IX+TEMP+4)
JR NZ,MU_NOR
CP (IX+TEMP+3)
JR NZ,MU_NOR
CP (IX+TEMP+2)
JR NZ,MU_NOR
JP MU_ZERO ; Mantisse komplett Null --> Null
MU_NOR:
XOR A ; A = 0
OR H ; Exponent ist negativ?
JP M,MU_UNT ; ggf. Unterlauf behandeln
MU_NR1:
XOR A ; A = 0
CP L ; Exponent = Null?
JR NZ,MU_NR2
CP H ; bei Null zum Runden
JR Z,MU_RND
MU_NR2:
DEC HL ; Exponent erniedrigen
SLA (IX+TEMP+0)
RL (IX+TEMP+1)
RL (IX+TEMP+2) ; Mantisse solange nach links
RL (IX+TEMP+3) ; verschieben bis fuerende Eins
RL (IX+TEMP+4) ; auftaucht
RL (IX+TEMP+5)
JP P,MU_NR1
MU_RND:
LD A,(IX+TEMP+2) ; jetzt Runden auf Bit hinter
ADD A,80H ; Mantisse
JR NC,MU_NOV ; kein Uebertrag?
INC (IX+TEMP+3) ; doch, naechstes Mantissenbyte
JR NZ,MU_NOV ; behandeln, jetzt auf Null pruefen
INC (IX+TEMP+4) ; da der INC-Befehl kein Carry liefert
JR NZ,MU_NOV
INC (IX+TEMP+5)
JR NZ,MU_NOV
SCF ; Eins erzeugen
RR (IX+TEMP+5) ; bei Ueberlauf Mantisse durch
RR (IX+TEMP+4) ; Rechtsschieben wieder normalisieren
RR (IX+TEMP+3)
INC HL ; und Eponent korrigieren
MU_NOV:
XOR A ; A = 0
CP H ; Exponent pruefen
LD A,MAXEXPO ; A vorbesetzen
JR NZ,MU_OVR ; groesser Null: Ueberlauf behandeln
CP L ; oder genau maxexpo erreicht?
JR NZ,MU_NUE ; nein, kein Ueberlauf
MU_OVR:
LD L,MAXEXPO ; Ueberlauf: Exponent = maxexpo
XOR A ; Mantisse = Null
LD (IX+TEMP+5),A
LD (IX+TEMP+4),A
LD (IX+TEMP+3),A
JR MU_DEN
MU_NUE:
XOR A ; A = 0
CP L ; Exponent ist Null?
JR Z,MU_DEN ; ja, Ergebnis ist denormalisiert
SLA (IX+TEMP+3) ; nein, fuehrendes Mantissenbit
RL (IX+TEMP+4) ; rausschieben
RL (IX+TEMP+5)
MU_DEN:
SLA C ; Vorzeichen in Carry schieben
LD B,L ; Exponent einsetzen
LD C,(IX+TEMP+5)
LD D,(IX+TEMP+4)
LD E,(IX+TEMP+3)
RR B ; und Vorzeichen einschieben
RR C
RR D ; Form: SEEE EEEE EFFF FFFF ... FFFF
RR E
MU_RES:
POP HL ; lokale Variable deallozieren
POP HL
POP HL
POP IY ; Register restaurieren
POP IX
POP AF
POP HL
LD (F_HL),HL ; Parameter vom Stack deallozieren
EX (SP),HL
LD SP,(F_STACK)
PUSH HL
LD HL,(F_HL)
RET ; und return
MU_ZERO:
XOR A ; Ergebnis ist Null
LD B,A
LD C,A
LD D,A
LD E,A
JR MU_RES
MU_UNT:
LD A,L ; Exponent in A
NEG ; negieren fuer Schleifenzaehler
CP 24 ; totaler Ueberlauf?
JR NC,MU_ZERO ; ja, dann ist Ergebnis Null
LD B,A ; in B fuer Loop
MU_SHR:
SRL (IX+TEMP+5) ; Mantisse denormalisieren
RR (IX+TEMP+4) ; bis Exponent Null ist
RR (IX+TEMP+3)
DJNZ MU_SHR
LD L,B ; Exponent in Register L = B = 0
JP MU_DEN ; denormalisiertes Ergebnis erzeugen
; *************************************************
; * Fliesskomma-Division in Single-Precision
; * Parameter: Operand 1 und Operand 2 ueber Stack
; * Ergebnis: in BC-DE: MSB in B, LSB in E
; *
F_DIV:
PUSH HL ; alten Basepointer retten
LD (F_STACK),SP ; aktuellen Stackpointer abspeichern
LD HL,(F_STACK) ; und in HL laden (= Basepointer)
PUSH AF ; benoetigte Register retten
PUSH IX
PUSH IY
LD BC,OP1
ADD HL,BC
PUSH HL
EX (SP),IX ; IX zeigt auf Operand 1
; 2 Dummy-Byte auf Stack fuer lokale
LD BC,OPSIZE ; Variable bleiben stehen
ADD HL,BC
PUSH HL
EX (SP),IY ; IY zeigt auf Operand 2
PUSH HL ; insgesamt 6 Byte fuer lokale Variable
ADD HL,BC ; HL zeigt jetzt hinter die Operanden!
LD (F_STACK),HL
LD A,(IX+3) ; Ergebnisvorzeichen bestimmen
XOR (IY+3)
LD C,A ; Vorzeichen in C Bit 7 merken
LD H,0 ; Exponent 1 laden
LD L,(IX+3)
LD A,(IX+2)
RES 7,(IX+2) ; implizite Null vorbesetzen
SLA A ; Exponent unterstes Bit in Carry
RL L ; und in E einschieben
JR Z,DV_DN1 ; falls Null, dann Op1 denormalisieren
SET 7,(IX+2) ; implizite Eins erzeugen
DEC HL ; Bias kompensieren
DV_DN1:
LD D,0 ; Exponent 2 in DE aufbauen
LD E,(IY+3)
LD A,(IY+2)
LD (IY+3),A ; Mantisse um 8 Bit verschieben
RES 7,(IY+3) ; implizite Null vorbesetzen
SLA A
RL E
JR Z,DV_DN2 ; gleich Null, dann Op2 denormalisieren
SET 7,(IY+3) ; implizite Eins erzeugen
DEC DE ; Bias kompensieren
DV_DN2:
LD A,(IY+1) ; jetzt restliche Bytes verschieben
LD (IY+2),A
LD A,(IY+0)
LD (IY+1),A
XOR A ; A = 0
LD (IY+0),A ; Form: FFFF ... FFFF 0000 0000
SRL (IY+3)
RR (IY+2)
RR (IY+1)
RR (IY+0) ; Form: 0FFF ... FFFF F000 0000
JR NZ,DV_NZ1 ; Mantisse 2 auf Null pruefen
CP (IY+1)
JR NZ,DV_NZ1
CP (IY+2)
JR NZ,DV_NZ1
CP (IY+3)
JR NZ,DV_NZ1
JP MU_OVR ; Bei Division durch Null: unendlich
DV_NZ1:
XOR A ; Carry-Flag loeschen
SBC HL,DE ; Exponenten subtrahieren
LD DE,BIAS ; Bias addieren
ADD HL,DE
BIT 7,H ; Exponent positiv?
JR Z,DV_NOZ
LD A,L ; Exponent kleiner als -24?
JR NC,DV_NOZ
JP MU_ZERO ; ja, dann ist das Ergebnis Null
DV_NOZ:
PUSH BC ; Vorzeichen retten
LD DE,25 ; Exponent um 25 erhoehen
ADD HL,DE ; jetzt ist er sicher groesser als Null
XOR A ; A = 0
LD B,(IX+2) ; Divident in Register kopieren
LD C,(IX+1)
LD D,(IX+0)
LD E,A ; die untersten Bits sind Null
CP D ; ist Dividend Null?
JR NZ,DV_NZ2
CP C
JR NZ,DV_NZ2
CP B
JR NZ,DV_NZ2
POP BC ; Stack bereinigen (Vorzeichen laden)
JP MU_ZERO ; und Null als Ergebnis ausgeben
DV_NZ2:
LD (IX+TEMP+5),A ; Ergebnis vorbesetzen
LD (IX+TEMP+4),A
LD (IX+TEMP+3),A
LD (IX+TEMP+2),A
DV_NLP:
BIT 6,(IY+3) ; ist der Divisor normalisiert
JR NZ,DV_NOR ; ja, -->
INC HL ; nein, Exponent erhoehen
SLA (IY+0) ; Divisor verschieben bis in
RL (IY+1) ; Form 01FF ...
RL (IY+2)
RL (IY+3)
JR DV_NLP
DV_NOR:
SRL B
RR C
RR D
RR E ; Form: 0FFF ... FFFF F000 0000
DV_LOP:
LD (IX+3),B ; Dividend zwischenspeichern
LD (IX+2),C ; die Speicherplaetze von Op1
LD (IX+1),D ; stehen zur Verfuegung, da wir OP1
LD (IX+0),E ; in die Register BC-DE kopiert haben
LD A,E ; jetzt Divisor abziehen
SUB (IY+0)
LD E,A
LD A,D
SBC A,(IY+1)
LD D,A
LD A,C
SBC A,(IY+2)
LD C,A
LD A,B
SBC A,(IY+3)
LD B,A
JR NC,DV_ONE ; kein Carry: Divisor passt
LD E,(IX+0) ; zurueckkopieren
LD D,(IX+1) ; Carry bleibt dabei erhalten
LD C,(IX+2)
LD B,(IX+3)
DV_ONE:
CCF ; Carry-Flag umkehren
RL (IX+TEMP+2) ; Ergebnis aufbauen
RL (IX+TEMP+3)
RL (IX+TEMP+4)
RL (IX+TEMP+5)
SLA E ; Dividend verschieben
RL D
RL C
RL B
DEC HL ; Exponent erniedrigen
XOR A ; A = 0
CP L ; Exponent = Null ?
JR NZ,DV_DIV
CP H
JR Z,DV_DEN ; falls Null, dann denormalisiert
DV_DIV:
BIT 0,(IX+TEMP+5) ; fuerende Eins in Ergebnis-Mantisse?
JR Z,DV_LOP ; nein, weiter rechnen
DV_DEN:
LD B,(IX+TEMP+5) ; hoechstes Bit merken
LD A,(IX+TEMP+4)
LD (IX+TEMP+5),A ; Mantisse in Form
LD A,(IX+TEMP+3) ; FFFF ... FFFF 0000 0000
LD (IX+TEMP+4),A
LD A,(IX+TEMP+2)
LD (IX+TEMP+3),A
RR B ; hoechstes Bit einschieben
RR (IX+TEMP+5)
RR (IX+TEMP+4)
RR (IX+TEMP+3) ; Form: FFFF ... FFFF F000 0000
RR (IX+TEMP+2)
POP BC ; Vorzeichen wieder laden
XOR A ; A = 0
CP (IX+TEMP+5) ; Mantisse ist Null?
JR NZ,DV_NZ3
CP (IX+TEMP+4)
JR NZ,DV_NZ3
CP (IX+TEMP+3)
JR NZ,DV_NZ3
CP (IX+TEMP+2)
JP Z,MU_ZERO ; dann ist Ergebnis auch Null
DV_NZ3:
JP MU_RND ; sonst weiter wie bei Multiplikation
F_STACK:
DEFS 2 ; Hilfsspeicher fuer Stackpointer
F_HL:
DEFS 2 ; Hilfsspeicher fuer Basepointer HL
END

View File

@@ -0,0 +1,638 @@
TITLE 'Z80-Disassembler'
; Hardware-unabhaengiger, ROM-faehiger Z80-Disassembler
;
; Die Adresse, ab der disassembliert serden soll, ist in der
; 16-Bit Speicherzelle DADR abzulegen. Danach kann eines der
; Entrys DISSCR (Ausgabe eines Bildschirms) oder DISLIN
; (Ausgabe einer Zeile) aufgerufen werden. Da die Folgeadressen
; durch das Programm ebenfalls wieder in der Speicherzelle
; DADR abgelegt werden, ist mehrfacher Aufruf ohne Laden
; von neuen Adressen moeglich.
; Zur Ausgabe muss ein Unterprogramm mit dem Namen PRTSTR
; erstellt werden, dem in HL die Adresse eines Null-terminierten
; Strings uebergeben wird.
;
; 27-JUN-89 Udo Munk
LPP EQU 15 ; Anzahl Zeilen/Bildschirm Ausgabe
MNEPOS EQU 11H ; Offset des Mnemonics in Ausgabe-Workspace
; Disassembliere einen Bildschirm voll
DISSCR: LD B,LPP ; einen Bildschirm mit LPP Zeilen
$DLP1: PUSH BC ; disassemblieren
CALL DISLIN
POP BC
DJNZ $DLP1
RET
; Disassembliere eine Zeile
DISLIN: CALL CLWO ; Workspace fuer eine Zeile Ausgabe loeschen
LD HL,WRKS ; Adresse der Ausgabe-Workspace -> HL
LD DE,(DADR) ; Disassemblier-Adresse -> DE
CALL PRBY ; Adresse in DE ausgeben
INC HL ; Blank ausgeben
LD (PRTMP),HL ; vordere Printposition retten
LD C,0 ; Steuerflag loeschen
DEC DE ; laufende Adr.-1 -> DE
$DL13: CALL PRNB ; laufendes Byte ausgeben
LD A,(DE) ; laufendes Byte -> A
LD B,A ; und in B retten
CP 0EDH ; Preafix ED ?
JR NZ,$DL14
SET 4,C ; ja, ED-Flag setzen
JR $DL13 ; und naechstes Byte bearbeiten
$DL14: CP 0FDH ; Preafix FD ?
JR NZ,$DL15
SET 6,C ; ja, FD-Flag setzen
JR $DL16 ; und Index-Flag setzen
$DL15: CP 0DDH ; Preafix DD ?
JR NZ,$DL17
$DL16: SET 5,C ; Index-Flag fuer IX/IY-Adressierung setzen
LD HL,(PRTMP) ; vordere Printposition -> HL
JR $DL13 ; naechstes Byte bearbeiten
$DL17: LD HL,WRKS+MNEPOS ; HL auf Operator Position setzen
; nach Praefix CB
CB: LD A,B ; Befehlsbyte aus B holen
CP 0CBH ; Preafix CB ?
JP NZ,OHNE
INC DE ; ja, Pointer auf naechstes Byte setzen
BIT 5,C ; IX/IY-Flag ?
JR Z,$DL18
INC DE ; ja, Pointer auf naechstes Byte setzen
$DL18: LD A,(DE) ; naechstes Byte -> A
LD B,A ; und in B retten
PUSH DE ; Disassemblieradr. retten
LD D,MNETAB > 8 ; High-Byte Operatorentabelle -> D
LD E,0E8H ; DE = Pointer auf "SET"
CP 0C0H ; SET ?
JR NC,$DL19
LD E,0E4H ; nein, DE = Pointer auf "RES"
CP 80H ; RES ?
JR NC,$DL19
LD E,0E0H ; nein, DE = Pointer auf "BIT"
CP 40H ; BIT ?
JR NC,$DL19
AND 38H ; loesche Bits 0..2 und 6..7
RRCA ; Division durch 2
ADD A,CBMTAB & 0FFH ; zur Basis der CB-Mnemonics addieren
LD E,A
LD D,CBMTAB > 8 ; DE = Pointer auf CB-Mnemonic
$DL19: CALL TRBY ; Mnemonic ausgeben
POP DE ; akt. Disassemblieradr. wieder -> DE
LD A,B ; Byte wieder -> A
BIT 5,C ; IX/IY-Flag ?
JR Z,$DL20
DEC DE ; eins zurueck bei IX/IY-Adressierung
$DL20: DEC DE ; Pointer wieder auf CB-Preafix
CP 40H ; CB-Befehl < 40H ?
JR C,$DL21
AND 38H ; nein, Bits 0..2 und 6..7 loeschen
RRCA ; Division durch 8 -> 1. Operanden
RRCA
RRCA
CALL PRO1 ; 1. Operanden ausgeben
LD A,B ; Byte wieder -> A
SET 7,C ; Komma-Flag setzen
$DL21: AND 7 ; Bits 3..7 loeschen -> 2. Operanden
SET 4,A ; Buchstaben-Flag setzen
CALL PRO1 ; 2. Operanden ausgeben
CALL PRNB ; Befehlsbyte vorne ausgeben
JP INAD ; fertig, Adresse merken und Workspace ausgeben
; ohne Preafix CB/ED
OHNE: PUSH DE ; Disassemblieradr. retten
BIT 4,C ; ED-Flag ?
JP NZ,ED
CP 40H ; nein, < 40H ?
JR C,$DL25
CP 80H ; nein, > 80H ?
JR NC,$DL23
LD E,50H ; nein, DE = Pointer auf "LD"
CP 76H ; HALT ?
JR NZ,$DL22
LD E,5CH ; nein, DE = Pointer auf "HALT"
$DL22: JR $DL26 ; Mnemonic ausgeben
$DL23: CP 0C0H ; > C0H ?
JR NC,$DL24
AND 38H ; ja, Bits 0..2 und 6..7 loeschen
RRCA ; Division durch 2 -> Operator
LD E,A ; Operator -> E
JR $DL26 ; Mnemonic ausgeben
$DL24: SUB 80H ; wenn > C0H, -80 -> Tabellenoperator
$DL25: LD E,A ; Operator -> E
LD D,CODTAB > 8 ; High-Byte Operatortabelle -> D
LD A,(DE) ; LSB Mnemonic-Adresse -> A
LD E,A ; und nach E
$DL26: LD D,MNETAB > 8 ; MSB Mnemonic-Adresse -> D
CALL TRBY ; Mnemonic ausgeben
POP DE ; akt. Disassemblieradr. wieder -> DE
LD A,B ; Befehlsbyte wieder -> A
PUSH DE ; Disassemblieradr. retten
CP 40H ; Byte < 40 ?
JR C,$DL30
CP 80H ; nein, > 80 ?
JR NC,$DL28
CP 76H ; nein, HALT ?
JR NZ,$DL27
LD A,0FFH ; ja, leeren Operanden -> A
JR $DL31 ; Operanden ausgeben
$DL27: AND 38H ; loesche Bits 0..2 und 6..7
RRCA ; Division durch 8 -> 1. Operanden
RRCA
RRCA
SET 4,A ; Buchstabenflag setzen
JR $DL31 ; Operanden ausgeben
$DL28: CP 0C0H ; > C0 ?
JR NC,$DL29
CP 90H ; > 90 ?
JR C,$DL51
AND 0F8H ; ja, Register-Bits loeschen
CP 98H ; "SBC" ?
JR Z,$DL51
LD A,B ; Byte wieder -> A
AND 7 ; nur Register Bits uebrig lassen
SET 4,A ; Buchstaben-Flag setzen
JR $DL52
$DL51: LD A,17H ; ja, 17 = Register A ausgeben
JR $DL31 ; Operanden ausgeben
$DL29: SUB 80H ; wenn > C0, -80 -> Operandentabelle
$DL30: LD E,A ; LSB Operandentabelle -> E
LD D,OPETAB > 8 ; MSB Operandentabelle -> D
LD A,(DE) ; 1. Operanden -> A
$DL31: POP DE ; akt. Disassemblieradr. wieder -> DE
CALL PRO1 ; 1. Operanden ausgeben
LD A,B ; Befehlsbyte wieder -> A
PUSH DE ; akt. Disassemblieradr. retten
CP 40H ; < 40 ?
JR C,$DL34
CP 0C0H ; nein, < C0 ?
JR NC,$DL33
CP 76H ; ja, HALT ?
JR NZ,$DL32
LD A,0FFH ; ja, wieder leeren Operanden -> A
JR $DL35 ; Operanden ausgeben
$DL32: AND 7 ; loesche Bits 3..7, -> 2. Operanden
SET 4,A ; Buchstabenflag setzen
JR $DL35 ; Operanden ausgeben
$DL33: SUB 80H ; wenn > C0 : 80 abziehen
$DL34: ADD A,80H ; LSB Operandentabelle -> A
LD E,A ; und -> E
LD D,OPETAB > 8 ; MSB Operandentabelle -> D
LD A,(DE) ; 2. Operanden -> A
$DL35: POP DE ; akt. Disassemblieradr. wieder -> DE
SET 7,C ; Komma-Flag setzen
CALL PRO1 ; 2. Operanden ausgeben
JP INAD ; fertig, Adresse merken und Workspace ausgeben
; nach Preafix ED
ED: SUB 40H ; 40 vom 2. Byte subtrahieren
JP C,ERRO ; Fehler wenn carry
CP 60H ; 2. Byte < A0 ?
JR NC,$DL36
CP 40H ; ja, >= 60 ?
JP NC,ERRO ; ja, Fehler
JR $DL37 ; nein, weiter
$DL36: SUB 20H ; aus 60..7F wird 00..20
$DL37: ADD A,80H ; LSB Operatortabelle -> A
LD E,A ; und -> E
LD D,CODTAB > 8 ; MSB Operatortabelle -> D
LD A,(DE) ; LSB Mnemonic-Adresse -> A
CP 0FFH ; leer ?
JP Z,ERRO ; ja, Fehler
LD E,A ; nein, -> E
LD D,MNETAB > 8 ; MSB Mnemonic-Adresse -> D
CALL TRBY ; Mnemonic ausgeben
POP DE ; Disassemblieradr. wieder -> DE
LD A,B ; Befehlsbyte wieder -> A
CP 80H ; < 80 ?
JP NC,INAD ; nein, Workspace ausgeben und fertig
PUSH DE ; Disassemblieradr. retten
SUB 40H ; LSB 1. Operanden in A
LD E,A ; und -> E
LD D,OP2TAB > 8 ; MSB 2. Operanden -> D
LD A,(DE) ; 1. Operanden -> A
POP DE ; akt. Disassemblieradr. wieder -> DE
CALL PRO1 ; 1. Operanden ausgeben
LD A,B ; Befehlsbyte wieder -> A
CP 80H ; < 80 ?
JP NC,INAD ; ja, Workspace ausgeben und fertig
PUSH DE ; akt. Disassemblieradr. retten
LD E,A ; LSB Operandentabelle -> E
LD D,OP2TAB > 8 ; MSB Operandentabelle -> D
LD A,(DE) ; 2. Operanden -> A
SET 7,C ; Buchstabenflag setzen
$DL52: POP DE ; akt. Disassemblieradr. retten
CALL PRO1 ; 2. Operanden ausgeben
JP INAD ; fertig, Adresse merken und Workspace ausgeben
; Operand 1 ausgeben
PRO1: CP 0FFH ; leere Operand ?
RET Z ; ja, fertig
CP 17H ; nein, Register "A" ausgeben ?
JR NZ,$DL01
LD A,18H ; ja, umkodieren
$DL01: CP 16H ; Register "(HL)" ausgeben ?
JR NZ,$DL02
LD A,0B4H ; ja, umkodieren
$DL02: BIT 7,C ; 2. Operand ?
JR Z,$DL03
LD (HL),',' ; ja, "," ausgeben
INC HL ; naechste Printposition -> HL
$DL03: BIT 7,A ; "(...)" ?
JR Z,$DL04
LD (HL),'(' ; ja, "(" ausgeben
INC HL ; naechste Printposition -> HL
$DL04: BIT 4,A ; Buchstabe ?
JR NZ,PRBU ; ja, Buchstaben ausgeben
BIT 6,A ; nein, Bitnummer/RST-Adresse ?
JR NZ,DIST ; ja, Distanz ausgeben
BIT 5,A ; nein, Bitnummer ?
JR NZ,PRO2 ; ja, RST ausgeben
AND 7 ; nein, Bits 3..7 loeschen
CALL PRCH ; Hexbyte ausgeben
RET
; RST ausgeben
PRO2: PUSH AF ; A retten
AND 6 ; loesche Bits 0 und 4..7
RRCA ; Division durch 2
CALL PRCH ; oberes Nibble ausgeben
POP AF ; A wieder herstellen
BIT 0,A ; RST x8 ?
LD A,'0' ; nein, "0" -> A
JR Z,$DL05
LD A,'8' ; ja, "8" -> A
$DL05: LD (HL),A ; "0" oder "8" ausgeben
INC HL ; naechste Printposition -> HL
RET
; Distanz ausgeben
DIST: BIT 0,A ; relative Distanz ?
JR Z,PR_N ; nein, N ausgeben
CALL PRNB ; Byte vorne ausgeben
PUSH DE ; akt. Disassemblieradr. retten
LD A,(DE) ; Distanzbyte -> A
INC DE ; Disassemblieradr. erhoehen
RLCA ; Bit 7 Distanzbyte -> carry
RRCA
JR NC,$DL06 ; Vorwaertsprung
SET 0,C ; Flag fuer Rueckwaertssprung setzen
$DL06: ADD A,E ; Distanz zu PC addieren
LD E,A
BIT 0,C ; Flag testen
JR NC,$DL07 ; kein Ueberlauf
JR NZ,$DL08 ; Rueckwaertssprung
INC D ; MSB PC erhoehen
JR $DL08 ; Zieladresse ausgeben
$DL07: JR Z,$DL08 ; bei Vorwaertssprung Zieladresse ausgeben
DEC D ; sonst MSB PC erniedrigen
$DL08: CALL PRBY ; Zieladresse in DE ausgeben
POP DE ; akt. Disassemblieradresse wieder -> DE
RET
; N ausgeben
PR_N: PUSH AF ; A retten
BIT 1,A ; N ?
JR Z,PRNN ; nein, NN ausgeben
CALL PRVH ; ja, Byte vorne und hinten ausgeben
JR $DL12 ; ")" bearbeiten
; NN ausgeben
PRNN: CALL PRNB ; Byte vorne ausgeben
CALL PRVH ; Byte vorne und hinten ausgeben
DEC DE ; DE -> LSB von NN
CALL PRBH ; Byte hinten ausgeben
INC DE ; akt. Disassemblieradr. wieder -> DE
JR $DL12 ; ")" bearbeiten
; Buchstaben ausgeben
PRBU: PUSH AF ; A retten
PUSH BC ; Flags in C retten
PUSH DE ; akt. Disassemblieradr. retten
LD B,1 ; Anzahl = 1
LD DE,REGTAB ; DE zeigt auf die Register-Namen
BIT 5,A ; 2 Buchstaben ?
JR Z,$DL09
INC B ; ja, Anzahl erhoehen
$DL09: BIT 6,A ; Sprungbedingung ?
JR Z,$DL10
LD DE,SPRTAB ; ja, DE zeigt auf Condition-Namen
$DL10: RES 7,A ; Klammer-Bit loeschen
CP 34H ; "(HL)" ?
JR NZ,$DL11
BIT 5,C ; ja, Indexregister ?
JR Z,$DL11
LD A,0AH ; ja, A -> IX-Register
BIT 6,C ; IY-Register ?
JR Z,$DL11
LD A,0CH ; ja, A -> IY-Register
$DL11: AND 0FH ; loesche oberes Nibble
ADD A,E ; und addiere zur Basis in DE
LD E,A
$DL50: LD A,(DE) ; Zeichen -> A
LD (HL),A ; Zeichen ausgeben
INC DE ; Tabellen-Adresse erhoehen
INC HL ; naechste Printposition
DJNZ $DL50 ; naechstes Zeichen
POP DE ; Register wieder herstellen
POP BC
POP AF
PUSH AF ; A retten
CP 0B4H ; "(HL)" ?
JR NZ,$DL12
BIT 5,C ; nein, Indexregister ?
JR Z,$DL12
LD A,(DE) ; ja, Befehlsbyte nach DD/FD -> A
CP 0E9H ; "JP (IX/IY)" ?
JR Z,$DL12
LD (HL),'+' ; nein, "+" ausgeben
INC HL ; naechste Printposition
CALL PRVH ; Offset ausgeben
$DL12: POP AF ; A wieder herstellen
BIT 7,A ; "()" ?
RET Z ; nein, fertig
LD (HL),')' ; ja, ")" ausgeben
INC HL ; naechste Printposition
RET
; Error
ERRO: LD DE,CBMTAB+24 ; Pointer auf "????" -> DE
CALL TRBY ; als Mnemonic ausgeben
POP DE ; akt. Disassemblieradr. vom Stack holen
; Disassemblier-Adresse erhoehen und merken
INAD: INC DE
LD (DADR),DE
; Workspace ausgeben
PRWO: PUSH AF ; Register retten
PUSH BC
PUSH DE
PUSH HL
LD HL,WRKS ; Adresse Workspace -> HL
CALL PRTSTR ; Workspace aufs Terminal ausgeben
LD HL,NL ; Adresse Newline-String -> HL
CALL PRTSTR ; Newline ausgeben
POP HL ; Register wieder herstellen
POP DE
POP BC
POP AF
RET
; Workspace loeschen
CLWO: LD HL,WRKS ; Workspace mit Space fuellen
LD DE,WRKS+1 ; und mit Null terminieren
LD (HL),32
LD BC,32
LDIR
XOR A
LD (DE),A
RET
; 4 Bytes transferieren
TRBY: PUSH BC ; BC retten
LD BC,4 ; 4 Bytes
EX DE,HL ; DE=Printposition, HL=Mnemonic
LDIR ; Bytes transferieren
EX DE,HL ; HL ist wieder Printposition
POP BC ; BC wieder herstellen
INC HL ; Leerzeichen
RET
; Byte vorne und hinten ausgeben
PRVH: CALL PRNB ; Byte vorne ausgeben
; Byte hinten ausgeben
PRBH: PUSH AF ; A retten
LD A,(DE) ; Byte -> A
CALL PRAK ; A ausgeben
POP AF ; A wieder herstellen
RET
; Byte vorne ausgeben
PRNB: PUSH AF ; A retten
INC DE ; DE auf naechstes Byte setzen
PUSH HL ; akt. Printposition retten
LD HL,(PRTMP) ; vordere Printposition -> HL
LD A,(DE) ; Byte -> A
CALL PRAK ; A ausgeben
INC HL ; Leerzeichen
LD (PRTMP),HL ; vordere Printposition retten
POP HL ; akt. Printposition wieder -> HL
POP AF ; A wieder herstellen
RET
; DE ausgeben
PRBY: LD A,D ; MSB -> A
CALL PRAK ; A ausgeben
LD A,E ; LSB -> A
; A ausgeben
PRAK: PUSH AF ; A retten
RRCA ; oberes Nibble ins untere schieben
RRCA
RRCA
RRCA
CALL PRCH ; oberes Nibble ausgeben
POP AF ; A wieder herstellen
CALL PRCH ; unteres Nibble ausgeben
RET
; unteres Nibble in ASCII-Hex umwandeln und in Workspace schreiben
PRCH: AND 0FH
ADD A,90H
DAA
ADC A,40H
DAA
LD (HL),A ; ASCII-Ziffer in Workspace schreiben
INC HL ; Printposition erhoehen
RET
; Die hier folgenden Tabellen muessen am Anfang einer Page
; beginnen, und die Reihenfolge der Tabellen darf auf keinen
; Fall geaendert werden, weil das LSB der Tabellenadressen
; durch arithmetische Operationen mit den Op-Codes berechnet
; wird !!!
DEFS 256 - ($ & 0FFH)
MNETAB: ; Tabelle mit den Z80-Mnemonics
DEFM 'ADD ADC '
DEFM 'SUB SBC '
DEFM 'AND XOR '
DEFM 'OR CP '
DEFM 'JR NOP '
DEFM 'DJNZEX '
DEFM 'RLCARLA '
DEFM 'DAA SCF '
DEFM 'RRCARRA '
DEFM 'CPL CCF '
DEFM 'LD INC '
DEFM 'DEC HALT'
DEFM 'RET POP '
DEFM 'JP OUT '
DEFM 'EX DI '
DEFM 'CALLPUSH'
DEFM 'RST EXX '
DEFM 'IN EX '
DEFM 'EI LDI '
DEFM 'LDIRINI '
DEFM 'INIROUTI'
DEFM 'OTIRNEG '
DEFM 'RETNRRD '
DEFM 'LDD LDDR'
DEFM 'CPD CPDR'
DEFM 'IND INDR'
DEFM 'OTDROUTD'
DEFM 'RETIRLD '
DEFM 'BIT RES '
DEFM 'SET ????'
DEFM 'CPI CPIR'
DEFM 'IM ----'
CODTAB: ; LSB-Adressen der Mnemonics in MNETAB fuer
; Befehle 00..3F ohne Preafix ED/CB
DEFB 024H,050H,050H,054H,054H,058H,050H,030H ; NOP LD LD INC INC DEC LD RLCA
DEFB 070H,000H,050H,058H,054H,058H,050H,040H ; EX ADD LD DEC INC DEC LD RRCA
DEFB 028H,050H,050H,054H,054H,058H,050H,034H ; DJNZ LD LD INC INC DEC LD RLA
DEFB 020H,000H,050H,058H,054H,058H,050H,044H ; JR ADD LD DEC INC DEC LD RRA
DEFB 020H,050H,050H,054H,054H,058H,050H,038H ; JR LD LD INC INC DEC LD DAA
DEFB 020H,000H,050H,058H,054H,058H,050H,048H ; JR ADD LD DEC INC DEC LD CPL
DEFB 020H,050H,050H,054H,054H,058H,050H,03CH ; JR LD LD INC INC DEC LD SCF
DEFB 020H,000H,050H,058H,054H,058H,050H,04CH ; JR ADD LD DEC INC DEC LD CCF
; LSB-Adressen der Mnemonics in MNETAB fuer
; Befehle C0..FF ohne Preafix ED/CB
DEFB 060H,064H,068H,068H,078H,07CH,000H,080H ; RET POP JP JP CALL PUSH ADD RET
DEFB 060H,060H,068H,0F1H,078H,078H,004H,080H ; RET RET JP (CB) CALL CALL ADC RST
DEFB 060H,064H,068H,06CH,078H,07CH,008H,080H ; RET POP JP OUT CALL PUSH SUB RST
DEFB 060H,084H,068H,088H,078H,0F0H,00CH,080H ; RET EXX JP IN CALL (DD) SBC RST
DEFB 060H,064H,068H,070H,078H,07CH,010H,080H ; RET POP JP EX CALL PUSH AND RST
DEFB 060H,068H,068H,02CH,078H,0F2H,014H,080H ; RET JP JP EX CALL (ED) XOR RST
DEFB 060H,064H,068H,074H,078H,07CH,018H,080H ; RET POP JP DI CALL PUSH OR RST
DEFB 060H,050H,068H,090H,078H,0F8H,01CH,080H ; RET LD JP EI CALL (FD) CP RST
; LSB-Adressen der Mnemonics in MNETAB fuer
; Befehle 40..7F mit Preafix ED
DEFB 088H,06CH,00CH,050H,0ACH,0B0H,0F8H,050H ; IN OUT SBC LD NEG RETN IM LD
DEFB 088H,06CH,004H,050H,0FFH,0D8H,0FFH,050H ; IN OUT ADC LD RETI LD
DEFB 088H,06CH,00CH,050H,0FFH,0FFH,0F8H,050H ; IN OUT SBC LD IM LD
DEFB 088H,06CH,004H,050H,0FFH,0FFH,0F8H,050H ; IN OUT ADC LD IM LD
DEFB 088H,06CH,00CH,0FFH,0FFH,0FFH,0FFH,0B4H ; IN OUT SBC RRD
DEFB 088H,06CH,004H,0FFH,0FFH,0FFH,0FFH,0DCH ; IN OUT ADC RLD
DEFB 0FFH,0FFH,00CH,050H,0FFH,0FFH,0FFH,0FFH ; SBC LD
DEFB 088H,06CH,004H,050H,0FFH,0FFH,0FFH,0FFH ; IN OUT ADC LD
; LSB-Adressen der Mnemonics in MNETAB fuer
; Befehle A0..BF mit Praefix ED
DEFB 094H,0F0H,09CH,0A4H,0FFH,0FFH,0FFH,0FFH ; LDI CPI INI OUTI
DEFB 0B8H,0C0H,0C8H,0D4H,0FFH,0FFH,0FFH,0FFH ; LDD CPD IND OUTD
DEFB 098H,0F4H,0A0H,0A8H,0FFH,0FFH,0FFH,0FFH ; LDIR CPIR INIR OTIR
DEFB 0BCH,0C4H,0CCH,0D0H,0FFH,0FFH,0FFH,0FFH ; LDDR CPDR INDR OTDR
SPRTAB: ; Tabelle der Sprungbedingungen
DEFM 'NZNCPOPEPM'
DEFB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
REGTAB: ; Tabelle der Register
DEFM 'BCDEHLSPAFIXIYIR'
OPETAB: ; Tabelle der Operanden:
; Bit 7: Zahl/Buchstabe
; Bit 6: einfach/doppelt
; Bit 5: Register/Sprungbedingung
; Bit 4: ohne/mit Klammer
; Bit 0..3: Offset in der Tabelle der Registernamen
; Befehle 00..3F ohne Preafix ED/CB
; 1. Operand
DEFB 0FFH,030H,0B0H,030H,010H,010H,010H,0FFH ; - BC (BC) BC B B B -
DEFB 038H,034H,017H,030H,011H,011H,011H,0FFH ; AF HL A BC C C C -
DEFB 041H,032H,0B2H,032H,012H,012H,012H,0FFH ; DIS DE (DE) DE D D D -
DEFB 041H,034H,017H,032H,013H,013H,013H,0FFH ; DIS HL A DE E E E -
DEFB 070H,034H,0C4H,034H,014H,014H,014H,0FFH ; NZ HL (NN) HL H H H -
DEFB 051H,034H,034H,034H,015H,015H,015H,0FFH ; Z HL HL HL L L L -
DEFB 072H,036H,0C4H,036H,016H,016H,016H,0FFH ; NC SP (NN) SP (HL) (HL) (HL) -
DEFB 011H,034H,017H,036H,017H,017H,017H,0FFH ; C HL A SP A A A -
; Befehle C0..FF ohne Preafix ED/CB
; 1. Operand
DEFB 070H,030H,070H,044H,070H,030H,017H,020H ; NZ BC NZ NN NZ BC A 00
DEFB 051H,0FFH,051H,0F1H,051H,044H,017H,021H ; Z - Z *CB Z NN A 08
DEFB 072H,032H,072H,0C2H,072H,032H,042H,022H ; NC DE NC (N) NC DE N 10
DEFB 053H,0FFH,053H,017H,053H,0F2H,017H,023H ; C - C A C *DD A 18
DEFB 074H,034H,074H,0B6H,074H,034H,042H,024H ; PO HL PO (SP) PO HL N 20
DEFB 076H,016H,076H,032H,076H,0F4H,042H,025H ; PE (HL) PE DE PE *ED N 28
DEFB 058H,038H,058H,0FFH,058H,038H,042H,026H ; P AF P - P AF N 30
DEFB 059H,036H,059H,0FFH,059H,0F8H,042H,027H ; M SP M - M *FD N 38
; Befehle 00..3F ohne Preafix ED/CB
; 2. Operand
DEFB 0FFH,044H,017H,0FFH,0FFH,0FFH,042H,0FFH ; - NN A - - - N -
DEFB 038H,030H,0B0H,0FFH,0FFH,0FFH,042H,0FFH ; AF BC (BC) - - - N -
DEFB 0FFH,044H,017H,0FFH,0FFH,0FFH,042H,0FFH ; - NN A - - - N -
DEFB 0FFH,032H,0B2H,0FFH,0FFH,0FFH,042H,0FFH ; - DE (DE) - - - N -
DEFB 041H,044H,034H,0FFH,0FFH,0FFH,042H,0FFH ; DIS NN HL - - - N -
DEFB 041H,034H,0C4H,0FFH,0FFH,0FFH,042H,0FFH ; DIS HL (NN) - - - N -
DEFB 041H,044H,017H,0FFH,0FFH,0FFH,042H,0FFH ; DIS NN A - - - N -
DEFB 041H,036H,0C4H,0FFH,0FFH,0FFH,042H,0FFH ; DIS SP (NN) - - - N -
; Befehle C0..FF ohne Praefix ED/CB
; 2. Operand
DEFB 0FFH,0FFH,044H,0FFH,044H,0FFH,042H,0FFH ; - - NN - NN - N -
DEFB 0FFH,0FFH,044H,0FFH,044H,0FFH,042H,0FFH ; - - NN *CB NN - N -
DEFB 0FFH,0FFH,044H,017H,044H,0FFH,0FFH,0FFH ; - - NN A NN - - -
DEFB 0FFH,0FFH,044H,0C2H,044H,0FFH,042H,0FFH ; - - NN (N) NN *DD N -
DEFB 0FFH,0FFH,044H,034H,044H,0FFH,0FFH,0FFH ; - - NN HL NN - - -
DEFB 0FFH,0FFH,044H,034H,044H,0FFH,0FFH,0FFH ; - - NN HL NN *ED - -
DEFB 0FFH,0FFH,044H,0FFH,044H,0FFH,0FFH,0FFH ; - - NN - NN - - -
DEFB 0FFH,034H,044H,0FFH,044H,0FFH,0FFH,0FFH ; - HL NN - NN *FD - -
OP2TAB: ; Befehle 40..7F mit Praefix ED
; 1. Operand
DEFB 010H,091H,034H,0C4H,0FFH,0FFH,000H,01EH ; B (C) HL (NN) - - 0 I
DEFB 011H,091H,034H,030H,0FFH,0FFH,0FFH,01FH ; C (C) HL BC - - - R
DEFB 012H,091H,034H,0C4H,0FFH,0FFH,001H,017H ; D (C) HL (NN) - - 1 A
DEFB 013H,091H,034H,032H,0FFH,0FFH,002H,017H ; E (C) HL DE - - 2 A
DEFB 014H,091H,034H,0C4H,0FFH,0FFH,076H,0FFH ; H (C) HL - - - - -
DEFB 015H,091H,034H,0FFH,0FFH,0FFH,0FFH,0FFH ; L (C) HL - - - - -
DEFB 0FFH,0FFH,034H,0C4H,0FFH,0FFH,0FFH,0FFH ; - - HL (NN) - - - -
DEFB 017H,091H,034H,036H,0FFH,0FFH,0FFH,0FFH ; A (C) HL SP - - - -
; Befehle 40..7F mit Preafix ED
; 2. Operand
DEFB 091H,010H,030H,030H,0FFH,0FFH,0FFH,017H ; (C) B BC BC - - - A
DEFB 091H,011H,030H,0C4H,0FFH,0FFH,0FFH,017H ; (C) C BC (NN) - - - A
DEFB 091H,012H,032H,032H,0FFH,0FFH,0FFH,01EH ; (C) D DE DE - - - I
DEFB 091H,013H,032H,0C4H,0FFH,0FFH,0FFH,01FH ; (C) E DE (NN) - - - R
DEFB 091H,014H,034H,034H,0FFH,0FFH,0FFH,0FFH ; (C) H HL - - - - -
DEFB 091H,015H,034H,0FFH,0FFH,0FFH,0FFH,0FFH ; (C) L HL - - - - -
DEFB 0FFH,0FFH,036H,036H,0FFH,0FFH,0FFH,0FFH ; - - SP SP - - - -
DEFB 091H,017H,036H,0C4H,0FFH,0FFH,0FFH,0FFH ; (C) A SP (NN) - - - -
CBMTAB: ; Tabelle der Mnemonics mit Praefix CB
DEFM 'RLC RRC '
DEFM 'RL RR '
DEFM 'SLA SRA '
DEFM '????SRL '
NL: ; Null-terminiertes Newline fuers Terminal
DEFB 10,13,0
WRKS: DEFS 34 ; Workspace zur Aufbereitung einer Ausgabezeile
PRTMP: DEFS 2 ; temoraerer Speicher fuer Printposition
DADR: DEFS 2 ; Disassemblier-Adresse

View File

@@ -0,0 +1,28 @@
TITLE 'Test programm for Z80-Disassembler'
;==========================================================================
; Test programm for Z80-Disassembler
;==========================================================================
LD SP,STACK ; initialize stack for simulator
LD HL,Z80OPS ; start address for disassembler
LD (DADR),HL
LOOP:
CALL DISSCR ; disassemble one screen full
HALT ; stop simulation
JP LOOP ; next run
PRTSTR: ; print 0 terminated string
LD A,(HL) ; next char -> A
OR A ; 0 ?
RET Z ; yes, done
OUT (0),A ; no, print it
INC HL ; increase pointer to string
JP PRTSTR ; process next char
INCLUDE z80dis.asm
INCLUDE z80ops.asm
DEFS 100H
STACK:
END

View File

@@ -0,0 +1,704 @@
TITLE 'Z80 Instruction Set in alphabetical Order'
IND EQU 5
M EQU 10H
N EQU 20H
DIS EQU 30H
Z80OPS:
ADC A,(HL)
ADC A,(IX+IND)
ADC A,(IY+IND)
ADC A,A
ADC A,B
ADC A,C
ADC A,D
ADC A,E
ADC A,H
ADC A,L
ADC A,N
ADC HL,BC
ADC HL,DE
ADC HL,HL
ADC HL,SP
ADD A,(HL)
ADD A,(IX+IND)
ADD A,(IY+IND)
ADD A,A
ADD A,B
ADD A,C
ADD A,D
ADD A,E
ADD A,H
ADD A,L
ADD A,N
ADD HL,BC
ADD HL,DE
ADD HL,HL
ADD HL,SP
ADD IX,BC
ADD IX,DE
ADD IX,IX
ADD IX,SP
ADD IY,BC
ADD IY,DE
ADD IY,IY
ADD IY,SP
AND (HL)
AND (IX+IND)
AND (IY+IND)
AND A
AND B
AND C
AND D
AND E
AND H
AND L
AND N
BIT 0,(HL)
BIT 0,(IX+IND)
BIT 0,(IY+IND)
BIT 0,A
BIT 0,B
BIT 0,C
BIT 0,D
BIT 0,E
BIT 0,H
BIT 0,L
BIT 1,(HL)
BIT 1,(IX+IND)
BIT 1,(IY+IND)
BIT 1,A
BIT 1,B
BIT 1,C
BIT 1,D
BIT 1,E
BIT 1,H
BIT 1,L
BIT 2,(HL)
BIT 2,(IX+IND)
BIT 2,(IY+IND)
BIT 2,A
BIT 2,B
BIT 2,C
BIT 2,D
BIT 2,E
BIT 2,H
BIT 2,L
BIT 3,(HL)
BIT 3,(IX+IND)
BIT 3,(IY+IND)
BIT 3,A
BIT 3,B
BIT 3,C
BIT 3,D
BIT 3,E
BIT 3,H
BIT 3,L
BIT 4,(HL)
BIT 4,(IX+IND)
BIT 4,(IY+IND)
BIT 4,A
BIT 4,B
BIT 4,C
BIT 4,D
BIT 4,E
BIT 4,H
BIT 4,L
BIT 5,(HL)
BIT 5,(IX+IND)
BIT 5,(IY+IND)
BIT 5,A
BIT 5,B
BIT 5,C
BIT 5,D
BIT 5,E
BIT 5,H
BIT 5,L
BIT 6,(HL)
BIT 6,(IX+IND)
BIT 6,(IY+IND)
BIT 6,A
BIT 6,B
BIT 6,C
BIT 6,D
BIT 6,E
BIT 6,H
BIT 6,L
BIT 7,(HL)
BIT 7,(IX+IND)
BIT 7,(IY+IND)
BIT 7,A
BIT 7,B
BIT 7,C
BIT 7,D
BIT 7,E
BIT 7,H
BIT 7,L
CALL C,NN
CALL M,NN
CALL NC,NN
CALL NN
CALL NZ,NN
CALL P,NN
CALL PE,NN
CALL PO,NN
CALL Z,NN
CCF
CP (HL)
CP (IX+IND)
CP (IY+IND)
CP A
CP B
CP C
CP D
CP E
CP H
CP L
CP N
CPD
CPDR
CPI
CPIR
CPL
DAA
DEC (HL)
DEC (IX+IND)
DEC (IY+IND)
DEC A
DEC B
DEC BC
DEC C
DEC D
DEC DE
DEC E
DEC H
DEC HL
DEC IX
DEC IY
DEC L
DEC SP
DI
DJNZ $+DIS
EI
EX (SP),HL
EX (SP),IX
EX (SP),IY
EX AF,AF'
EX DE,HL
EXX
HALT
IM 0
IM 1
IM 2
IN A,(C)
IN A,(N)
IN B,(C)
IN C,(C)
IN D,(C)
IN E,(C)
IN H,(C)
IN L,(C)
INC (HL)
INC (IX+IND)
INC (IY+IND)
INC A
INC B
INC BC
INC C
INC D
INC DE
INC E
INC H
INC HL
INC IX
INC IY
INC L
INC SP
IND
INDR
INI
INIR
JP (HL)
JP (IX)
JP (IY)
JP C,NN
JP M,NN
JP NC,NN
JP NN
JP NZ,NN
JP P,NN
JP PE,NN
JP PO,NN
JP Z,NN
JR C,$+DIS
JR $+DIS
JR NC,$+DIS
JR NZ,$+DIS
JR Z,$+DIS
LD (BC),A
LD (DE),A
LD (HL),A
LD (HL),B
LD (HL),C
LD (HL),D
LD (HL),E
LD (HL),H
LD (HL),L
LD (HL),N
LD (IX+IND),A
LD (IX+IND),B
LD (IX+IND),C
LD (IX+IND),D
LD (IX+IND),E
LD (IX+IND),H
LD (IX+IND),L
LD (IX+IND),N
LD (IY+IND),A
LD (IY+IND),B
LD (IY+IND),C
LD (IY+IND),D
LD (IY+IND),E
LD (IY+IND),H
LD (IY+IND),L
LD (IY+IND),N
LD (NN),A
LD (NN),BC
LD (NN),DE
LD (NN),HL
LD (NN),IX
LD (NN),IY
LD (NN),SP
LD A,(BC)
LD A,(DE)
LD A,(HL)
LD A,(IX+IND)
LD A,(IY+IND)
LD A,(NN)
LD A,A
LD A,B
LD A,C
LD A,D
LD A,E
LD A,H
LD A,I
LD A,L
LD A,N
LD B,(HL)
LD B,(IX+IND)
LD B,(IY+IND)
LD B,A
LD B,B
LD B,C
LD B,D
LD B,E
LD B,H
LD B,L
LD B,N
LD BC,(NN)
LD BC,NN
LD C,(HL)
LD C,(IX+IND)
LD C,(IY+IND)
LD C,A
LD C,B
LD C,C
LD C,D
LD C,E
LD C,H
LD C,L
LD C,N
LD D,(HL)
LD D,(IX+IND)
LD D,(IY+IND)
LD D,A
LD D,B
LD D,C
LD D,D
LD D,E
LD D,H
LD D,L
LD D,N
LD DE,(NN)
LD DE,NN
LD E,(HL)
LD E,(IX+IND)
LD E,(IY+IND)
LD E,A
LD E,B
LD E,C
LD E,D
LD E,E
LD E,H
LD E,L
LD E,N
LD H,(HL)
LD H,(IX+IND)
LD H,(IY+IND)
LD H,A
LD H,B
LD H,C
LD H,D
LD H,E
LD H,H
LD H,L
LD H,N
LD HL,(NN)
LD HL,NN
LD I,A
LD IX,(NN)
LD IX,NN
LD IY,(NN)
LD IY,NN
LD L,(HL)
LD L,(IX+IND)
LD L,(IY+IND)
LD L,A
LD L,B
LD L,C
LD L,D
LD L,E
LD L,H
LD L,L
LD L,N
LD SP,(NN)
LD SP,HL
LD SP,IX
LD SP,IY
LD SP,NN
LDD
LDDR
LDI
LDIR
NEG
NOP
OR (HL)
OR (IX+IND)
OR (IY+IND)
OR A
OR B
OR C
OR D
OR E
OR H
OR L
OR N
OTDR
OTIR
OUT (C),A
OUT (C),B
OUT (C),C
OUT (C),D
OUT (C),E
OUT (C),H
OUT (C),L
OUT (N),A
OUTD
OUTI
POP AF
POP BC
POP DE
POP HL
POP IX
POP IY
PUSH AF
PUSH BC
PUSH DE
PUSH HL
PUSH IX
PUSH IY
RES 0,(HL)
RES 0,(IX+IND)
RES 0,(IY+IND)
RES 0,A
RES 0,B
RES 0,C
RES 0,D
RES 0,E
RES 0,H
RES 0,L
RES 1,(HL)
RES 1,(IX+IND)
RES 1,(IY+IND)
RES 1,A
RES 1,B
RES 1,C
RES 1,D
RES 1,E
RES 1,H
RES 1,L
RES 2,(HL)
RES 2,(IX+IND)
RES 2,(IY+IND)
RES 2,A
RES 2,B
RES 2,C
RES 2,D
RES 2,E
RES 2,H
RES 2,L
RES 3,(HL)
RES 3,(IX+IND)
RES 3,(IY+IND)
RES 3,A
RES 3,B
RES 3,C
RES 3,D
RES 3,E
RES 3,H
RES 3,L
RES 4,(HL)
RES 4,(IX+IND)
RES 4,(IY+IND)
RES 4,A
RES 4,B
RES 4,C
RES 4,D
RES 4,E
RES 4,H
RES 4,L
RES 5,(HL)
RES 5,(IX+IND)
RES 5,(IY+IND)
RES 5,A
RES 5,B
RES 5,C
RES 5,D
RES 5,E
RES 5,H
RES 5,L
RES 6,(HL)
RES 6,(IX+IND)
RES 6,(IY+IND)
RES 6,A
RES 6,B
RES 6,C
RES 6,D
RES 6,E
RES 6,H
RES 6,L
RES 7,(HL)
RES 7,(IX+IND)
RES 7,(IY+IND)
RES 7,A
RES 7,B
RES 7,C
RES 7,D
RES 7,E
RES 7,H
RES 7,L
RET
RET C
RET M
RET NC
RET NZ
RET P
RET PE
RET PO
RET Z
RETI
RETN
RL (HL)
RL (IX+IND)
RL (IY+IND)
RL A
RL B
RL C
RL D
RL E
RL H
RL L
RLA
RLC (HL)
RLC (IX+IND)
RLC (IY+IND)
RLC A
RLC B
RLC C
RLC D
RLC E
RLC H
RLC L
RLCA
RLD
RR (HL)
RR (IX+IND)
RR (IY+IND)
RR A
RR B
RR C
RR D
RR E
RR H
RR L
RRA
RRC (HL)
RRC (IX+IND)
RRC (IY+IND)
RRC A
RRC B
RRC C
RRC D
RRC E
RRC H
RRC L
RRCA
RRD
RST 0
RST 10H
RST 18H
RST 20H
RST 28H
RST 30H
RST 38H
RST 8
SBC A,(HL)
SBC A,(IX+IND)
SBC A,(IY+IND)
SBC A,A
SBC A,B
SBC A,C
SBC A,D
SBC A,E
SBC A,H
SBC A,L
SBC A,N
SBC HL,BC
SBC HL,DE
SBC HL,HL
SBC HL,SP
SCF
SET 0,(HL)
SET 0,(IX+IND)
SET 0,(IY+IND)
SET 0,A
SET 0,B
SET 0,C
SET 0,D
SET 0,E
SET 0,H
SET 0,L
SET 1,(HL)
SET 1,(IX+IND)
SET 1,(IY+IND)
SET 1,A
SET 1,B
SET 1,C
SET 1,D
SET 1,E
SET 1,H
SET 1,L
SET 2,(HL)
SET 2,(IX+IND)
SET 2,(IY+IND)
SET 2,A
SET 2,B
SET 2,C
SET 2,D
SET 2,E
SET 2,H
SET 2,L
SET 3,(HL)
SET 3,(IX+IND)
SET 3,(IY+IND)
SET 3,A
SET 3,B
SET 3,C
SET 3,D
SET 3,E
SET 3,H
SET 3,L
SET 4,(HL)
SET 4,(IX+IND)
SET 4,(IY+IND)
SET 4,A
SET 4,B
SET 4,C
SET 4,D
SET 4,E
SET 4,H
SET 4,L
SET 5,(HL)
SET 5,(IX+IND)
SET 5,(IY+IND)
SET 5,A
SET 5,B
SET 5,C
SET 5,D
SET 5,E
SET 5,H
SET 5,L
SET 6,(HL)
SET 6,(IX+IND)
SET 6,(IY+IND)
SET 6,A
SET 6,B
SET 6,C
SET 6,D
SET 6,E
SET 6,H
SET 6,L
SET 7,(HL)
SET 7,(IX+IND)
SET 7,(IY+IND)
SET 7,A
SET 7,B
SET 7,C
SET 7,D
SET 7,E
SET 7,H
SET 7,L
SLA (HL)
SLA (IX+IND)
SLA (IY+IND)
SLA A
SLA B
SLA C
SLA D
SLA E
SLA H
SLA L
SRA (HL)
SRA (IX+IND)
SRA (IY+IND)
SRA A
SRA B
SRA C
SRA D
SRA E
SRA H
SRA L
SRL (HL)
SRL (IX+IND)
SRL (IY+IND)
SRL A
SRL B
SRL C
SRL D
SRL E
SRL H
SRL L
SUB (HL)
SUB (IX+IND)
SUB (IY+IND)
SUB A
SUB B
SUB C
SUB D
SUB E
SUB H
SUB L
SUB N
XOR (HL)
XOR (IX+IND)
XOR (IY+IND)
XOR A
XOR B
XOR C
XOR D
XOR E
XOR H
XOR L
XOR N
NN: DEFS 2