
; Listing11l6.s		Routine Interlaced Mode Management (640x512)
; der das Bit 15 (LOF) von VPOSR ($dff004) liest.
; Wenn Sie die rechte Taste drücken, wird diese Prozedur nicht ausgeführt
; und Sie bemerken, wie die geraden Zeilen oder sogar Zeilen manchmal 
; seltsam in "pseudo-non-lace" bleiben.

	SECTION	INTERLACE,CODE

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

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

			;5432109876543210
DMASET	equ	%1000001110000000	; nur Copper und Bitplane DMA

WAITDISK	equ	30

SCRBYTES	= 80				; Anzahl der Bytes für jede horizontale Zeile.
								; 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		= 2					; 2 = HighRes (640*xxx) / 1 = LowRes (320*xxx)
SCR_LACE	= 1					; 0 = non interlace (xxx*256) / 1 = interlace (xxx*512)
HAM			= 0					; 0 = non HAM / 1 = HAM
SCR_BPL		= 1					; Anzahl Bitplanes

; Parameter automatisch berechnet

SCR_W		= SCRBYTES*8		; Bildschirmbreite
SCR_SIZE	= SCRBYTES*SCR_H	; Größe in Bytes des Bildschirms
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:

;	Zeiger Bitplanes in Copperlist

	move.l	#Bitplane,d0		; Adresse der Bitplane in d0
	lea	Bplpointers,a1			; Zeiger auf Copperlist
	move.w	d0,6(a1)			; kopiert das niedrige Wort der Bitplaneadresse
	swap	d0					; tauscht die 2 Wörter von d0 aus (1234 > 3412)
	move.w	d0,2(a1)			; kopiert das hohe Wort der Bitplaneadresse
	
	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	#$01000,d2			; warte auf Zeile $010
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 $010
	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 $010
	beq.s	WarteY2

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

	bsr.s	LaceInt				; Routine splittet ungerade oder gerade Linien
								; je nach LOF-Bit für das Interlace
NoLaceInt:
	bsr.w	PrintCharacter		; Drucken Sie jeweils ein Zeichen

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

	rts

******************************************************************************
; INTERLACE Routine - Test Bit LOF (Long Frame) um zu wissen, ob Sie
; gerade oder ungerade Zeilen anzeigen und entsprechend wechseln müssen.
******************************************************************************

LaceInt:
	move.l	#Bitplane,d0		; Adresse Bitplane
	btst.b	#15-8,4(a5)			; VPOSR LOF bit?
	beq.s	MakeOdd				; wenn ja, zeigen Sie auf ungerade Zeilen
	add.l	#SCRBYTES,d0		; Oder fügen Sie die Länge einer Zeile hinzu,
								; Starten der Ansicht von den geraden Zeilen!
								; gerade Zeilen werden angezeigt!
MakeOdd:
	lea	Bplpointers,a1			; Bitplanepointer in Copperlist
	move.w	d0,6(a1)			; Zeiger auf das Bild
	swap	d0
	move.w	d0,2(a1)
	rts

*****************************************************************************
;			Druck Routine
*****************************************************************************

PrintCharacter:
	move.l	PointerText(pc),a0	; Adresse des zu druckenden Textes a0
	moveq	#0,d2				; d2 löschen
	move.b	(a0)+,d2			; nächstes Zeichen in d2
	cmp.b	#$ff,d2				; Ende des Textsignals? ($ff)
	beq.s	EndText				; Wenn ja, beenden Sie ohne zu drucken
	tst.b	d2					; Zeilenende-Signal? ($00)
	bne.s	NotEndLine			; Wenn nicht, nicht aufhören

	add.l	#SCRBYTES*7,PointerBitplane	; wir gehen zum Anfang
	addq.l	#1,PointerText		; erste Zeichenzeile danach
								; (überspringe die NULL)
	move.b	(a0)+,d2			; erstes Zeichen der Zeile nach
								; (überspringe die NULL)

NotEndLine:
	sub.b	#$20,d2				; ZÄHLE 32 VOM ASCII-WERT DES BUCHSTABEN WEG
								; SOMIT VERWANDELN WIR Z.B. DAS LEERZEICHEN
								; (Das $20 entspricht), IN $00, DAS
								; AUSRUFUNGSZEICHEN ($21) IN $01...
	lsl.w	#3,d2				; MULTIPLIZIERE DIE ERHALTENE ZAHL MIT 8,
								; da die Charakter ja 8 Pixel hoch sind
	move.l	d2,a2
	add.l	#Font,a2			; FINDE DEN GEWÜNSCHTEN BUCHSTABEN IM FONT...

	move.l	PointerBitplane(pc),a3 ; Adresse Ziel-Bitplane in a3

								; DRUCKE DEN BUCHSTABEN ZEILE FÜR ZEILE
	move.b	(a2)+,(a3)			; Drucke Zeile 1 des Zeichens
	move.b	(a2)+,SCRBYTES(a3)		; Drucke Zeile  2  " "
	move.b	(a2)+,SCRBYTES*2(a3)	; Drucke Zeile  3  " "
	move.b	(a2)+,SCRBYTES*3(a3)	; Drucke Zeile  4  " "
	move.b	(a2)+,SCRBYTES*4(a3)	; Drucke Zeile  5  " "
	move.b	(a2)+,SCRBYTES*5(a3)	; Drucke Zeile  6  " "
	move.b	(a2)+,SCRBYTES*6(a3)	; Drucke Zeile  7  " "
	move.b	(a2)+,SCRBYTES*7(a3)	; Drucke Zeile  8  " "

	addq.l	#1,PointerBitplane	; wir rücken 8 Bits vor (NÄCHSTES ZEICHEN)
	addq.l	#1,PointerText		; nächstes zu druckendes Zeichen

EndText:
	rts

PointerText:
	dc.l	Text

PointerBitplane:
	dc.l	Bitplane

;	$00 für "Zeilenende" - $ff für "Textende"

		; Anzahl der Zeichen pro Zeile: 40
Text:	     ;		  1111111111222222222233333333334
             ;   1234567890123456789012345678901234567890
	dc.b	' Che scritte piccole! Non si leggono nem'   ; 1
	dc.b	'meno... ma sono in 640x512!             ',0 ; 1b
;
	dc.b	'Provate a premere il tasto destro e potr'   ; 2
	dc.b	'ete verificare cosa vedono i coder che  ',0 ; 2b
;
	dc.b	"non sanno come funziona l'interlace, hah"   ; 3
	dc.b	"aha! In fondo e' semplice, no?          ",0 ; 3b
;
	dc.b	'Programmate, fate qualche demo o qualche'   ; 4
	dc.b	" gioco, e' la cosa piu' creativa che si ",0 ; 4b
;
	dc.b	'possa fare nel mondo contemporaneo.     '   ; 5
	dc.b	'                                        ',$ff ; 5b - Ende

	even


;	Die Font-Zeichen 8x8.

Font:
	incbin	"/Sources/nice.fnt"

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

	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,80		; BPL1MOD \ INTERLACE: modulo = Länge Zeile!
	dc.w	$10a,80		; BPL2MOD / um sie zu überspringen (die geraden)

				; 5432109876543210
;	dc.w	$100,%1001001000000100	; 1 Bitplane, HIRES LACE 640x512
;								; Beachten Sie das Bit 2 Set für LACE!!

	dc.w	$100,BPLC0			; BPLCON0 -> lassen Sie es uns automatisch berechnen!
	
Bplpointers:
	dc.w	$e0,$0000,$e2,$0000	; erste Bitplane

	dc.w	$180,$226			; COLOR00 - Hintergrund
	dc.w	$182,$0b0			; COLOR01 - erste Bitplane Position normal, und
								; der "klebende" Teil an der Spitze.

	dc.w	$ffff,$fffe			; Ende Copperlist

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

	SECTION	LEEREPLANE,BSS_C

Bitplane:
	ds.b	SCRBYTES*SCR_H		; 80*512 eine Bitplane Hires int. 640x512

	end

Es sei darauf hingewiesen, dass das System der automatischen Berechnung der
DIWSTRT/STOP usw. gilt. Denken Sie jedoch für das Interlace daran, dass
Sie das Modulo auf "SCRBYTES", in diesem Fall auf 80 setzen.
