
; Listing23a.s
; Positionierung eines Lowres-Screens 320x256 und Overscan-Screens
; durch Änderung der DIWSTRT-DIWSTOP und DDFSTRT-DDFSTOP Werte
; zusätzlich Sprite-Positionierung
; mit rechter Maustaste Screen-Veränderung überspringen
; mit linker Maustaste raus

	SECTION SCREEN,CODE 
	
;	include	"DaWorkBench.s"	; entferne das; vor dem Speichern mit "wo"

*****************************************************************************
	include	"/Sources/startup2.s" ; speichern Copperlist etc.
*****************************************************************************

			;5432109876543210
DMASET	equ	%1000001110100000	; Copper und Bitplane DMA

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

Start:
	lea	$dff000,a6
	move.w	#DMASET,$96(a6)		; DMACON - aktivieren Copper
	move.l	#Copperlist,$80(a6)	; Zeiger Copperlist
	move.w	d0,$88(a6)			; Start Copperlist
	move.w	#0,$1fc(a6)			; AGA "deaktivieren"
	move.w	#$c00,$106(a6)		; AGA "deaktivieren"
	move.w	#$11,$10c(a6)		; AGA "deaktivieren"
		
	move.l	#Bitplane,d0		; Adresse der Bitplane in d0
	lea	Bplpointers,a1			; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

;	Pointen auf den Sprite
	move.l	#MeinSprite,d0		; Adresse des Sprite in d0
	lea	SpritePointers,a1		; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	move.l	#Bitplane1,ViewBuffer
	move.l	#Bitplane,DrawBuffer
	lea	DiwTab,a0				; Adresse Tabelle mit den DIW und DDF-Werten
	lea SpritePos,a3			; Adresse Tabelle mit den Sprite-Positionen
	lea EndSpritePos,a4			; Endemarke der Tabelle
	lea MeinSprite,a5			; Adresse des Sprites

	bsr	NextDiw					; den ersten Screen einrichten
	moveq	#0,d3				; Startwert Zähler für abgelaufene Zeit	

MainLoop: 
	move.l	#$1ff00,d1			; Bit zur Auswahl durch UND
	move.l	#$13700,d2			; warte auf Zeile $137 (311)
WarteY1:
	move.l	4(a6),d0			; VPOSR und VHPOSR - $dff004/$dff006
	andi.l	d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmpi.l	d2,d0				; warte auf Zeile $137
	bne.s	WarteY1
WarteY2:
	move.l	4(a6),d0			; VPOSR und VHPOSR - $dff004/$dff006
	andi.l	d1,d0				; wählen Sie nur die Bits der vertikalen Pos.
	cmpi.l	d2,d0				; warte auf Zeile $137
	beq.s	WarteY2	

;-- Frames zählen ---	
	add.w	#1,d3				; Durchläufe zählen			
	cmp.w	#50,d3				; etwas Zeit verschwenden
	blo.s	MainLoop
			
	btst	#2,$dff016			; rechte Maustaste gedrückt?
	beq.s	Skip				; wenn ja dann den Screen nicht wechseln
	
	bsr BitplaneClear			; DrawBuffer säubern
	bsr	NextDiw					; nächster Screen
	bsr ChangeScreen			; Draw- und Viewbuffer tauschen
Skip:
	bsr	BewegeSprite			; bewege Sprites
	moveq	#0,d3				; Startwert Zähler zurücksetzen

Mouse:
	btst	#6,$bfe001			; linke Maustaste gedrückt?
	bne.s	MainLoop
	
	rts					
			
******************************************************************************
; Double Buffering - View- und Drawpuffer umkehren
******************************************************************************

ChangeScreen:	
	move.l DrawBuffer(pc),d0		; Adresse DrawBuffer speichern
	move.l ViewBuffer,DrawBuffer	; Adresse ViewBuffer nach DrawBuffer kopieren
	move.l d0,ViewBuffer			; Adresse DrawBuffer nach ViewBufferr kopieren

	lea	Bplpointers,a1			; Pointer in der Copperlist
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	rts

ViewBuffer:		dc.l 0
DrawBuffer:		dc.l 0


*******************************************************************************
* In dieser Routine werden die DIW und DDF-Werte in der Copperliste			  *
* geändert																	  *
*******************************************************************************

NextDiw:	
	move.w (a0)+,d0				; Breite
	move.w (a0)+,d1				; Zeilen		
	bsr BitplaneDraw			; neue Bildpunkte (Rahmen) zeichnen
;---
	lea	EndDiwTab,a1			; Endemarke der Tabelle	
	lea DiwDdf,a2				; Adresse in der Copperliste wo die DIW/DDF Werte
								; ausgetauscht werden
	move.w (a0)+,2(a2)			; Datensatz kopieren
	move.w (a0)+,6(a2)
	move.w (a0)+,10(a2)
	move.w (a0)+,14(a2)	 
	move.w (a0)+,18(a2)			; jetzt noch die dazugehörigen BPLCON1-Werte
	move.w (a0)+,50(a2)			; und die Farbe ändern
;---						
	cmp.l  a0,a1				; am Ende der Tabelle angekommen?
	bne.s NoRestart				; wenn nicht überspringen
	lea DiwTab,a0				; Tabelle wieder von vorn 		
NoRestart:
	rts

*******************************************************************************
* In dieser Routine werden die Spritepositionen des Sprites geändert		  *
*******************************************************************************	

BewegeSprite:
	move.l (a3)+,(a5)			; Datensatz kopieren 
	cmp.l  a3,a4				; am Ende der Tabelle angekommen?
	bne.s NoRestart2			; wenn nicht überspringen
	lea SpritePos,a3			; Tabelle wieder von vorn 	
NoRestart2:
	rts

******************************************************************************
; Bildrahmen zeichnen
******************************************************************************
; Eingang
; d0 - Breite
; d1 - Zeilen
; a0 - 

BitplaneDraw:
	movem.l	d0-d1/a0,-(sp)	

	move.w d0,d4					; Kopie Breite
	move.w d1,d5					; Kopie Zeilen
;-- waagerechte Linie unten/oben ---	
	move.l	DrawBuffer(pc),a0		; Adresse erste Zeile					
	lea (a0),a1						; Adresse letzte Zeile ermitteln
	mulu.w d4,d5					; Breite*Höhe
	adda.w d5,a1					; zur Adresse hinzufügen und 1 Zeile abziehen
	suba.w d0,a1					; letzte Zeile
	
	move.w #$ffff,d2				; Muster für horizontale Linie
	move.w d0,d7					; Breite in Bytes
	lsr.w  #1,d7					; Breite in Words (16px)
	subq.w #1,d7					; Breite-1
Line1:
	move.w d2,(a0)+					; obere Linie zeichnen
	move.w d2,(a1)+					; untere Linie zeichnen
	dbf d7,Line1

;-- horizontale Linie links/rechts ---
	move.l	DrawBuffer(pc),a0		; Adresse erste Zeile
	adda.w d0,a0					; mit der zweiten Zeile beginnen links
	lea  (a0),a1			
	add.w  d0,a1					; die Breite einer Zeile hinzufügen
	subq.w #1,a1					; mit der zweiten Zeile beginnen rechts
	
	move.b #$80,d2					; Muster für senkrechte Linie links
	moveq  #$01,d3					; Muster für senkrechte Linie rechts
	
;--- nur für dc.w 48,286,$1a5f,$38d4,$20,$d8,$77,$0ff --- 
; sie Kommentar am Ende des Listings		
	;move.b #$01,d2					; Muster für senkrechte Linie links
	;moveq  #$10,d3					; Muster für senkrechte Linie rechts

	subq.w #3,d1					; für alle Zeilen-2
Line2:
	move.b d2,(a0)					; linken Rand zeichnen
	move.b d3,(a1)					; rechten Rand zeichnen
	add.w  d0,a0					; nächste Zeile	
	add.w  d0,a1					; nächste Zeile
	dbf d1,Line2

	movem.l	(sp)+,d0-d1/a0
	rts


******************************************************************************
; Bild löschen komplett - lieber mehr als weniger
******************************************************************************

BitplaneClear:
	movem.l	d0/a0,-(sp)	

	move.l	DrawBuffer,a0			; Zeiger auf Bitplane
	moveq	#0,d0					; 
	move.w	#(16000/40)-1,d7		; Anzahl der Bytes geteilt durch 40	
Clr:
	move.l	d0,(a0)+				; zurücksetzen 4 bytes
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	move.l	d0,(a0)+
	dbra	d7,Clr					; und wir machen 400 Schleifen	

	movem.l	(sp)+,d0/a0
	rts

*******************************************************************************
* In dieser Routine werden die DIW und DDF-Werte in der Copperliste geändert  *
*******************************************************************************

; SCRBYTE, SRC_H, DIWSTRT, DIWSTOP, DDFSTRT, DDFSTOP, BPLCON1
DiwTab:
; Standard: horizontal 320x256		 
	dc.w 40,256,$2c81,$2cc1,$38,$d0,$0,$f00	; normale Bildschirmposition für (320x256)
	dc.w 40,256,$2c71,$2cb1,$30,$c8,$0,$0f0	; 16 Pixel nach links
	dc.w 40,256,$2c91,$2cd1,$40,$d8,$0,$00f	; 16 Pixel nach rechts
	dc.w 40,256,$2c61,$2ca1,$28,$c0,$0,$ff0	; 32 Pixel nach links
; Standard: vertikal
	dc.w 40,256,$1a81,$1ac1,$38,$d0,$0,$0ff	; Bild beginnt ganz oben 1. Zeile
	dc.w 40,256,$3881,$38c1,$38,$d0,$0,$f0f	; Bild endet ganz unten letzte Zeile
;------------------------------------------------------------------------------
; erstes sichtbares Pixel links finden 
	dc.w 40,256,$2c51,$2c91,$20,$b8,$0,$fff		; 48 Pixel nach links - Ultra Extreme Debug, wir verlieren Pixel links
	; mit Hardwarescroll nach rechts verschieben, und DIW-Fenster anpassen	
	dc.w 40,256,$2c5f,$2c9f,$20,$b8,$ee,$f00	; laut Aussage $5c ???
; letztes sichtbares Pixel rechts finden 
	dc.w 40,256,$2c94,$2cd4,$40,$d8,$33,$0f0	; 3 Pixel nach rechts
;------------------------------------------------------------------------------
; Standardscreen in allen vier Ecken platziert
	dc.w 40,256,$1a5f,$1a9f,$20,$b8,$ee,$00f	; links oben
	dc.w 40,256,$1a94,$1ad4,$40,$d8,$33,$ff0	; rechts oben
	dc.w 40,256,$3894,$38d4,$40,$d8,$00,$0ff	; rechts unten	
	dc.w 40,256,$385f,$389f,$20,$b8,$ee,$f0f	; links unten
;------------------------------------------------------------------------------
; Overscan 384x286
	dc.w 48,286,$1a51,$38d4,$20,$d8,$33,$fff	; max. Overscan 384x286 rechts ausgerichtet
	dc.w 48,286,$1a51,$38d4,$20,$d8,$ee,$f00	; max. Overscan 384x286 links ausgerichtet
;------------------------------------------------------------------------------
	dc.w 42,256,$2c71,$2cc1,$30,$d0,$0,$0f0		; some games used 336x256 (DDF 30 to d0)
	dc.w 46,286,$1a61,$38d1,$28,$d8,$00,$00f	; 368x286 ok
;------------------------------------------------------------------------------
; maximale Verschiebung
	dc.w 40,256,$ff81,$38c1,$38,$d0,$0,$ff0		; maximale Verschiebung nach unten	
	dc.w 26,286,$1aff,$38cf,$70,$d0,$0,$0ff		; DIWSTRT horizontal ist maximal $FF=255	 208/8=26 ok
	dc.w  6,286,$1af1,$3821,$70,$80,$0,$f0f		; DIWSTOP horizontal ist minimal $(1)00=256	 48/8=6  ok											
	dc.w  4,286,$1af1,$3811,$70,$78,$0,$fff		; 32/8=4  ok
	dc.w  4, 16,$f1f1,$0111,$70,$78,$0,$f00
	dc.w 40,256,$2c91,$2cd1,$40,$d8,$00,$0f0	; ok	
	dc.w 40,256,$2c91,$2cd1,$40,$d8,$33,$00f	; ok
	dc.w 28,256,$2cf1,$2cd1,$70,$d8,$00,$ff0	; ok	Breite 224
;------------------------------------------------------------------------------
; maximalster Screen (komplett sichtbar)
	dc.w 48,286,$1a5f,$38d4,$20,$d8,$77,$0ff	; maximal 373x286  ok	Achtung Kommenta unten beachten
;------------------------------------------------------------------------------
	;dc.w 28,256,$2c81,$2cc8,$18,$d8,$00,$f0f	; erklärt Denise >$(1)d7 = never matches
EndDiwTab:

; Hier ist die Tabelle mit den Sprite-Positionswerten

SpritePos:					; Vstart,Hstart,Vstop		
	dc.b $2c,$40,$39,$00	; normale Position links oben
	dc.b $2c,$d8,$39,$00	; normale Position rechts oben
	dc.b $f2,$40,$ff,$00	; normale Position links unten bis $FF
	dc.b $f2,$d8,$ff,$00	; normale Position rechts unten bis $FF
	dc.b $1f,$40,$2c,$06	; normale Position links unten
	dc.b $1f,$d8,$2c,$06	; normale Position rechts unten
	dc.b $1a,$32,$27,$00	; Overscan - Position links oben	
	dc.b $1a,$de,$27,$00	; Overscan - Position rechts oben						
	dc.b $2a,$32,$37,$06	; Overscan - Position links unten	
	dc.b $2a,$de,$37,$06	; Overscan - Position rechts unten
	dc.b $1a,$2a,$27,$00	; Overscan - Position links oben	; fast verschwunden
	dc.b $1a,$e5,$27,$00	; Overscan - Position rechts oben	; fast verschwunden
	dc.b $2a,$2a,$37,$06	; Overscan - Position links unten	; fast verschwunden
	dc.b $2a,$e5,$37,$06	; Overscan - Position rechts unten	; fast verschwunden
EndSpritePos:

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

	SECTION GRAPHIC,DATA_C

Copperlist:
SpritePointers:
	dc.w	$120,0,$122,0,$124,0,$126,0,$128,0 ; Sprite
	dc.w	$12a,0,$12c,0,$12e,0,$130,0,$132,0
	dc.w	$134,0,$136,0,$138,0,$13a,0,$13c,0
	dc.w	$13e,0

DiwDdf:	
	dc.w	$8e,$2c81,$90,$2cc1,$92,$38,$94,$d0		; diese Werte werden ersetzt	
;----------------------------------------------------------	
	;dc.w	$8e,$2c81	; DIWSTRT
	;dc.w	$90,$2cc1	; DIWSTOP
	;dc.w	$92,$38		; DDFSTRT
	;dc.w	$94,$d0		; DDFSTOP
;----------------------------------------------------------
BplCon1:	
	dc.w	$102,0		; BPLCON1
	dc.w	$104,0		; BPLCON2
	dc.w	$108,0		; BPL1MOD
	dc.w	$10a,0		; BPL2MOD

			    ; 5432109876543210
	dc.w	$100,%0001001000000000  ; Bit 12 an!! 1 Bitplane Lowres
	
Bplpointers:
	dc.w	$e0,0,$e2,0	; erste Bitplane

	dc.w	$180,$666	; COLOR00	; Hintergrund schwarz
	dc.w	$182,$f00	; COLOR01	; Farbe 1 der Bitplane

	dc.w	$1a2,$f00	; COLOR17, oder COLOR1 des Sprite0 - rot
	dc.w	$1a4,$0f0	; COLOR18, oder COLOR2 des Sprite0 - grün
	dc.w	$1a6,$ff0	; COLOR19, oder COLOR3 des Sprite0 - gelb
								
	dc.w	$ffff,$fffe	; Ende der Copperlist
	
************ Hier ist der Sprite: NATÜRLICH muß er in CHIP RAM sein! ************

MeinSprite:	  ; Länge 13 Zeilen
Vstart:
	dc.b $1a  ; Vertikale Anfangsposition des Sprite (von $2c bis $f2)
Hstart:
	dc.b $e5  ; Horizontale Anfangsposition des Sprite (von $40 bis $d8)
Vstop:
	dc.b $27  ; $30+13=$3d - Vertikale Endposition des Sprite
	dc.b $00																						
																						
 dc.w	%0000000000000000,%0000110000110000 ; Binäres Format für ev. Änderungen			
 dc.w	%0000000000000000,%0000011001100000
 dc.w	%0000000000000000,%0000001001000000
 dc.w	%0000000110000000,%0011000110001100 ; BINÄR 00=COLOR 0 (Transparent)
 dc.w	%0000011111100000,%0110011111100110 ; BINÄR 10=COLOR 1 (rot)
 dc.w	%0000011111100000,%1100100110010011 ; BINÄR 01=COLOR 2 (grün)
 dc.w	%0000110110110000,%1111100110011111 ; BINÄR 11=COLOR 3 (gelb)
 dc.w	%0000011111100000,%0000011111100000
 dc.w	%0000011111100000,%0001111001111000
 dc.w	%0000001111000000,%0011101111011100
 dc.w	%0000000110000000,%0011000110001100
 dc.w	%0000000000000000,%1111000000001111
 dc.w	%0000000000000000,%1111000000001111
 dc.w	0,0	; 2 word auf NULL definieren das Ende des Sprite.

******************************************************************************
	
	SECTION	LEEREPLANE,BSS_C

Bitplane:
	ds.b	16000	; 50*300	
BitplaneEnd:

Bitplane1:
	ds.b	16000	; 50*300	
BitplaneEnd1:

	end

Nur aus Interesse wollte ich den größten maximalen umschlossenen Screen finden
und bin durch Tests zu folgendem Ergebnis gekommen:

	dc.w 48,286,$1a5f,$38d4,$20,$d8,$77

oder:
	dc.w	$8e,$1a5f	; DIWSTRT
	dc.w	$90,$38d4	; DIWSTOP
	dc.w	$92,$20		; DDFSTRT
	dc.w	$94,$d8		; DDFSTOP
	dc.w	$102,$77	; BPLCON1

mit erstem Pixel in:	$01	(und nicht $80) -> um 7 px nach rechts verschoben
und letzten Pixel in:	$10	(und nicht $01) -> um 4 Pixel nach links verschoben
Ergebnis Horizontal: 384-7-4=373px

laut: thread 
$1d4-$05c=376px) max horizontal overscan, ($138-$01a=286px) max vertical overscan
aber, durch 'probieren' ermitteltes maximal sichtbare Lowres-Screengröße:
$1d4-$05f=373px) max horizontal overscan, ($138-$01a=286px) max vertical overscan

Es werden 24*16px=384 abgerufen, aber nur 373px anzeigen.
