;ANIRECH2 (v3.2) - Animationsablauf berechnen (aus ANIMAKE entwickelt)
;30.3.1991  (15.7.,6.8.1990, 28.3.,29.3.1991)
;
;Proceduren fuer Animator (v3.2)
;
nolist
;
;WRITE"ANIRECH2.BIN"
;
CAUS EQU &BB5A;Charaus
;
ORG #6000
;
JP ANIBER;GesamtBerechnung
JP ANIONE;eine Berechnung
JP ANIVOR;Vorbereitung
JP DOKEHLP
JP ANILOAD
JP ANISAVE
;
;eine vordefinierte Konstante
;
FLUCHT DEFW 640;Fluchtpunkt
;
HLVONIX LD L,(IX+0)
INC IX
LD H,(IX+0)
INC IX
RET
;
;
DOKEHLP
CP 2
RET NZ
CALL HLVONIX;2.Param=Doke-Wert
EX DE,HL;nach DE
CALL HLVONIX;Adr
LD (HL),E
INC HL
LD (HL),D;Wert poken
RET
;
ANILOAD CP 2;2 Param?
RET NZ;nein
CALL FILEPARA;Filepara holen
RET NC;Namenslaenge=0
CALL FILELOAD;Daten laden
RET NC;Error
LD HL,(FILEADR);Animerkadr=Ladeadr
LD E,(HL)
INC HL
LD D,(HL);gesicherte Anfadr
INC HL;auf 1.Kopieradr
PUSH HL
POP IX;nach IX
DEC HL
DEC HL;wieder Animerkadr
OR A
SBC HL,DE;Offset feststellen
PUSH HL
POP IY;Offset in IY
LD HL,(PUNKTA);Zieladr
CALL ANIL6;dorthinkopieren
LD HL,(LINEA)
CALL ANIL6
LD HL,(ANIA)
CALL ANIL6
LD HL,(ANIBLK)
INC HL
INC HL;Offset zu Anidat ueberlesen
JR ANIL6

ANIL6
EX DE,HL;Zieladr in DE
CALL HLVONIX;StartAdr
PUSH IY
POP BC;Offset in BC
ADD HL,BC;Offset zur Startadr
PUSH HL;sich
CALL HLVONIX;Laenge
LD B,H
LD C,L;nach BC
POP HL;Startadr
LDIR;kopieren
RET
;
ANISAVE CP 2
RET NZ
CALL FILEPARA;Filepara holen
RET NC;Namenslaenge=0
PUSH HL;Namadr sich
PUSH BC;Namlg sich
PUSH DE;Buffadr sich
LD HL,(FILEADR);Saveadr als Animerkadr
LD (HL),L
LD A,H
INC HL
LD (HL),A;Anfadr als Kennung set
INC HL
PUSH HL
POP IX;Startadr in IX
LD DE,16;Platz fuer 4 Adressen mit 4 Laengen reservieren
ADD HL,DE
EX DE,HL;nach DE
LD HL,(PUNKTA)
LD A,6;Bytes pro Punkt
CALL ANIS5;kopieren

LD HL,(LINEA)
LD A,(HL);Anz Linienbloecke
PUSH HL;Adr sich
INC HL;+1
LD B,0;Hi-Byte
ANIS2 LD C,(HL);Anz Punkte
ADD HL,BC;zur Adr
INC HL;auf naechste Anzahl
DEC A
JR NZ,ANIS2
POP BC;Anfadr aus HL
PUSH BC;nochmal sich
OR A
SBC HL,BC;Laenge in HL
LD B,H
LD C,L;Lg nach BC
POP HL;Linea
CALL ANIS6;merk+Ldir

LD HL,(ANIA)
LD A,6;Bytes pro Phase
CALL ANIS5;kopieren
LD HL,(ANIBLK)
INC HL
INC HL;Offset zu Anidatentabelle ueberlesen
LD A,2;2 Byte pro Phase(Bildnr,Farbe)
CALL ANIS5;kopieren
;DE=akt.Endadr nach ldir
LD HL,(FILEADR);Startadr
EX DE,HL
OR A
SBC HL,DE;Laenge=Ende-Anfang
LD (FILELANG),HL;Filelaenge set
POP DE;Bufferadr
POP BC;Namlg
POP HL;Namadr
JP FILESAVE;speichern

ANIS5
CALL ANILSB;Lg berechnen
;akt.Adr DE und Lg. BC merken + Ldir
ANIS6
LD (IX+0),E
LD (IX+1),D;ZielAdr
LD (IX+2),C
LD (IX+3),B;Lg
INC IX
INC IX
INC IX
INC IX
LDIR;kopieren
RET

ANILSB
PUSH DE;sich
PUSH HL
LD E,(HL);Anzahl holen
CALL MULT8;HL=A*E
INC HL;Lg+1
LD B,H
LD C,L;nach BC
POP HL
POP DE
RET
;
;
FILEPARA PUSH IX;sich
CALL &BC7D;IN ABANDON
CALL &BC92;OUT ABANDON
POP IX
CALL HLVONIX;2.Param=Adr
LD (FILEADR),HL;Startadr
CALL HLVONIX;1.Param=Adr Descr.
LD A,(HL);Laenge
INC HL
LD B,A;nach B
OR A;0?
RET Z;Ja,Err
LD A,(HL)
INC HL
LD H,(HL);Name
LD L,A
LD DE,#C000;Filebuffer
SCF;Ok
RET
;
FILELOAD CALL &BC77;IN OPEN
RET NC
LD HL,(FILEADR);Ladr aus Hzahl
CALL &BC83;IN DIRECT
RET NC
JP &BC7A;IN CLOSE

FILESAVE CALL &BC8C;OUT OPEN
RET NC
LD HL,(FILEADR);Saveadr
LD DE,(FILELANG);Laenge
LD A,2;Bin
LD BC,0;Einspr.
CALL &BC98;OUT DIRECT
RET NC
JP &BC8F;OUT CLOSE
;
;
;Anivorbereitung - Wichtige Parameter fuer die Berechnung setzen
ANIVOR CP 5
RET NZ
CALL HLVONIX;5.Param=Adr Aniblk
LD (ANIBLK),HL;Adr sich
CALL HLVONIX;4.Param=Adr Anidata (Ziel fuer Anidaten)
LD (ANIDATA),HL;Anidatenadresse
CALL HLVONIX;3.Param=Adr Ania
LD (ANIA),HL;Startadr der Animationsphasen
CALL HLVONIX;2.Param=Adr Linea
LD (LINEA),HL;Startadr der Linien
CALL HLVONIX;1.Param=Adr Punkta
LD (PUNKTA),HL;Startadr der Eckpunkte
RET
;
;eine Phase 0 berechnen
ANIONE CP 6
RET NZ
LD DE,ANIPHA+5;Zieladr(zoff)
LD B,A;Anz.nach B
ANIONE1 CALL HLVONIX;Param.holen
LD A,L;Param
LD (DE),A;set
DEC DE
DJNZ ANIONE1
LD HL,(ANIDATA);Zieladr fuer Anidaten
LD (ANIDAT0POS),HL;als akt.Zeigerblockadr
LD DE,4;2 Bytes Offset Anipha0+Endoffset
ADD HL,DE
LD (ANIDATPOS),HL;akt.Pos im Anidatenblock
JP PHABER;eine Animationsphase berechnen
;
;
ANIBER CP 1;1 Variablenparameter zum Endesichern?
RET NZ;nein
CALL HLVONIX;Varadr holen
PUSH HL;sich
LD HL,(ANIDATA);Zieladr fuer Anidaten
LD (ANIDAT0POS),HL;als akt.Zeigerblockadr
EX DE,HL;nach DE
LD HL,(ANIA);Startadr AniDaten
LD A,(HL);Anzahl
INC A;+1,da ein Endezeiger
LD L,A
LD H,0;nach HL
ADD HL,HL;*2,da 2 Bytes Zeiger pro Animationsphase
ADD HL,DE;Anfadr dazu
LD (ANIDATPOS),HL;akt.Pos im Anidatenblock
XOR A
LD (ANIPOS),A;Beginn mit Phase 0
ANIBER1 CALL ANISET;Phasenwerte setzen
CALL ANIAUS;Animationsphase ausgeben
CALL PHABER;eine Animationsphase berechnen (CY=1=Ok)
LD DE,0;Endadresse bei Err
JR NC,ANIBER2;Error-kein Platz mehr
CALL ANINEXT;naechste Animationsphase
JR C,ANIBER1;noch eine,weiter
;fertig
LD DE,(ANIDATPOS);akt.Pos=Endadr
ANIBER2 POP HL;Variablenadr zum Ende-Sichern
LD (HL),E
INC HL
LD (HL),D
RET
;Animationsphase ausgeben
ANIAUS
CALL &BB78;TXT GET CURS. nach HL
LD A,(ANIPOS)
CALL DAUS8;8-Bit-Wert ausgeben
JP &BB75;TXT SET CURS. (alte Posit set)

DAUS8
LD B,#FF
DAUS81
INC B
SUB #A
JR NC,DAUS81
PUSH AF
LD A,B
OR A
CALL NZ,DAUS8
POP AF
ADD A,#3A;AUF ASCII
JP CAUS;Charaus

;
;
;Eine Animationsphase berechnen
PHABER LD HL,(ANIDATPOS);akt.Datensicheradr
LD DE,(ANIDATA);Anfangsadr zum Datensichern
OR A
SBC HL,DE;ergibt Offset
EX DE,HL;nach DE
LD HL,(ANIDAT0POS);akt.Ziel im Zeigerblock
LD (HL),E
INC HL
LD (HL),D;Offset zur akt.Phase sich
INC HL
LD (ANIDAT0POS),HL
XOR A;0
LD (HL),A
INC HL
LD (HL),A;naechsten Zeiger auf 0 setzen
CALL WINSET;Winkel der akt.Animationsphase setzen
CALL POLBER;Vorberechungen zur akt.Animationsphase
LD HL,(LINEA);Line-Beginn am Anfang
LD B,(HL);Anzahl Linienbloecke
INC HL
PHABER2
LD A,(HL);Punktanzahl im akt.LinienBlock
INC HL
OR A;akt.Anzahl Linien=0?
JR Z,PHABER3;Ja,Bild fertig
PUSH BC;B=akt.Anz Linienbloecke
LD B,A;Anz nach B
CALL LINESBER;Linien berechnen (CY=1=ok)
POP BC
RET NC;Error-kein Platz mehr
DJNZ PHABER2;bis alle Linienbloecke
PHABER3
;Animationsphasenende markieren
LD HL,(ANIDATPOS);akt.Adr
LD (HL),0;Laenge0=Bildende
INC HL
LD (ANIDATPOS),HL
SCF;Ok
RET
;
;Linien berechnen (zusammenhaengende)
LINESBER PUSH HL
LD HL,(ANIDATPOS);akt.Anidatensicheradr
LD (ANIDATPANZ),HL;wird Adr Anzahl zusammenhaengende Punkte
LD (HL),0;Anzahl zusammenhaengende Punkte auf 0
INC HL
LD (ANIDATPOS),HL;1.Adr fuer Daten
POP HL
LINESBER1
PUSH BC;sich
LD A,(HL);Punktnummer
INC HL
PUSH HL
LD E,6;6 Bytes pro Punkt
CALL MULT8;HL=A*E
LD DE,(PUNKTA);Start Punktdaten
INC DE;Anz ueberlesen
ADD HL,DE
LD DE,XKO;Ziel=xko,yko,zko
LD BC,&0006;3 Koordinaten*2 Bytes
LDIR;uebernehmen
CALL KOORBER;Bildkoordinaten berechnen
LD HL,(ANIDATPANZ);Adr Anzahl
LD A,(HL);akt.Anz
LD HL,(ANIDATPOS);akt.Anidatensicheradr
LD BC,(XKOOR);C=xkoor,B=ykoor
OR A;Anzahl=0?
JR Z,LINESBER3;Ja,Punkt auf jeden Fall eintragen
LD D,H
LD E,L;Anidatadr auch in DE
DEC DE
LD A,(DE);letzte y-Koord
CP B;=neue y-Koord?
JR NZ,LINESBER3;nein
DEC DE
LD A,(DE);letzte x-Koord
CP C;=neue x-Koord?
JR Z,LINESBER4;Koordinaten gleich - nicht eintragen
LINESBER3 LD A,&9F;Endadr Hi
CP H;Vgl.
JR NZ,LINESBOK;<>,weiter
LD A,&FD;Endadr Lo-3
CP L
JR C,LINESERR;A<L-passt nicht !
LINESBOK LD (HL),C;x-Koord.sich
INC HL
LD (HL),B;y-Koord.sich
INC HL
LD (ANIDATPOS),HL;Adr wieder set
LD HL,(ANIDATPANZ)
INC (HL);Anzahl Punkte erhoehen
LINESBER4 POP HL
POP BC
DJNZ LINESBER1;naechster Punkt
SCF;Ok
RET
LINESERR POP HL
POP BC
OR A;NC=Err
RET
;

;
;Cosinus-Wert aus Tabelle holen
; EIN  A=gewuenschter Wert (0-35)
; AUS  HL=Cosinuswert , AF veraendert
COSINUS ADD A,9;Cosinus ist gegenueber Sinus um 90 Grad verschoben
;jetzt wie Sinus holen
;
;Sinus-Wert aus Tabelle holen
; EIN  A=gewuenschter Wert (0-35)
; AUS  HL=Sinuswert , AF veraendert
SINUS SUB 36
JR NC,SINUS;bis Unterlauf
ADD A,36;Korrektur,damit von (0-35)
ADD A,A;*2,da 2 Bytes pro Wert
LD HL,SINTAB;Startadr der Tabelle
ADD A,L;Offset dazu
LD L,A
JR NC,SINUS1;kein Ueberlauf
INC H;Korrektur
SINUS1 LD A,(HL);Lo-Byte
INC HL
LD H,(HL);Hi-Byte
LD L,A;Lo-Byte nach L
RET
;
;naechste Animationsphase,falls moeglich
; AUS  CY=1=naechste Animationsphase uebernommen
ANINEXT LD HL,(ANIA);Adr max.Anz
LD C,(HL);max.Anzahl in C
LD HL,ANIPOS;Adr akt.Phase
INC (HL);+1
LD A,(HL);nach A
CP C;akt kleiner als max?
RET C;ja,ok
DEC (HL);wieder -1
RET;NC=keine mehr
;
ANISET LD A,(ANIPOS);akt.Phasennummer
LD E,6;Laenge einer Aniphase
CALL MULT8;HL=A*E
LD DE,(ANIA);Startadr
INC DE;Laenge ueberlesen
ADD HL,DE;auf akt.Phase
LD DE,ANIPHA;Zieladr
LD BC,&0006;6 Bytes Laenge
LDIR;Phase uebernehmen
RET
;
;
;Setzen der Winkelwerte SinAlpha,CosAlpha,SinBeta,CosBeta,SinGamma,CosGamma
WINSET
PUSH IX;sich
LD IX,ANIPHA;akt.Animationsphasen (alpha...)
LD DE,SinAlpha;Tabelle fuer Winkelwerte
LD B,3;Anzahl
WINSET1 LD A,(IX+0);Winkel get
INC IX
LD C,A;Winkel in C sich
CALL SINUS
EX DE,HL;Winkeladr in HL
LD (HL),E
INC HL
LD (HL),D;Sinus sich
INC HL
EX DE,HL
LD A,C;akt.Winkel
CALL COSINUS
EX DE,HL
LD (HL),E
INC HL
LD (HL),D;Cosinus sich
INC HL
EX DE,HL
DJNZ WINSET1
POP IX;zurueck
RET
;
;
POLMULT CALL HLMULTDE;HL=HL*DE
LD DE,(FAKT);Faktor
LD A,E;Faktor Lo
CP 128;128?
JP NZ,HLDIVDE;nein,komplexe Div
;Spezialdivision durch Fakt=128
;HL=INT(HL/128) Zweierkomplement-Division (nicht div, int(i/128) ! )
DIV128 LD B,7
LOOP SRA H;Shift right arithmetic,b7 bleibt
RR L
DJNZ LOOP
RET
;
POLBER
;p0=cg*cb p0=p0/fk
LD HL,(CosGamma)
LD DE,(CosBeta)
CALL POLMULT
LD (P0),HL
;p1=sg*cb p1=p1/fk
LD HL,(SinGamma)
LD DE,(CosBeta)
CALL POLMULT
LD (P1),HL
;p2=-sb
LD HL,(SinBeta)
CALL MINUSHL
LD (P2),HL
;p3=-sg*ca p3=p3/fk ph=cg*sb ph=ph/fk ph=ph*sa ph=ph/fk p3=p3+ph
LD HL,(SinGamma)
CALL MINUSHL
LD DE,(CosAlpha)
CALL POLMULT
PUSH HL;p3
LD HL,(CosGamma)
LD DE,(SinBeta)
CALL POLMULT
LD DE,(SinAlpha)
CALL POLMULT
POP DE;p3
ADD HL,DE;HL+DE
LD (P3),HL
;p4=cg*ca p4=p4/fk ph=sg*sb ph=ph/fk ph=ph*sa ph=ph/fk p4=p4+ph
LD HL,(CosGamma)
LD DE,(CosAlpha)
CALL POLMULT
PUSH HL;p4
LD HL,(SinGamma)
LD DE,(SinBeta)
CALL POLMULT
LD DE,(SinAlpha)
CALL POLMULT
POP DE;p4
ADD HL,DE;HL+DE
LD (P4),HL
;p5=cb*sa p5=p5/fk
LD HL,(CosBeta)
LD DE,(SinAlpha)
CALL POLMULT
LD (P5),HL
;p6=sg*sa p6=p6/fk ph=cg*sb ph=ph/fk ph=ph*ca ph=ph/fk p6=p6+ph
LD HL,(SinGamma)
LD DE,(SinAlpha)
CALL POLMULT
PUSH HL;p6
LD HL,(CosGamma)
LD DE,(SinBeta)
CALL POLMULT
LD DE,(CosAlpha)
CALL POLMULT
POP DE;p6
ADD HL,DE;HL+DE
LD (P6),HL
;p7=-cg*sa p7=p7/fk ph=sg*sb ph=ph/fk ph=ph*ca ph=ph/fk p7=p7+ph
LD HL,(CosGamma)
CALL MINUSHL
LD DE,(SinAlpha)
CALL POLMULT
PUSH HL;p7
LD HL,(SinGamma)
LD DE,(SinBeta)
CALL POLMULT
LD DE,(CosAlpha)
CALL POLMULT
POP DE;p7
ADD HL,DE;HL+DE
LD (P7),HL
;p8=cb*ca p8=p8/fk
LD HL,(CosBeta)
LD DE,(CosAlpha)
CALL POLMULT
LD (P8),HL
RET 
;
;
;Offset get
; EIN  DE=Adr mit Byte/HL=Zahl,fuer Offsetaddition
; AUS  DE=Offsetwert
OFFGET LD A,(DE);A.Byte aus Animationsphase
LD D,A;als Hi-Byte nehmen !
LD E,0;Lo=0
RET
;
;
;Koordinatenberechnung
KOORBER
;h1=x0*p2 h2=y0*p5 h3=z0*p8 h4=h1+h2+h3+zoff(k)
LD HL,(XKO)
LD DE,(P2)
CALL HLMULTDE
PUSH HL;h1
LD HL,(YKO)
LD DE,(P5)
CALL HLMULTDE
PUSH HL;h2
LD HL,(ZKO)
LD DE,(P8)
CALL HLMULTDE
POP DE;h2
ADD HL,DE;HL+DE
POP DE;h1
ADD HL,DE;HL+DE
LD DE,ANIPHA+5;Adr Zoff
CALL OFFGET;Offset nach DE
ADD HL,DE;HL+DE
ADD HL,DE;HL+DE 2 mal add ergibt h4
;zp=fk-h4/fp
LD DE,(FLUCHT);Fluchtpunkt
CALL HLDIVDE;h4/fp
EX DE,HL;nach DE
LD HL,(FAKT)
OR A
SBC HL,DE;HL-DE
LD (ZP),HL
;h1=x0*p0 h2=y0*p3 h3=z0*p6 h4=h1+h2+h3+xoff(k)
LD HL,(XKO)
LD DE,(P0)
CALL HLMULTDE
PUSH HL;h1
LD HL,(YKO)
LD DE,(P3)
CALL HLMULTDE
PUSH HL;h2
LD HL,(ZKO)
LD DE,(P6)
CALL HLMULTDE
POP DE;h2
ADD HL,DE;HL+DE
POP DE;h1
ADD HL,DE;HL+DE
LD DE,ANIPHA+3;Adr Xoff
CALL OFFGET;Offset nach DE get
ADD HL,DE;HL+DE
;xp=h4/zp+xorigin (320 bzw.128)
LD DE,(ZP)
CALL HLDIVDE
LD DE,(XORG)
ADD HL,DE;HL+DE
XOR A;0 fuer gleich
RLC H;b7 nach CY=1=negativ?
JR C,KOORBER3;Ja,0 nehmen
LD A,H
OR A;positiv>&FF?
LD A,&FF
JR NZ,KOORBER3;Ja,max nehmen
LD A,L;Koord. nach A
KOORBER3
LD (XKOOR),A;x-Koordinate sich
;h1=x0*p1 h2=y0*p4 h3=z0*p7 h4=h1+h2+h3+yoff(k)
LD HL,(XKO)
LD DE,(P1)
CALL HLMULTDE
PUSH HL;h1
LD HL,(YKO)
LD DE,(P4)
CALL HLMULTDE
PUSH HL;h2
LD HL,(ZKO)
LD DE,(P7)
CALL HLMULTDE
POP DE;h2
ADD HL,DE;HL+DE
POP DE;h1
ADD HL,DE;HL+DE
LD DE,ANIPHA+4;Adr Yoff
CALL OFFGET;Offset nach DE get
ADD HL,DE;HL+DE
;yp=yorigin(100 bzw. 128)-h4/zp   (/2)
LD DE,(ZP)
CALL HLDIVDE
EX DE,HL;nach DE
LD HL,(YORG)
OR A
SBC HL,DE;HL-DE
XOR A
RLC H;b7 nach CY=1=negativ?
JR C,KOORBER5;Ja,0 nehmen
LD A,H
OR A;positiv>&FF?
LD A,&FF
JR NZ,KOORBER5;Ja,max nehmen
LD A,L;sonst Koord.Lo
KOORBER5 LD (YKOOR),A;y-Koordinate sich
RET
;
;
;HL=A*E ; DE erhalten
MULT8
LD HL,0
PUSH BC;SICH
LD C,D;D SICH
LD D,H;0
LD B,8;8 BITS
MULT81
ADD HL,HL;SHIFT LEFT 1 BIT
RLA;MULTIPLIKANT 1 BIT
JR NC,MULT82
ADD HL,DE
MULT82
DJNZ MULT81
LD D,C
POP BC
RET
;
;
;Teile aus Integer-Arithmetics CPC 6128
;disassembliert 28.3.1991
;
;signed Binary > 2er Kompl.
; EIN  HL=unsigned Integer  B<b7>=Vorzeichen
; AUS  HL=Integer, 2er Kompl.  CY=1,Z=0 f.Ueberlauf
INTMIX LD A,H
OR A
JP M,LDD42
OR B
JP M,MINUSHL
SCF
RET
LDD42 XOR #80
OR L
RET NZ
LD A,B
SCF
ADC A,A
RET


;HL=HL*DE
; EIN  HL=Integerarg1, 2er Komplement, DE=Integerarg2, 2er Komplement
; AUS  HL=ABS(HL)*ABS(DE), B=Vorzeichen des Ergebnisses
HLMULTDE CALL VORZBEST;Vorzeichen get
CALL LDD72
JP NC,INTMIX
OR #FF
RET

;Vorz. d.Ergebn.bestimmen
; EIN  HL=Integer, 2er Kompl. DE=Integer, 2er Kompl.
; AUS  HL=ABS(HL), DE=ABS(DE), B=Vorzeichenvergleich
VORZBEST LD A,H
XOR D
LD B,A
EX DE,HL
CALL ABSHL
EX DE,HL
JP ABSHL

;vorzeichenlose Multiplikation
; EIN  HL=unsigned Integer,Int1 , DE=unsigned Integer,Int2
; AUS  HL=unsigned Integer, Erg.  CY=1,wenn Fehler
LDD72 LD A,H
OR A
JR Z,LDD7B
LD A,D
OR A
SCF
RET NZ
EX DE,HL
LDD7B OR L
RET Z
LD A,D
OR E
LD A,L
LD L,E
LD H,D
RET Z
CP #03
JR C,LDD97
SCF
LDD88 ADC A,A
JR NC,LDD88
LDD8B ADD HL,HL
RET C
ADD A,A
JR NC,LDD92
ADD HL,DE
RET C
LDD92 CP #80
JR NZ,LDD8B
RET
LDD97 CP #01
RET Z
ADD HL,HL
RET

;HL=HL DIV DE
; EIN  HL=Integer1, 2er Kompl. DE=Integer2, 2er Kompl.
; AUS  HL=HL DIV DE, 2er Kompl, CY=0 f.Fehler  Z=1='division by zero'
;      Z=0='overflow'
HLDIVDE CALL LDDAB
LDD9F JP C,INTMIX
RET

;HL=HL MOD DE
; EIN  HL=Integer1, 2er Kompl. DE=Integer2, 2er Kompl.
; AUS  HL=HL MOD DE, 2er Kompl
LD C,H
CALL LDDAB
EX DE,HL
LD B,C
JR LDD9F

;Division
; EIN  HL=Integer1, 2er Kompl. DE=Integer2, 2er Kompl.
; AUS  HL=ABS(HL DIV DE), 2er Kompl, DE=ABS(HL MOD DE), 2er Kompl
;      B=Vorzeichen d.Quotienten, Z=1 f.'division by zero'
LDDAB CALL VORZBEST

;vorzeichenlose Division
; EIN  HL=Integer1, unsigned DE=Integer2, unsigned
; AUS  HL=HL DIV DE, DE=HL MOD DE, Z=1 f.'division by zero'
LD A,D
OR E
RET Z
PUSH BC
EX DE,HL
LD B,#01
LD A,H
OR A
JR NZ,LDDC2
LD A,D
CP L
JR C,LDDC2
LD H,L
LD L,#00
LD B,#09
LDDC2 LD A,E
SUB L
LD A,D
SBC A,H
JR C,LDDCD
INC B
ADD HL,HL
JR NC,LDDC2
CCF
LDDCD CCF
LD A,B
LD B,H
LD C,L
LD HL,#0000
JR LDDE4
LDDD6 RR B
RR C
EX DE,HL
SBC HL,BC
JR NC,LDDE0
ADD HL,BC
LDDE0 EX DE,HL
CCF
ADC HL,HL
LDDE4 DEC A
JR NZ,LDDD6
SCF
POP BC
RET

;HL=ABS(HL)
; EIN  HL=Integer, 2er Kompl.
; AUS  HL=ABS(HL), 2er Kompl.
ABSHL LD A,H
OR A
RET P

;HL=-HL (Zweierkomplement von HL)
; EIN  HL=Integer, 2er Kompl.
; AUS  HL=-HL, 2er Kompl.
MINUSHL XOR A
SUB L
LD L,A
SBC A,A
SUB H
LD H,A
RET
;

;
;** vordefinierte Konstanten
FAKT DEFW 128;Faktor, mit dem alles multipliziert wurde (evtl. Polmult anpass!)
XORG DEFW 128;x-Origin
YORG DEFW 128;y-Origin
;Sinustabelle der Sinus-Werte in 10 Grad-Schritten (multipliziert mit fakt=128)
SINTAB DEFW &0000,&0016,&002C,&0040,&0052,&0062,&006F,&0078,&007E
DEFW &0080,&007E,&0078,&006F,&0062,&0052,&0040,&002C,&0016
DEFW &0000,&FFEA,&FFD4,&FFC0,&FFAE,&FF9E,&FF91,&FF88,&FF82
DEFW &FF80,&FF82,&FF88,&FF91,&FF9E,&FFAE,&FFC0,&FFD4,&FFEA
;
;
;dynamische Variablen
;
VARSTART EQU $
;Variablen fuer mehrmaligen Aufruf von AniBer (ohne immer AniVor)
PUNKTA EQU VARSTART;DW 0;Startadr der Eckpunkte
LINEA EQU PUNKTA+2;DW 0;Startadr der Linien
ANIA EQU LINEA+2;DW 0;Startadr der Animationsphasen
ANIDATA EQU ANIA+2;DW 0;Anidatenadresse
ANIBLK EQU ANIDATA+2;DW 0;Adresse des Animationsablaufs

;Variablen immer neu
ANIPOS EQU ANIBLK+2;DB 0 akt.Animationsphase
ANIDAT0POS EQU ANIPOS+1;DW 0 akt.Adr fuer Zeiger auf Bilder
ANIDATPOS EQU ANIDAT0POS+2;DW 0 akt.Adr zum Koordinatensichern
ANIDATPANZ EQU ANIDATPOS+2;DW 0;Adresse der akt.Punktanzahl
;Werte der aktuellen Animationsphase
ANIPHA EQU ANIDATPANZ+2;DS 6;alpha,beta,gamma,xoff,yoff,zoff
;

SinAlpha EQU ANIPHA+6;DW 0 aktuelle Winkelwerte aus Tabelle
CosAlpha EQU SinAlpha+2;DW 0
SinBeta EQU CosAlpha+2;DW 0
CosBeta EQU SinBeta+2;DW 0
SinGamma EQU CosBeta+2;DW 0
CosGamma EQU SinGamma+2;DW 0

P0 EQU CosGamma+2;DW 0
P1 EQU P0+2;DW 0
P2 EQU P1+2;DW 0
P3 EQU P2+2;DW 0
P4 EQU P3+2;DW 0
P5 EQU P4+2;DW 0
P6 EQU P5+2;DW 0
P7 EQU P6+2;DW 0
P8 EQU P7+2;DW 0

ZP EQU P8+2;DW 0

XKO EQU ZP+2;DW 0;akt. x-Koordinate eines Eckpunktes
YKO EQU XKO+2;DW 0
ZKO EQU YKO+2;DW 0

XKOOR EQU ZKO+2;DB 0 x-Koordinate (normal 1 Byte)
YKOOR EQU XKOOR+1;DB 0 y-Koordinate

FILEADR EQU YKOOR+1;DW 0;fuer fileload,save
FILELANG EQU FILEADR+2;DW 0
;

list
VARENDE EQU FILELANG+2
;
list
end
;
