;ANIMATE3 (v2.0) - Der Animator mit Bildschirmswap (Mode 2)
;30.3.1991  (14.15.7.,15.8.1990  29.3.1991)
;
nolist
;(Linienzeichnen mit veraenderter Bildschirmbreite) (siehe BLINE)
;(jetzt fuer beliebigen Bildschirmstart !!!) (aus Tempest  Graphics0)
;
;
;WRITE"ANIMATE3.BIN"
;
;HizeilBu=Buffer fuer Hi-Bytes der Bildschirmstartadressen
;LozeilBu=Buffer fuer Lo-Bytes der Bildschirmstartadressen
;folgende 2 Buffer an geraden Adressen und genau &100 Byte auseinander
HIZEILBU EQU &A300
LOZEILBU EQU HIZEILBU+&100
SCRHI EQU LOZEILBU+&100;DB 0 ZeichenScreen Hi-Byte &40 oder &C0
SCRBA EQU SCRHI+1;DB 0 zu sehender Screen (Out fuer Crtc) &10 oder &30
FARBE EQU SCRBA+1;DB 0 Farbzahl
ANIDATADR EQU FARBE+1;DW 0 Zwischenspeicher fuer Datentabellenadr
SPSICH EQU ANIDATADR+2;DW 0 Stack-Speicher
;
;
ORG &A000
JP INITST
JP ANIMATEST
JP BILDAUSST
JP ANIMAONE;eine Phase 0 animieren
DEFB 1+4;5=Kennung fuer Animat21
WAIT DEFB 3;Wartezeit
;
;
HLVONIX
LD L,(IX+0)
INC IX
LD H,(IX+0)
INC IX
RET
;
;
INITST CALL BUMAKE;Bildschirmadresstabelle anlegen
CALL &BC0B;SCR GET LOCATION (A=Base/HL=Offs)
LD (SCRHI),A;set
LD A,2
CALL &BC0E;Scr Set Mode
CALL ZEICHSWAP;Zeichenbildschirm swap+Bildschirm loeschen
XOR A;neue Screenouts
JR BILDOUT;ausgeben
;
;
;zu sehenden Bildschirm swap
SEESWAP
LD A,(SCRBA)
XOR #20
LD (SCRBA),A
LD BC,&BC0C;Register 12 Crtc select
OUT (C),C
INC B;&bd
OUT (C),A;Scr Base set
RET
;
;Zeichenbildschirm swap+Cls
ZEICHSWAP
LD A,(SCRHI)
XOR #80
LD (SCRHI),A
;weiter mit Clrscr...
;
;Bildschirm loeschen (superschnell) (schneller als mit ldir)
; EIN  -
; AUS  AF veraendert
CLRSCR DI
LD (SPSICH),SP;Spack sich
PUSH HL
PUSH BC
LD A,(SCRHI);Hi-Byte
ADD A,&40;auf Ende Bildschirm
LD H,A;nach H
LD L,0;;Lo auf 0
LD SP,HL;Ende Bildschirm+1 nach Sp
LD HL,&0000;Fillword
LD BC,#0020;&100*&20=&2000=Anzahl Durchlaeufe
CLRSCR1 PUSH HL;2 Bytes auf einmal loeschen
DJNZ CLRSCR1;&100 mal
DEC C;&20 mal
JP NZ,CLRSCR1
POP BC
POP HL
LD SP,(SPSICH)
EI
RET
;
;
BILDAUSST
LD A,&FF;alt
JP BILDOUT
;
;A=0=neue Outs, sonst normal
BILDOUT CALL &BD19;Wait Flyback
LD BC,&BC00
LD HL,BILDTAB1
OR A;A=0?
JR Z,BILDOUT1;Ja,neu
LD HL,BILDTAB2;sonst normal
BILDOUT1
LD A,(HL)
OR A;0?
RET Z;Ja
OUT (C),A
INC HL
LD A,B
XOR &1;bc wird bd und umgekehrt
LD B,A
JR BILDOUT1;weiter

;neue Bildouts
BILDTAB1;(1=32,2=41,6=32,7=34)
DEFB 1,&20, 2,&29, 6,&20, 7,&22 ,0
;normale Bildouts
BILDTAB2;(1=40,2=46,6=25,5=0,7=30)
DEFB 1,&28, 2,&2E, 6,&19 ,7,&1E, 0
;
;
;Die Animationsschleife
; call animate,aniphasenadr
ANIMATEST CP 1
RET NZ
CALL HLVONIX;Phasenadr get
LD E,(HL)
INC HL
LD D,(HL);Offset zu der Datentabelle
PUSH HL;Phasadr sich
DEC HL;alte Phasadr
ADD HL,DE;Offset dazu
LD (ANIDATADR),HL;Adr der Animationsdatentabelle sich
POP HL
INC HL;auf Anzahl der Phasen
;Screen zeigen,auf dem nicht gezeichnet wird
LD A,(SCRHI)
RRA
RRA;2*rechts
AND %00110000;nur bestimmte Bits
LD (SCRBA),A;Akt Screenbyte
CALL SEESWAP;zu sehenden Bildschirm swap
LD B,(HL);Anzahl der Phasen holen
INC HL
INC B;Anz+1,da sofort djnz
JR ANIMATE2
ANIMATE1 PUSH BC;Anzahl sich
LD B,0;Hi=0
LD C,(HL);Phasennummer holen
INC HL
LD A,(HL);Farbe holen
INC HL
PUSH HL;Phasenadr sich
ld a,&80
LD (FARBE),A;setzen
LD HL,(ANIDATADR);Adr der Datentabelle
LD D,H
LD E,L;Datentabelle auch in DE
ADD HL,BC;Phasennr dazu
ADD HL,BC;2 mal dazu, da 2 Bytes pro Eintrag
LD C,(HL)
INC HL
LD B,(HL);Offset zu den Daten der Phase holen
EX DE,HL;Start Datentabelle in HL
ADD HL,BC;HL auf Daten
CALL BILDDRAW;auf dem Zeichenscreen Bild zeichnen
LD A,(WAIT)
CP 3;<3?
JR C,WARTEN2;Ja,Unterlauf
DEC A;3 wird 2
LD B,A
JR WARTEN1
WARTEN CALL &BD19;normal 1 mal
WARTEN1 DJNZ WARTEN
WARTEN2 CALL SEESWAP;zu sehender Bildschirm swap
CALL ZEICHSWAP;Zeichenbildsch swap+cls
LD A,47;Space
CALL &BB1E;Km Test Key
POP HL;Phasenadr zurueck
POP BC
RET NZ;Space gedrueckt - Abbruch
ANIMATE2 DJNZ ANIMATE1
RET;fertig
;
;
;eine Phase 0 animieren
ANIMAONE CP 1
RET NZ
CALL HLVONIX;Phasenadr get
LD E,(HL)
INC HL
LD D,(HL);Offset zu der Datentabelle
DEC HL;alte Phasadr
ADD HL,DE;Offset dazu
;HL=Adr der Animationsdatentabelle
LD A,&80
LD (FARBE),A;setzen
LD D,H
LD E,L;Datentabelle auch in DE
LD C,(HL)
INC HL
LD B,(HL);Offset zu den Daten der Phase holen
EX DE,HL;Start Datentabelle in HL
ADD HL,BC;HL auf Daten
JR BILDDRAW;auf dem Zeichenscreen Bild zeichnen
;
;
;ein Bild auf den Zeichenscreen zeichnen
; EIN  HL=Adresse eines Bildes
BILDDRAW LD A,(HL);Anzahl der Punkte
OR A;0?
RET Z;Ja,fertig
INC HL
LD E,(HL);Spalte1
INC HL
LD D,(HL);Zeile1
INC HL
DEC A;nur ein Punkt?
JR Z,BILDDRAW2;nur Punkt zeichnen+fertig
LD B,A;RestAnzahl in B
BILDDRAW1 PUSH BC;B=Anzahl sich
LD C,(HL);Spalte2
INC HL
LD B,(HL);Zeile2
INC HL
LD A,(FARBE)
PUSH HL
PUSH BC
CALL L635C;Draw
POP DE;2.Punkt BC wird neuer erster Punkt DE
POP HL
POP BC
DJNZ BILDDRAW1;bis zusammenhaengender Linienblock gezeichnet
JR BILDDRAW;evtl.weitere Linienbloecke
BILDDRAW2 PUSH HL;* sich 29.3.1991
LD L,D;Zeile nach L
LD A,(FARBE)
LD C,A;nach C
CALL L649D;Punkt zeichnen
POP HL;*
JR BILDDRAW;*
;
;
;Linie zeichnen
; EIN  D=ypos1,E=xpos1 , B=ypos2,C=xpos2 , A=Linienmaske
; AUS  ??
;(benoetigt HIZEILBU,LOZEILBU)
;
L635C PUSH AF
LD A,D;ypos1
SUB B;-ypos2
JP NZ,L636D;Linie
LD A,E;xpos1
CP C;xpos2
JP NZ,L6375;Linie
LD L,B;ypos nach L, E=Spalte
POP AF
LD C,A;Linienmaske set
JP L649D;Punkt plot

;y1<>y2
L636D JP C,L6375;ypos1<ypos2
LD D,A;Differenz=ypos1-ypos2
POP AF;Linienmaske
JP L637D
;y1<y2 oder (y1=y2 und x1<>x2)
L6375 PUSH DE;x1,y1 sich
LD D,B
LD E,C;x2,y2 nach DE
POP BC;x1,y1 nach BC (also vertauschen)
LD A,D;y2
SUB B;-y1
LD D,A;Differenz=y2-y1
POP AF;Linienmaske
;D=Differenz max(y1,y2)-min(y1,y2), E=zugehoeriges x , BC=groessere Koord
L637D DI
PUSH BC;grossKoord sich
EXX;2.Reg.
POP DE;DE'=grossKoord
PUSH BC;Out-Wert sich
LD C,A;Linienmaske set
EX AF,AF';2.Reg.
PUSH AF;AF' sich
LD L,D;Lo-Byte auf gewuenschte Zeile
LD A,(SCRHI);* Screen-Start
LD H,HIZEILBU/&ff;* Hi-Byte Zeilenadresstabelle
OR (HL);* Zeilenadresse Hi zum Screen-Start
INC H;* Lo-Byte Zeilenadresstabelle aus Lozeilbu
LD L,(HL);* Zeilenadresse Lo get
LD H,A;* Zeiladr Hi nach H
;B' unbenutzt (vorher Maskenzaehler)
LD A,C;Maske in A
SRL E;xklein div 2
JP C,L63A1
SRL E;xklein div 2
JP NC,L63AF
RRCA
RRCA
RRCA
RRCA;Maske 4 rechts
JP L63AF
L63A1 RRCA
RRCA;Maske 2 rechts
SRL E
JP NC,L63AF
RRCA
RRCA
RRCA
RRCA;Maske 4 rechts
L63AF LD C,A;Bitmaske set
LD D,#00
ADD HL,DE
LD DE,#0800;Nextline-Offset
LD (L63F6),SP;Stack sich
LD SP,#C040;Korrekturwert fuer 8-Zeilenueberlauf
EXX;1.Reg.
LD A,E;xpos
SUB C;-andere xpos
JP C,L642F
LD E,A;xdiff
LD A,D;ydiff
CP E;<xdiff?
JP C,L63FF;ja

XOR A;Zaehler init
LD B,D;ydiff (<xdiff) als Zaehler
L63CA ADD A,E;Zaehler+xdiff
JP C,L63D2;Ueberlauf
CP D;Zaehler<ydiff?
JP C,L63E7;Ja
L63D2 SUB D;Zaehler-ydiff
EXX;2.Reg
RRC C
RRC C;Maske rechts
JP NC,L63E8;noch kein Unterlauf
INC HL;next Byte
EXX;1.Reg
L63E7 EXX;2.Reg
L63E8 EX AF,AF';1.Reg(Zaehler sich)
LD A,(HL)
L63EA OR C;*
LD (HL),A
ADD HL,DE;Nextline(+&800)
LD A,H;*
AND #38;* fuer &4000 angepasst
JP NZ,L63F1;* ok,kein Ueberlauf
ADD HL,SP;8-Zeilen Ueberlaufkorrektur
L63F1 EXX;1.Reg.
EX AF,AF';2.Reg(Zaehler zurueck)
DJNZ L63CA
L63F6 EQU $+1
L63F5 LD SP,#BFEA;alten Stack zurueck
EXX;2.Reg
POP AF;altes AF'
EX AF,AF';1.Reg
POP BC;BC'=Out zurueck
EXX;1.Reg.
EI
RET

;ydiff<xdiff
L63FF XOR A;Zaehler init
LD B,E;xdiff(<ydiff) in Zaehler
L6401 ADD A,D;Zaehler+ydiff
JP C,L6409;Ueberlauf
CP E;Zaehler<xdiff?
JP C,L6411;Ja
L6409 SUB E;Zaehler-xdiff
EXX;2.Reg.
ADD HL,DE;Nextline(+&800)
EX AF,AF';*
LD A,H;*
AND &38;* fuer &4000 angepasst
JP NZ,HELP;* ok
ADD HL,SP;Ueberlaufkorrektur
EX AF,AF';*
EXX;1.Reg
L6411 EXX;2.Reg
L6412 EX AF,AF';1.Reg(Zaehler sich)
HELP;*
LD A,(HL)
L6414 OR C;*
LD (HL),A
RRC C
RRC C;Unterlauf?
JP NC,L6428;nein
INC HL;naechstes Byte
L6428 EXX;1.Reg
EX AF,AF';2.Reg(Zaehler zurueck)
DJNZ L6401
JP L63F5;Beenden


L642F NEG;Zweierkomplement von xdiff
LD E,A;xdiff nach E
CP D;xdiff>=ydiff?
JP NC,L646D;Ja

XOR A;Zaehler init
LD B,D;ydiff
L643F ADD A,E;Zaehler+xdiff
JP C,L6447;Ueberlauf
CP D;Zaehler<ydiff?
JP C,L645C;ja
L6447 SUB D;Zaehler-ydiff
EXX;2.Reg
RLC C;Ueberlauf?
JP NC,LIN31;nein
RLC C;Standardmaske
DEC HL;Byte zurueck
JP L645D
LIN31 RLC C;Bitmaske links
EXX;1.Reg.
L645C EXX;2.Reg.
L645D EX AF,AF';1.Reg(Zaehler sich)
LD A,(HL)
L645F OR C;*
LD (HL),A
ADD HL,DE;Nextline(+&800)
LD A,H;*
AND #38;* fuer &4000 angepasst
JP NZ,L6466;* ok
ADD HL,SP;Korrektur
L6466 EXX;1.Reg
EX AF,AF';2.Reg(Zaehler zurueck)
DJNZ L643F
JP L63F5;Beenden


L646D XOR A;Zaehler init
LD B,E;xdiff
L646F ADD A,D;Zaehler+ydiff
JP C,L6477;Ueberlauf
CP E;Zaehler<xdiff?
JP C,L647F;ja
L6477 SUB E;Zaehler-xdiff
EXX;2.Reg
ADD HL,DE;Nextline(+&800)
EX AF,AF';*
LD A,H;*
AND &38;*
JP NZ,HELP2;*
ADD HL,SP;Korrektur
EX AF,AF';*
EXX;1.Reg.
L647F EXX;2.Reg
L6480 EX AF,AF';1.Reg(Zaehler sich)
HELP2;*
LD A,(HL)
L6482 OR C;*
LD (HL),A
RLC C;Ueberlauf?
JP NC,LIN41;nein
RLC C;Standardmaske
DEC HL;Byte zurueck
JP L6496
LIN41 RLC C;Bitmaske links
L6496 EXX;1.Reg
EX AF,AF';2.Reg(Zaehler zurueck)
DJNZ L646F
JP L63F5

;
;Punkt plot
; EIN  E=Spalte L=Zeile  C=Bitmaske(fuer div-4-Spalten)
; AUS  B erhalten!
L649D LD A,(SCRHI);* Screen-Start
LD H,HIZEILBU/&FF;* Hi-Byte Zeilenadresstabelle
OR (HL);* Zeilenadresse Hi zum Screen-Start
INC H;* Lo-Byte Zeilenadresstabelle (aus LozeilBu)
LD L,(HL);* Zeilenadresse Lo get
LD H,A;* Hi-Adr nach H
LD D,#00;Hi-Byte Spalte auf 0
SRL E;div 2
JP C,PLOTR2
SRL E;div 4
JP C,PLOTR4
ADD HL,DE;Spalte zur Adr add
LD A,(HL)
OR C
LD (HL),A;set
RET
;Spalte nicht durch 2 teilbar
PLOTR2 SRL C;Bitmaske links
SRL C
SRL E;Spalte div 4
JP C,PLOTR4;Rest
ADD HL,DE
LD A,(HL)
OR C
LD (HL),A;set
RET
;Spalte nicht durch 4 teilbar
PLOTR4 SRL C
SRL C
SRL C
SRL C;Maske 4 mal rechts
ADD HL,DE
LD A,(HL)
OR C
LD (HL),A;set
RET
;
;
;Bildschirmzeilentabellen anlegen
BUMAKE
LD IX,HIZEILBU;Hi-Bytes
LD IY,LOZEILBU;Lo-Bytes
LD HL,#C000
LD DE,#0800;Offset fuer Next Line
LD B,#00;256 Zeilen
L6533 LD A,H;* Hi-Byte
AND &3F;* nur untere Bits
LD (IX+0),A;*
LD (IY+0),L
INC IX
INC IY
ADD HL,DE
JP NC,L6548
LD DE,#C040
ADD HL,DE;Korrektur
LD DE,#0800;alten Offset set
L6548 DJNZ L6533;bis 256 Zeilen
RET

list
end
