
; Listing11l5b.s   - "Zoom" Animation, die nur 40*29 pixel misst.
; Die endgültige Auflösung beträgt 320 * 232, also das Achtfache.
; VERSION DURCH TABELLE OPTIMIERT!

	SECTION ZOOM,CODE

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

*****************************************************************************
	include "/Sources/startup2.s"	; speichern Sie Interrupt, DMA und so weiter.
*****************************************************************************

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

			;5432109876543210
DMASET	equ	%1000001110000000	; GRAPHIC, 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
BpLoop:
	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,BpLoop

	bsr.w	PreCalCop			; Tabelle Turbo mit vorkalibrierten "erweiterten" Bytes erstellen.

	bsr.w	CreateCop			; Erstellen der Copperliste, die 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
WarteY1:
	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	WarteY1
WarteY2:
	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	WarteY2

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

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

****************************************************************************
; Routine die "ZoomFrame" alle 7 Frames macht, um zu verlangsamen
****************************************************************************

ChangeFrame:
	addq.b	#1,WaitFlag
	cmp.b	#7,WaitFlag			; wurden 7 Frames übergeben? (um langsamer zu werden)
	bne.s	NotNow
	clr.b	WaitFlag
	bsr.w	ZoomFrame			; wenn ja, "erweitere" den nächsten Frame!
NotNow:
	rts

WaitFlag:
	dc.w	0

****************************************************************************
; "Erweiterung" der Bilder: Jedes Bit wird getestet, und je nachdem, ob letzteres
; gesetzt oder zurückgesetzt ist, wird ein Byte $ff oder $00 eingegeben.
; Dies ist eine OPTIMIERTE-Version, die eine Tabelle verwendet, die die
; Werte "erweitert" für jedes mögliche Byte (eines von 256 Möglichen).
****************************************************************************

;	    .----.
;	___ `-/\-' ____
;	\_ \_/  \_/ __/
;	  \___  ___/
;	   _(_\/_)_
;	   \  `'  /
;	    \``''/
;	    :\  /:
;	    ! \/ !
;	     _|l_

ZoomFrame:
	move.l	AnimPointer(pc),a0	; Frame klein aktuell (40*29)
	lea	Bitplane,a1				; Puffer Ziel (zu 320*29)
	move.w	#(5*29*3)-1,d7		; 5 Bytes pro Zeile * 29 Zeilen * 3 Bitplanes
Animloop:
	moveq	#0,d0
	move.b	(a0)+,d0			; nächstes Byte in d0
	lsl.w	#3,d0				; d0*8 um den Wert in der Tabelle zu finden
								; (d.h. der Offset von seinem Anfang)
	lea	PreCalTab,a2
	lea	0(a2,d0.w),a2			; in a2 die Adresse im 8-Byte-Tab
								; "Erweiterung" der 8 Bits.
	move.l	(a2)+,(a1)+			; 4 Bytes erweitert
	move.l	(a2),(a1)+			; 4 Bytes erweitert (total 8 Bytes!!)

	dbra	d7,Animloop			; Konvertieren des gesamten Frames

	add.l	#(5*29)*3,AnimPointer	; Zeigen Sie auf den nächsten Frame
	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, mit dem ersten beginnen
DoNotStartAgain:
	rts

AnimPointer:
	dc.l	Anim

****************************************************************************
; Routine, die die Copperliste erstellt, die das Bild um das 8-fache verlängert,
; Modulos wie folgt: warten Sie auf eine Zeile und setzen Sie das Modulo auf 0,
; die nach der Zeile einrastet, dann die Zeile darunter erneut abwartet und das
; Modulo auf -40, so dass die gleiche Zeile pro Zeile unten "repliziert" wird.
; Nach 7 Warte-Zeilen setzte das Modulo für eine Zeile auf 0;
; Klicken Sie auf eine Zeile darunter und setzen Sie das Modulo für weitere 7 
; 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 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 tiefer
	move.l	d0,(a0)+			; wait2
	move.l	d3,(a0)+			; BPL1MOD = -40
	move.l	d4,(a0)+			; BPL2MOD = -40
	add.l	#$07000000,d0		; springe 7 Zeilen
	cmp.l	#$0407fffe,d0		; sind wir unten $ff?
	bne.s	NoPal
	move.l	#$ffdffffe,(a0)+	; Zugang zum Bereich PAL
NoPal:
	dbra	d7,MakeCop
	move.l	d0,(a0)+			; wait Ende
	rts

****************************************************************************
; Routine, die alle möglichen 8 Bytes in Kombination mit möglichen
; 8-Bit vorberechnet. Für alle $ff bedeutet es, das heißt, 255.
****************************************************************************

PreCalCop:
	lea	PreCalTab,a1			; Ziel
	moveq	#0,d0				; Teile von Null
EndTab:
	moveq	#8-1,d1				; 8 bit die sie steuern und erweitern möchten.
ByteLoop:
	btst.l	d1,d0				; Testen des aktuellen Schleifenbits
	beq.s	BitClear			; ist es zurückgesetzt?
	st.b	(a1)+				; wenn nein, lege 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.	
	addq.w	#1,d0				; nächster Wert
	cmp.w	#256,d0				; Haben wir alle gemacht? (max $ff)
	bne.s	EndTab
	rts

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

; Animation jedes Frame mist 40*29 pixel, 3 Bitplanes. Tot. 8 frames

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 - Wiederholen Sie die gleiche Zeile!
	dc.w	$10a,-40
ExtendCop:
	ds.b	6*4*28				; 2 wait + 4 move = 6*4 bytes * 21 loops
								; Diese Copperliste verlängert, was
								; Verwendung der Module 0 und -40
								; abwechselnd alle 8 Zeilen.
	ds.b	4*2					; Für die $ffdffffe und letzte Wartezeit

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

****************************************************************************
; Puffer mit der Tabelle für den vorkalkulierten Zoom
****************************************************************************

	SECTION	PRECALTAB,BSS

PreCalTab:
	ds.b	256*8

****************************************************************************
; Puffer, bei dem pro Frame "erweitert" wird.
****************************************************************************

	SECTION	LEEREPLANE,BSS_C

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

	end