* VERTICAL WAGGLER
;SPECIAL EFFECTS - Listing #8
;Vertical Waggler- 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,&7F00 ;INK 0,0
OUT (C),C
LD C,&54
OUT (C),C
LD HL,&3000 ;Tabelle fuer Register 9-Werte ab &3000 aufbauen.
PUSH HL ;&3000 zur spaeteren Verwendung auf den Stack.
LD DE,&3001 ;DE=HL+1
LD B,0 ;B fuer LDIR auf 0,C wird immer neu geladen.
LD IX,DAT ;IX=Tabelle fuer komprimierte Register 9-Werte.
LD A,25 ;25(=Anzahl Textzeilen) Durchlaeufe.
LOOP0 LD C,(IX+0);C aus komprimierter Tabelle holen
LD (HL),C ;und in die entpackte Tabelle nach &30XX schreiben.
INC C ;Wenn C=0,dann 1 Durchlauf,wenn C=7,dann 8 Durchlaeufe etc.
LDIR ;Jetzt den Wert von C Cx kopieren.
INC IX ;Naechstes Tabellenelement.
DEC A ;Schleife 25x
JR NZ,LOOP0 ;durchlaufen.
LD HL,&09FF ;STEP und POS
LD (STEP),HL ;neu laden.
LD A,&C9 ;Verzoegerungsschleife initialisieren. (Mit CALL &5000
LD (&5028),A ;wartet man somit &28 NOPs ab.)
LD A,3 ;Anzahl der Verzoegerungszyklen
LD (ZAEHL),A ;festlegen.
POP HL ;HL=&3000
LD DE,&3100 ;Und somit Tabelle von &3000 nach
LD BC,&FF ;&3100 weiter kopieren.
LDIR ;(Backup anlegen.)
LD HL,200 ;200 Durchlaeufe.
LOOP2 PUSH HL ;Zaehler sichern.
LOOP3 LD B,&F5
FRAME IN A,(C) ;Strahlruecklauf
RRCA ;abwarten...
JR NC,FRAME
LD BC,&7F10 ;BORDER 6
OUT (C),C
LD C,&4C
OUT (C),C
LD HL,650
LOOP4 DEC HL ;Warten,bis der
LD A,H ;Elektronenstrahl die
OR L ;erste Textzeile
JR NZ,LOOP4 ;erreicht hat.
;Dann den CRTC auf den verkleinerten Bildschirm vorbereiten.
LD BC,&BC04:OUT (C),C
LD BC,&BD65:OUT (C),C
LD BC,&BC07:OUT (C),C
LD BC,&BD4E:OUT (C),C
LD BC,&BC09 ;CRTC Register 9
OUT (C),C ;anwaehlen
INC B ;und zur Ausgabe vorbereiten.
LD HL,&3000 ;HL=Zeiger auf Tabelle der Werte fuer Register 9.
LD D,75 ;75 Pixelzeilen lang Register 9 beschreiben.
LOOP5 LD A,(HL) ;Wert fuer Register 9 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,LOOP5 ;und zurueckspringen.
LD C,2 ;Register 9 fuer den Rest des Bildaufbaus
OUT (C),C ;mit 2 laden. (Eine Textzeile also 3 Pixelzeilen gross.)
LD HL,ZAEHL ;Verzoegerungszaehler
DEC (HL) ;DECrementieren. Nach jedem dritten Bildaufbau wird die
JP NZ,LOOP3 ;Tabelle aktualisiert. (Sonst zu schnell!)
LD (HL),3 ;Zaehler neu laden.
LD HL,(STEP) ;L=Schrittrichtung der Rolle (1 oder -1(&FF)),H=Position
LD A,H ;Schrittrichtung zu Position
ADD A,L ;addieren.
CALL Z,LPLU ;Oberer Rand erreicht? (H=0) Dann L=1.
CP 10 ;Unterer Rand erreicht? (H=10)
CALL Z,LMIN ;Dann L=-1 oder &FF.
LD H,A ;H mit neuer Position laden
LD (STEP),HL ;und zurueckschreiben.
LD E,A ;Jetzt die &40 Bytes lange Walze
LD D,&30 ;von &3109 in die verwendete Tabelle
LD HL,&3109 ;nach &3000+E bzw. A kopieren.
LD BC,&40
LDIR
POP HL ;Durchlaufzaehler vom Stack holen
DEC HL ;und DECrementieren.
LD A,H ;200x zu LOOP2 zurueck.
OR L
JP NZ,LOOP2
;CRTC wieder mit alten Werten fuellen.
LD BC,&BC04:OUT (C),C
LD BC,&BD26:OUT (C),C
LD BC,&BC07:OUT (C),C
LD BC,&BD1E:OUT (C),C
LD BC,&BC09:OUT (C),C
LD BC,&BD07:OUT (C),C
EI ;Interrupts ein
RET ;und ins BASIC.
LPLU LD L,1 ;Schrittweite=1
RET
LMIN LD L,&FF ;Schrittweite=-1
RET
;Komprimierte Tabelle fuer Walze.
DAT DB 0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,6,5,4,3,2,1,0,7
STEP DB 0 ;Schrittrichtung.
POS DB 0 ;Walzenposition.
ZAEHL DB 3 ;Wartezaehler.