
; Listing11l5.s   - "Zoom" Animation, die nur 40 * 29 Pixel misst.
; Die endgültige Auflösung beträgt 320 * 232 oder das Achtfache.

	SECTION ZOOM,CODE

;	include	"DaWorkBench.s"		; entferne das; vor dem Speichern mit "wo"

*****************************************************************************
	include "/Sources/startup2.s"	; speichern interrupt, dma etc.
*****************************************************************************

; Mit DMASET entscheiden wir, welche DMA-Kanäle geöffnet und welche geschlossen werden sollen

			;5432109876543210
DMASET	equ	%1000001110000000	; Copper,Bitplane DMA aktivieren

WaitDisk	equ	30				; 50-150 zur Rettung (je nach Fall)

SCRBYTES	= 40				; Anzahl der Bytes für jede horizontale Linie.
								; Daraus berechnen wir die Bildschirmbreite,
								; Multiplizieren von Bytes mit 8: normaler Bildschirm 320/8 = 40
								; z.B. für einen 336 Pixel breiten Bildschirm 336/8 = 42
								; Beispielbreiten:
								; 264 pixel = 33 / 272 pixel = 34 / 280 pixel = 35
								; 360 pixel = 45 / 368 pixel = 46 / 376 pixel = 47
								; ... 640 pixel = 80 / 648 pixel = 81 ...

SCR_H		= 256				; Bildschirmhöhe in Zeilen
SCR_X		= $81				; Startbildschirm, XX-Position (normal $xx81) (129)
SCR_Y		= $2c				; Startbildschirm, YY-Position (normal $2cxx) (44)
SCR_RES		= 1					; 2 = HighRes (640*xxx) / 1 = LowRes (320*xxx)
SCR_LACE	= 0					; 0 = non interlace (xxx*256) / 1 = interlace (xxx*512)
HAM			= 0					; 0 = nicht HAM / 1 = HAM
SCR_BPL		= 3					; Anzahl Bitplanes

; Parameter automatisch berechnet

SCR_W		= SCRBYTES*8		; Bildschirmbreite
SCR_SIZE	= SCRBYTES*SCR_H	; Größe des Bildschirms in Bytes 
BPLC0		= ((SCR_RES&2)<<14)+(SCR_BPL<<12)+$200+(SCR_LACE<<2)+(HAM<<11)		; BPLCON0
DIWS		= (SCR_Y<<8)+SCR_X													; DIWSTRT
DIWST		= ((SCR_Y+SCR_H/(SCR_LACE+1))&255)<<8+(SCR_X+SCR_W/SCR_RES)&255		; DIWSTOP
DDFS		= (SCR_X-(16/SCR_RES+1))/2											; DDFSTRT
DDFST		= DDFS+(8/SCR_RES)*(SCRBYTES/2-SCR_RES)								; DDFSTOP


Start:
	move.l	#Bitplane,d0		; Bitplanepuffer
	lea	Bplpointers,a0
	move.w	#3-1,d7				; Anzahl planes
PointAnim:
	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
	addq.w	#8,a0
	swap	d0
	addi.l	#40*29,d0			; Länge der Bitplane von 1 Frame
	dbra	d7,PointAnim

	bsr.w	CreateCop			; Erstellen der Copperliste, die sie 
								; mit den Modulos um * 8 streckt
	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Bitplane, Copper
	move.l	#Copperlist,$80(a5)	; Zeiger Copperlist
	move.w	d0,$88(a5)			; Start Copperlist
	move.w	#0,$1fc(a5)			; AGA "deaktivieren"
	move.w	#$c00,$106(a5)		; AGA "deaktivieren"
	move.w	#$11,$10c(a5)		; AGA "deaktivieren"

Mouse:
	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$11500,d2			; warte auf Zeile $115
WaitY1:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l   d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmp.l   d2,d0				; warte auf Zeile $115
	bne.s	WaitY1
WaitY2:
	move.l	4(a5),d0			; VPOSR und VHPOSR - $dff004/$dff006
	and.l   d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmp.l   d2,d0				; warte auf Zeile $115
	beq.s	WaitY2

	bsr.w	ChangeFrame			; Erweitern Sie den aktuellen Frame horizontal
								; 8x: Im Grunde wird jedes Nit ein Byte

	btst	#6,$bfe001			; Maus gedrückt?
	bne.s	Mouse
	rts							; exit

****************************************************************************
; Routine, die alle 7 Bilder "ZoomFrame" ausführt, um langsamer zu werden
****************************************************************************

ChangeFrame:
	addq.b	#1,WaitFlag
	cmp.b	#7,WaitFlag			; Wurden 7 Frames übergeben? (um langsamer zu werden)
	bne.s	NoHoriz
	clr.b	WaitFlag
	bsr.w	ZoomFrame			; Wenn ja, lassen Sie uns den nächsten Frame "erweitern"!
NoHoriz:
	rts

WaitFlag:
	dc.w	0

****************************************************************************
; "Erweiterung" des Bildes: jedes Bit wird getestet, und je nachdem ob letzteres
; gesetzt oder nicht gesetzt ist, wird ein $FF- oder $00-Byte eingegeben.
; Beachten Sie das ByteLoop, das die Mitte des Programms ist: Ein Byte muss
; in 8 Bytes transformiert werden, daher muss jedes Bit des Bytes in ein Byte
; transformiert werden. Wie wird es gemacht? Machen Sie einfach einen btst von 
; jedem der 8 Bits und verschieben Sie das Byte $00 oder $ff, je nach Ergebnis 
; des Tests. Das d1-Register wird als dbra-Schleifenzähler verwendet, aber auch 
; als Zähler der Anzahl der zu testenden Bits mit dem btst.
****************************************************************************

;	___________
;	\      _  /
;	 \ oO  / /
;	  \\__/ /
;	   \___/____  .--*
;	     \______--'
;	      |    |
;	     _|   _|...g®m ...

ZoomFrame:
	move.l	AnimPointer(pc),a0	; aktuelles kleines Bild (40*29)
	lea	Bitplane,a1				; Puffer Ziel (320*29)
	move.w	#(5*29*3)-1,d7		; 5 Bytes für eine Zeile * 29 Zeilen * 3 Bitplanes
Animloop:
	moveq	#0,d0
	move.b	(a0)+,d0			; nächste byte in d0
	moveq	#8-1,d1				; 8 Bit zu überprüfen und zu erweitern.
ByteLoop:
	btst.l	d1,d0				; Testen des aktuellen Schleifenbits
	beq.s	BitClear			; Ist es zurückgesetzt?
	st.b	(a1)+				; Wenn nicht, legt das Byte fest (=$FF)
	bra.s	BitSet
BitClear:
	clr.b	(a1)+				; Wenn es Null ist, setzt es das Byte zurück (=$00)
BitSet:
	dbra	d1,ByteLoop			; Überprüfen und erweitern Sie alle Bits des Bytes:
								; d1, abnehmend, bewirkt, dass der btst jedes Mal auf
								; ein anderes Bit zeigt von 7 bis 0.

	dbra	d7,Animloop			; Konvertieren Sie den gesamten Frame

	add.l	#(5*29)*3,AnimPointer	; Zeigen Sie auf das nächste Bild
	move.l	AnimPointer(pc),a0
	lea	EndAnim(pc),a1
	cmp.l	a0,a1				; War es der letzte Frame?
	bne.s	DoNotStartAgain
	move.l	#Anim,AnimPointer	; Wenn ja, fangen wir mit dem ersten an
DoNotStartAgain:
	rts

AnimPointer:
	dc.l	Anim

****************************************************************************
; Routine, die die copperliste erstellt, die das Bild achtmal mit dem Modulo.
; auf diese Weise dehnt: warte eine Zeile, dann setze das Modulo auf 0, so
; damit Sie später an der Zeile einrasten, dann die Zeile darunter neu ausrichten
; und das Modulo auf -40 setzen so dass jede Zeile "repliziert" wird die gleiche 
; Zeile darunter. Nach 7 wait Zeilen, setze das Modulo für eine Zeile auf 0.
; Klicken Sie auf die untere Zeile und setzen Sie das Modulo für 7 weitere 
; Zeilen auf -40 zurück um es zu replizieren. Das Ergebnis ist, dass jede 
; Zeile 8 Mal wiederholt wird.
****************************************************************************

;	   ______
;	 _/      \_
;	 \        /
;	 _\ °  __/-
;	 \_\__/  (·)__
;	   \   )__  __)
;	    \___\_\/
;	   ./_    \.
;	   | |   | |
;	   | |___|_.-_
;	   (______)__/
;	     |___| |
;	     \_ _|_|
;	  _   | |(_)  _
;	 / \__|_|_|__/ \
;	(_______|_______)

CreateCop:
	lea	ExtendCop,a0			; Puffer in Copperlist
	move.l	#$3407fffe,d0		; wait start
	move.l	#$1080000,d1		; BPL1MOD 0
	move.l	#$10a0000,d2		; BPL2MOD 0
	move.l	#$108ffd8,d3		; BPL1MOD -40
	move.l	#$10affd8,d4		; BPL1MOD -40
	moveq	#28-1,d7			; Anzahl der loops
MakeCop:
	move.l	d0,(a0)+			; wait1
	move.l	d1,(a0)+			; BPL1MOD = 0
	move.l	d2,(a0)+			; BPL2MOD = 0
	add.l	#$01000000,d0		; 1 Zeile überspringen
	move.l	d0,(a0)+			; wait2
	move.l	d3,(a0)+			; BPL1MOD = -40
	move.l	d4,(a0)+			; BPL2MOD = -40
	add.l	#$07000000,d0		; 7 Zeilen überspringen
	cmp.l	#$0407fffe,d0		; sind wir unten $ff?
	bne.s	NoPAl
	move.l	#$ffdffffe,(a0)+	; um auf den PAL-Bereich zuzugreifen
NoPal:
	dbra	d7,MakeCop
	move.l	d0,(a0)+			; wait Ende
	rts


****************************************************************************
; ANIMATION: 8 Bilder Größe 40*29 pixel, mit 8 Farben (3 Bitplanes)
****************************************************************************

; ANIMATION jeder Frame misst 40 * 29 Pixel, 3 Bitebenen. Insgesamt 8 Bilder

Anim:
	incbin "/Sources/frame1"	; 40*29 mit 3 Bitplanes (8 Farben)
	incbin "/Sources/frame2"
	incbin "/Sources/frame3"
	incbin "/Sources/frame4"
	incbin "/Sources/frame5"
	incbin "/Sources/frame6"
	incbin "/Sources/frame7"
	incbin "/Sources/frame8"
EndAnim:

****************************************************************************
;			COPPERLISTE
****************************************************************************

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$8e,DIWS			; DIWSTRT
	dc.w	$90,DIWST			; DIWSTOP
	dc.w	$92,DDFS			; DDFSTRT
	dc.w	$94,DDFST			; DDFSTOP

	dc.w	$102,0				; BPLCON1
	dc.w	$104,0				; BPLCON2
	dc.w	$108,0				; BPL1MOD
	dc.w	$10a,0				; BPL2MOD

Bplpointers:
	dc.w	$e0,0,$e2,0			; erste	   Bitplane
	dc.w	$e4,0,$e6,0			; zweite	  "
	dc.w	$e8,0,$ea,0			; dritte      "

; 8 Farben

	dc.w	$180,$000,$182,$080,$184,$8c6
	dc.w	$186,$c20,$188,$d50,$18a,$e80,$18c,$0fb0
	dc.w	$18e,$ff0

	dc.w	$2c07,$fffe			; wait

	dc.w	$100,BPLC0			; BPLCON0 - 3 planes

	dc.w	$108,-40			; Modulo negativ - wiederhole die gleiche Zeile!
	dc.w	$10a,-40
ExtendCop:
	ds.b	6*4*28				; 2 wait + 4 move = 6*4 bytes * 21 loops
								; Diese copperliste erweitert * 8, was es ist
								; wird mit den Modulen 0 und -40 angezeigt
								; abwechselnd alle 8 Zeilen.
	ds.b	4*2					; Für das $ffdffffe und für das letzte Wait

	dc.w	$100,$200			; BPLCON0 - keine Bitplanes
	dc.w	$ffff,$fffe			; Ende Copperlist

****************************************************************************
; Puffer, in dem jeder Frame "erweitert" wird.
****************************************************************************

	SECTION	LEEREPLANE,BSS_C

Bitplane:						; Wobei jeder Frame erweitert wird.
	ds.b	40*29*3				; 40 Bytes * 29 Zeilen * 3 Bitplanes

	end
