;SPECIAL EFFECTS - Listing #7
;Screen Squasher - Kommentierter Quellcode
;(C)1992 by ELMSOFT and CPC AMSTRAD INTERNATIONAL
;Geschrieben fuer MAXAM Assembler V1.13
NOLIST ;Keine Ausgaben.
ORG &4000 ;Programmstart bei 16384.
DI ;Alle die Synchronisation stoerenden Interrupts aus.
LD BC,&7F10 ;BORDER 6
OUT (C),C
LD C,&4C
OUT (C),C
LD HL,&3000 ;250 Bytes lange
LD DE,&3001 ;Tabelle fuer
LD (HL),40 ;Register 1 mit
LD BC,250 ;Standardwert 40
LDIR ;ab &3000 aufbauen.
LD A,&C9 ;Verzoegerungsschleife initialisieren. (Mit CALL &5000
LD (&5028),A ;wartet man somit &28 NOPs ab.)
LD HL,POS ;Positionstabelle fuer das Wegscrollen der einzelnen
LD A,192 ;Textzeilen aufbauen. (Werte in Pixelzeilen)
LO1 LD (HL),A ;Zeile 1 erhaelt die Position 0,
INC HL ;Zeile 2 den Wert 8...
SUB 8 ;...Zeile 25 die Position 192.
JR NC,LO1
LD HL,&0501 ;ZAEHL und NEU
LD (ZAEHL),HL ;initialisieren.
LD HL,150 ;150 Durchlaeufe bis Bildschirm leer.
LOOP0 PUSH HL ;Zaehler sichern.
LD B,&F5
FRAME IN A,(C) ;Strahlruecklauf
RRCA ;abwarten...
JR NC,FRAME
LD HL,653 ;Warten,bis der
WAIT DEC HL ;Elektronenstrahl
LD A,H ;den Beginn der
OR L ;ersten Textzeile
JR NZ,WAIT ;erreicht hat.
LD BC,&BC01 ;Dann CRTC Register 1
OUT (C),C ;anwaehlen
INC B ;und zur Ausgabe vorbereiten.
LD HL,&3000 ;HL=Zeiger auf Tabelle der Werte fuer Register 1.
LD D,210 ;210 Pixelzeilen lang Register 1 beschreiben.
LOOP1 LD A,(HL) ;Wert fuer Register 1 holen
OUT (C),A ;und ausgeben.
INC HL ;Zeiger erhoehen.
LD A,(HL) ;Verzoegerung.
LD A,(HL) ;Verzoegerung.
CALL &5000;Verzoegerung.
DEC D ;Durchlaufzaehler DECrementieren
JP NZ,LOOP1 ;und zurueckspringen.
LD IX,POS ;Jetzt werden die Bildschirmzeilen verschoben,
LD A,(ZAEHL) ;IX=Zeiger auf deren Positionstabelle,A=Anzahl der zu
LD B,A ;verschiebenden Zeilen (wachsend),Wert nach B als Zaehler.
LOOP2 PUSH BC ;B sichern.
LD L,(IX+0) ;Y-Position der untersten Zeile holen.
LD A,L ;Nach A
CP 240 ;und auf 240 ueberpruefen.
JR Z,W2 ;Schon 240,also ganz unten,dann keine Neuverschiebung noetig.
ADD A,8 ;Sonst 8 Pixelzeilen weiter
W1 LD (IX+0),A;und Positionstabelle aktualisieren.
LD H,&30 ;HL enthaelt jetzt alte Position der Textzeile,
LD D,H ;HL in DE
LD E,L ;kopieren und
INC E ;DE INCrementieren,
LD (HL),0 ;eine Null nach HL und dann
LD BC,7 ;7x weiterkopieren,
LDIR ;also 8 Nullen in Tabelle schreiben.
INC L ;HL und DE
INC E ;um 1 erhoehen. (Ueberlauf hier unmoeglich)
LD (HL),40 ;Und jetzt 8x den Wert 40 in die Tabelle
LD BC,7 ;schreiben, die Textzeile rutscht also
LDIR ;8 Pixelzeilen hinunter.
W2 POP BC ;B zurueckholen
INC IX ;und naechste Zeile
DJNZ LOOP2 ;verschieben.
LD HL,NEU ;Soll eine NEUe Textzeile mitgescrollt werden ?
DEC (HL) ;(Dies ist nach jeweils fuenf Durchlaeufen der Fall!)
JR NZ,W3 ;Nein,dann zu W3,
LD (HL),5 ;sonst Countdown wieder mit 5 laden und den ZAEHLer
DEC HL ;fuer die Anzahl der zu bewegenden Textzeilen
INC (HL) ;INCrementieren. (Eine Adresse unter NEU,daher zuerst DEC HL)
LD A,(HL) ;War das schon die
CP 26 ;26. Textzeile?
JR NZ,W3 ;Nein,dann zu W3,
DEC (HL) ;sonst Zaehler auf 25 zurueckstellen.
W3 POP HL ;Durchlaufzaehler vom Stack holen,
DEC HL ;erniedrigen,
LD A,H ;und 150x zu
OR L ;LOOP0
JP NZ,LOOP0 ;zurueck.
;Register 1 wiederherstellen.
LD BC,&BC01:OUT (C),C
LD BC,&BD28:OUT (C),C
EI ;Interrupts ein
RET ;und nach Hause ins Basic.
ZAEHL DB 1 ;Anzahl der zu scrollenden Textzeilen (1-25)
NEU DB 5 ;Verzoegerung bis ZAEHL erhoeht wird.
POS DS 25 ;Position der Textzeilen in Pixelzeilen.