
; Listing8n3.s - Optimierte Punktdruckroutine.
; Eine Tabelle wird verwendet, um einen Punkt zu "verschieben". 
; Rechte Taste um die "Spur zu verlassen" auf den Punkt bringen.

	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

BreiteBildschirm	equ	40		; Bildschirmbreite in Bytes

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)

; Wir bereiten eine Tabelle mit den Vielfachen von 40 oder der Breite des
; Bildschirms vor, um eine Multiplikation für jeden Plot zu vermeiden.

	lea	MulTab,a0				; Adressraum mit 256 Wörtern zum Schreiben
								; der Vielfachen von 40 ...
	moveq	#0,d0				; wir beginnen mit 0 ...
	move.w	#256-1,d7			; Anzahl der benötigten Vielfachen von 40
PreCalcLoop
	move.w	d0,(a0)+			; Speichere das aktuelle Vielfache
	add.w	#BreiteBildschirm,d0		; Wir addieren die Bildschirmgröße, nächstes Vielfaches
	dbra	d7,PreCalcLoop		; Wir erstellen alle MulTab
	
	move.w	#DMASET,$96(a5)		; DMACON - aktivieren Bitplane, Copper
								
; Zeiger auf die Copperlist	
	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 in a0 gedruckt werden soll
	lea	MulTab,a1				; Tabellenadresse mit Vielfachen der Bildschirmbreite
								; vorberechneter Bildschirm in a1

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.w	LiesTabelle			; Liest die X- und Y-Positionen aus den Tabellen

	move.w	MeinX(pc),d0		; Koordinate X
	move.w	MeinY(pc),d1		; Koordinate Y

	bsr.w	PlotPixP			; den Punkt auf die Koordinate X=d0, Y=d1 drucken

	btst	#2,$16(a5)			; rechte Maustaste gedrückt?
	beq.s	NotErase

	move.w	MeinXalt(pc),d0		; alte X-Koordinate, die gelöscht werden soll
	move.w	MeinYalt(pc),d1		; alte Y-Koordinate

	bsr.w	ErasePixP			; den Punkt auf die Koordinate X=d0, Y=d1 zurücksetzen

NotErase:
	move.w	MeinX(pc),MeinXalt	; die Koordinaten des Punktes vorbereiten, den wir löschen wollen
	move.w	MeinY(pc),MeinYalt	; danach

	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			; linke Maustaste gedrückt?
	bne.s	Mouse
	rts							; exit

	
MeinX:
	dc.w	0
MeinY:
	dc.w	0
MeinXalt:
	dc.w	0
MeinYalt:
	dc.w	0


*****************************************************************************
;		Routine zum Plotten eines Punktes - optimiert
*****************************************************************************

;	Eingehende Parameter von PlotPixP:
;
;	a0 = Ziel-Bitplane-Adresse
;	a1 = Adresse der Tabelle mit den vorberechneten Vielfachen von 40
;	d0.w = Koordinate X (0-319)
;	d1.w = Koordinate Y (0-255)

;	    .....
;	  __\ oO/__
;	 / _ \./ _ \
;	/\/|  "  |\/\
;	\ \|_____|/ /
;	 \ \_(_)_| /
;	  \\\     \
;	 /   \/    \
;	 \____\____/
;	(_____\_____)eD
;

PlotPixP:
	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
	add.w	d1,d1				; wir multiplizieren das Y mit 2 und finden den Versatz
	add.w	(a1,d1.w),d0		; vertikaler Versatz + horizontaler Versatz
	and.w	#%111,d2			; nur die ersten 3 Bits von X auswählen (Rest)
	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

; Routine, die ein Pixel löscht. Ersetzen Sie einfach BSET durch BCLR.

ErasePixP:
	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
	add.w	d1,d1				; wir multiplizieren das Y mit 2 und finden den Versatz
	add.w	(a1,d1.w),d0		; vertikaler Versatz + horizontaler Versatz
	and.w	#%111,d2			; nur die ersten 3 Bits von X auswählen (Rest)
	not.w	d2					; negieren
	bclr	d2,(a0,d0.w)		; Bit d2 des Bytes setzen, das d0 Bytes 
								; vom Anfang des Bildschirms entfernt ist
	rts

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

LiesTabelle:
	move.l	a0,-(sp)			; a0 im Stack speichern
	addq.l	#1,TabYpoint		; auf das nächste Byte zeigen
	move.l	TabYpoint(pc),a0	; Adresse, die im long TabXpoint enthalten ist
								; nach a0 kopieren
	cmp.l	#EndeTabY-1,a0		; Sind wir am letzten Byte der TAB?
	bne.s	NobStartY			; noch nicht? dann geht es weiter
	move.l	#TabY-1,TabYpoint	; wir beginnen wieder mit dem ersten Byte
NobStartY:
	moveq	#0,d0				; d0 zurücksetzen
	move.b	(a0),d0				; das Byte aus der Tabelle kopieren, dh die
								; Y-Koordinate in d0, damit Sie es tun können
								; finde zur universellen Routine

	addq.l	#2,TabXpoint		; auf das nächste Wort zeigen
	move.l	TabXpoint(pc),a0	; Adresse, die im long TabXpoint enthalten ist
								; nach a0 kopieren
	cmp.l	#EndeTabX-2,a0		; Sind wir beim letzten Wort der TAB?
	bne.s	NobStartX			; noch nicht? dann geht es weiter
	move.l	#TabX-2,TabXpoint	; wir beginnen wieder mit dem ersten Wort-2
NobStartX:
	moveq	#0,d1				; d1 zurücksetzen
	move.w	(a0),d1				; wir setzen den Wert der Tabelle, das heißt
								; die X-Koordinate in d1
	move.w	d0,MeinY			; die Koordinaten speichern
	move.w	d1,MeinX
	move.l	(sp)+,a0			; a0 vom Stack wiederherstellen
	rts


TabYpoint:
	dc.l	TabY-1				; HINWEIS: Die Werte in der Tabelle sind Bytes
TabXpoint:
	dc.l	TabX-2				; HINWEIS: Die hier angegebenen Tabellenwerte sind Wörter

; Tabelle mit Koordinaten Y

TabY:
	incbin	"/Sources/ycoordinatok.tab"	; 200 Werte .B
EndeTabY:

; Tabelle mit Koordinaten X

TabX:
	incbin	"/Sources/xcoordinatok.tab"	; 150 Werte .W
EndeTabX:

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

	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

; Tabelle, die die vorberechneten Vielfachen der Bildschirmbreite enthält
; zur Beseitigung der Multiplikation in der PlotPix-Routine und zur Erhöhung 
; ihrer Geschwindigkeit.

	SECTION	PRECALC,BSS

MulTab:
	ds.w	256

	end

In diesem Beispiel haben wir einfach die Routine hinzugefügt, die aus den 2
Tabellen die X- und Y-Koordinaten, wie für Sprites liest. Wie Sie sehen können,
ist es auch für Routinen zum Drucken von Punkten nützlich. Durch die Erstellung
komplexerer Tabellen und Routinen können Sie verschiedene Wellen erhalten.
                                                                                                                                                                                                                    n.
