
; Listing8m4.s - Routine zum Drucken eines Punktes, verwendet in einer Schleife für die
; Berechnung von y = a * x * x oder Parabeln

	SECTION	PUNKT,CODE

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

*****************************************************************************
	include	"/Sources/Startup1.s"		; damit mache ich Einsparungen und 
										; schreib es nicht jedes mal neu!					
*****************************************************************************


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

			;5432109876543210
DMASET	equ	%1000001110000000	; Copper und Bitplane DMA aktivieren
;			 -----a-bcdefghij


Start:
	move.l	#Bitplane,d0		; Adresse der Bitplane
	lea	Bplpointers,a1			; Bitplanepointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	move.w	#DMASET,$96(a5)		; DMACON - Copper und Bitplane DMA aktivieren

	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"

	lea	Bitplane,a0				; Bitplane-Adresse, an der gedruckt werden soll

Mouse:
	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$13000,d2			; Warte auf Zeile = $130 (304)
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 = $130 (304)
	bne.s	WarteY1

	bsr.s	BerechneParabel		; y=a*x*x

	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$13000,d2			; Warte auf Zeile = $130 (304)
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 = $130 (304)
	beq.s	WarteY2

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

;	     ______
;	    /      \
;	   /   oo   \
;	   \___()___/
;	   /       ¬\
;	   \________/
;	   /       ¬\
;	 __\________/__
;	(_____/  \_____)CNT

;	Y=a*x*x, Koeffizienten*d0*d0=d1

BerechneParabel:
	addq.w	#1,MeinX			; das X erhöhen
	move.w	MeinX(pc),d1
	mulu.w	d1,d1				; x*x
	mulu.w	Koeff(pc),d1		; y=a*x*x
	lsr.w	#8,d1				; dividiere durch 256 um das Y "zu erweitern"

	cmp.w	#256,MeinY			; Sind wir unter dem Bildschirm?
	bhi.s	NeuStarten			; wenn ja, wir haben nur 1 Bildschirm !!! dann neu Starten
	cmp.w	#319-160,MeinX		; Sind wir ganz rechts auf dem Bildschirm?
	ble.s	NichtEnde
NeuStarten:
	addq.w	#1,Koeff			; Addiere 1 zum Koeffizienten der Parabel
	cmp.w	#3,Koeff			; Haben wir schon 2 Parabeln gemacht?
	beq.s	Ende				; Wenn ja, gehen wir raus!
	move.w	#-160,MeinX			; und Starten erneut mit X = -160 für die neue Parabel
	rts							; Diesmal gibt es nichts zu zeichnen.

NichtEnde:
	move.w	d1,MeinY

; wir zeichnen den Punkt:

	move.w	MeinX(pc),d0		; Koordinate X
	add.w	#160,d0				; um 160 nach rechts verschieben, da das Ergebnis der
								; Berechnung im Bereich von -160 bis +160 liegt, damit
								; wird es auf die Koordinaten von 0 bis 320 normalisiert
								; ... auf diese Weise bewege ich die Parabel nach rechts.
	move.w	MeinY(pc),d1		; Koordinate  Y
	bsr.s	PlotPix				; den Punkt auf die Koordinate X=d0, Y=d1 drucken

	rts


MeinX:
	dc.w	-160				; Ich beginne von -160, um die Parabel zu "zentrieren".
MeinY:
	dc.w	0

Koeff:
	dc.w	1

*****************************************************************************
;			Routine zum Plotten eines Punktes
*****************************************************************************

;	Eingehende Parameter von PlotPix:
;
;	a0 = Ziel-Bitplane-Adresse
;	d0.w = Koordinate X (0-319)
;	d1.w = Koordinate Y (0-255)

BreiteBildschirm	equ	40		; Bildschirmbreite in Bytes.

PlotPix:
	move.w	d0,d2				; Koordinate X in d2 kopieren 
	lsr.w	#3,d0				; den horizontalen Versatz finden, in dem wir
								; die X-Koordinate durch 8 teilen
	mulu.w	#BreiteBildschirm,d1
	add.w	d1,d0				; den vertikalen zum horizontalen Versatz hinzufügen

	and.w	#%111,d2			; nur die ersten 3 Bits von X auswählen
								; (In Wirklichkeit wäre es der Rest der Division
								; durch 8, vorher gemacht)
	not.w	d2					; negieren

	bset.b	d2,(a0,d0.w)		; Bit d2 des Bytes setzen, das d0 Bytes 
								; vom Anfang des Bildschirms entfernt ist
	rts

*****************************************************************************

	SECTION	GRAPHIC,DATA_C

Copperlist:
	dc.w	$8e,$2c81			; DIWSTRT
	dc.w	$90,$2cc1			; DIWSTOP
	dc.w	$92,$0038			; DDFSTRT
	dc.w	$94,$00d0			; DDFSTOP
	dc.w	$102,0				; BPLCON1
	dc.w	$104,$24			; BPLCON2 - Alle Sprites über der Bitplane
	dc.w	$108,0				; BPL1MOD
	dc.w	$10a,0				; BPL2MOD
				; 5432109876543210
	dc.w	$100,%0001001000000000	; 1 Bitplane LOWRES 320x256

Bplpointers:
	dc.w	$e0,0,$e2,0			; erste Bitplane

	dc.w	$0180,$000			; COLOR00 - Hintergrund
	dc.w	$0182,$1af			; COLOR01 - Schrift

	dc.w	$ffff,$fffe			; Ende Copperlist


*****************************************************************************

	SECTION	MEINEPLANE,BSS_C

Bitplane:
	ds.b	40*256				; eine Bitplane lowres 320x256

	end

Die wichtigste Änderung hierbei ist, dass wir die Parabel in Richtung rechts
"verschoben" haben und damit auch den negativen Teil, der sich erhebt
"Aufdecken":

		**
      *	    *
   *	      *
 *		 0		*
       NULL

Wie Sie aus dem Schema ersehen können, ist die Kurve mit dem X kleiner als Null
entgegengesetzt, oder spiegelnd, vah... 
Um das zu sehen, fangen wir einfach mit einem x von -160 an steigen auf +160 an. 
Dann "verschieben" wir das Ganze um 160 nach rechts und zentrieren die Parabel,
mit einem einfachen add.w #160,d0. Aus -160 wird 0 und +160 wird 320.

In diesem Beispiel haben wir auch einen Koeffizienten eingefügt, mit dem wir
x * x multiplizieren, was zu zwei Parabeln führt, eine "breiter" als die andere.

Ein letzter Hinweis: Damit die Parabel "sichtbarer" und weniger gestrichelt
ist, wird die Y-Koordinate durch 256 mit einem LSR #8 geteilt.

	lsr.w	#8,d1				; dividiere durch 256 das Y um "zu erweitern"

Wie Sie wissen, können Sie mit lsr Potenzen von 2 dividieren oder mit lsl 
multiplizieren, auch wenn es nicht ganz mit einem mulu oder divu
"gleichzusetzen" ist. In diesem Fall aber funktioniert es ganz gut...

P.S: Ab diesem Listing wird die PlotPix-Routine ohne die Megakommentare von den
vorherigen Listings sein...  es hat keinen Sinn, die Quelle zu verlängern!
                                                                                                                                                                         X = 3	-> Y= 3*3, d.h. 9
