
*************************************************
*	DOUBLE DAMMIER EN SCROLLING		*
*						*
*	Copyright	© 13 décembre 1990	*
*	Auteur		Pierre Philippe Launay	*
*						*
*	Dual-Playfield & Scrolling		*
*	D' après La Bible de l' Amiga		*
*************************************************

	opt ow+		Optimisation
*	opt s+		Liste la table des symboles
	opt d+		Débugage en clair

*****************
*	MACROS	*
*****************

Alloue	MACRO
	jsr	AllocMem(a6)		Allocation
	move.l	d0,Pointeur\1		Je Sauve le pointeur
	beq	Fin_\2			Si cela devait arriver
	ENDM

Libère	MACRO
	move.l	Pointeur\1,a1		Mémoire à libérer
	jsr	FreeMem(a6)		Libération de mémoire
	ENDM

_DiwStart	MACRO			(FenêtreY2 D0, FenêtreX2 D1, $100 D2)
	moveq.l	#Fenêtre\1Y1,d0
	lsl.l	#8,d0
	moveq.l	#Fenêtre\1X1,d1
	add.l	d1,d0			J' obtiens    yyyyyyyy xxxxxxxx
	move.w	d0,DIWSTRT(a5)		Début de la fenêtre
	ENDM

_DiwStop	MACRO			(FenêtreY2 D0, FenêtreX2 D1, $100 D2)
	move.l #$100,d2			Il faut soustraire 256 à Y2
	move.l	#Fenêtre\1Y2,d0	
	sub.l	d2,d0			
	lsl.l	#8,d0
	move.l	#Fenêtre\1X2,d1
	sub.l	d2,d1
	add.l	d1,d0			J' obtiens     yyyyyyyy xxxxxxxx
	move.w	d0,DIWSTOP(a5)		Fin de la fenêtre
	ENDM

_DdfStart	MACRO			(FenêtreX1 D0, $FFFB D1, $11 D2)
	move.l	#Fenêtre\1X1,d0
	move.w	#$fff8,d1		Mode Basse Résolution :
	move.w	#$21,d2			(FenêtreX1-$11)/2 and $fff8
	sub.l	d2,d0			Décalage : +$10 en D2
	lsr.l	#1,d0			Mode Haute Résolution :
	and.l	d1,d0			(FenêtreX1-$09)/2 and $fffc
	move.w	d0,DDFSTRT(a5)		Début de lecture du DMA
	ENDM

_DdfStop	MACRO			(DDFSTRT D0, Résolution D1, $10 D2)
	add.l	#$20,d0			Décalage : DDFSTRT +$20 en D0
	move.l	#$140,d1
	move.l	#$10,d2			Mode Basse Résolution :
	sub.l	d2,d1			DDFSTRT +(320-$10)/2
	lsr.l	#1,d1			Mode Haute Résolution :
	add	d1,d0			DDFSTRT + (640-$20)/4
	move.w	d0,DDFSTOP(a5)		Fin de lecture du DMA
	ENDM

_LitDemiCopper	MACRO			(Pointeur D1, Registre D3, $02 D5)
	move.w	d3,(a0)+		Registre souhaité en A0
	add.w	d5,d3			Registre suivant soit mot suivant
	swap	d1			Inversion Haut et Bas mot du pointeur
	move.w	d1,(a0)+		Moitié du Pointeur
	ENDM

*************************
*	CONSTANTES	*
*************************

**%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	registres des circuits spécialisés	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
VPOSR	= $004		Position haute du faisceau d' électron	(lecture)
DMACON  = $096		Registre de contrôle DMA		(Ecriture)
INTENA  = $09A		Registre Interruption activé		(Ecriture)
COLOR00 = $180		Registre de la couleur 0

*%%%%%%%%%%%%%%%%%%%%%%%*
*	registre COPPER	*
*%%%%%%%%%%%%%%%%%%%%%%%*
COPPER  = $DFF000	Adresse de base de la zône des registres du Copper
COP1LC  = $080		Adresse de la première liste Copper
COP2LC  = $084		Adresse de la seconde liste Copper
COPJMP1 = $088		Redémarrage de la première liste Copper
COPJMP2 = $08A		Redémarrage de la seconde liste Copper

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	registre des plans de bits	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
BPL1PTH	=	$0E0	Pointeur sur le premier plan de bits
BPL1PTL	=	$0E2	Idem
DIWSTRT	=	$08E	Début de la fenêtre écran
DIWSTOP	=	$090	Fin de la fenêtre écran
DDFSTRT	=	$092	Début du plan de bits DMA
DDFSTOP	=	$094	Fin du plan de bits DMA
BPLCON0	=	$100	Contrôle du plan de bit 0
BPLCON1	=	$102	Contrôle du plan de bit 1 (Valeur du scrolling)
BPLCON2	=	$104	Contrôle du plan de bit 2 (Lutin <> priorité playfield)
BPL1MOD	=	$108	Valeur du modulo des plans de bits impairs
BPL2MOD	=	$10A	Valeur du modulo des plans de bits pairs

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*	CIA-A registre port A	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CIAAPRA = $BFE001	Registre de données port A du CIA-A

*************************
*	BIBLIOTHEQUES	*
*************************

*%%%%%%%%%%%%%%%%%%%%%%%*
*	Exec library	*
*%%%%%%%%%%%%%%%%%%%%%%%*
OpenLibrary	= -552	Ouverture (Nom A1, Version D0)
Forbid		= -132	Monotâche ()
Permit		= -138	Multitâche ()
AllocMem	= -198	Occupation d' un signal de tâche (Taille D0, Type D1)
FreeMem		= -210	Vide la mémoire (Pointeur A1, Taille D0)	

*%%%%%%%%%%%%%%%%%%%%%%%*
*	graphicbase	*
*%%%%%%%%%%%%%%%%%%%%%%%*

StartList	= 38

*%%%%%%%%%%%%%%%%%%%%%%%*
*	autres labels	*
*%%%%%%%%%%%%%%%%%%%%%%%*
Execbase	= 4		Ad vitam eternam pour cause de reset
Chip		= 2		AllocMem sur CHIP pour le Blitter
Clear		= $10002	Chip-Ram réservée

Colonne		= 52		416 points divisés par 8
Ligne		= 345

HauteurRectangle= 8

Fenêtre1X1	= 100	$64	Valeur de la fenêtre écran
Fenêtre1Y1	= 026	$1a
Fenêtre1X2	= 465	$d1
Fenêtre1Y2	= 313	$39

PasVertical	= 002		Valeur du scrolling
PasHorizontal	= 001

EpaisseurImage1	= 4		Nombre de plans de l' image
LongueurPlan1	= Colonne*Ligne	345 lignes fois 52 octets
LongueurCopper1	= 13*4		13 instructions fois 4 octets
LongueurImage1	= LongueurPlan1*EpaisseurImage1

Début:	movea.l	Execbase,a6

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Allocation de mémoire	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	move.l	#LongueurImage1,d0	Mémoire nécessaire
	move.l	#Clear,d1		Type de mémoire utilisée
	Alloue	Image1,Retour		Les divers plans de l' image

	moveq	#LongueurCopper1,d0	Mémoire nécessaire
	moveq	#Chip,d1		Type de mémoire utilisée
	Alloue	Copper1,Plan		La liste du copper

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Installation de la liste du Copper	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	moveq	#EpaisseurImage1-1,d4			Valeur du compteur = 2 plans -1
	moveq.w	#2,d5			2 octets mais gain dans la boucle
	move.l	#LongueurPlan1,d6	6 octets mais gain dans la boucle
	movea.l	d0,a0			Adresse de la liste du copper
	move.l	PointeurImage1(pc),d1	Adresse des plans de bits	
	move.w	#BPL1PTH,d3		Premier plan de bits

Installe_Copper:
	_LitDemiCopper			Haut mot du pointeur en RAM
	_LitDemiCopper			Bas mot du pointeur en RAM	
	add.l	d6,d1			Adresse du prochain plan calculé
	dbf	d4,Installe_Copper	Il y a d4+1 plans

	move.l	#$FFFFFFFE,(a0)		Fin de la liste du copper

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Blocage du DMA Copper et monotâche	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	jsr	Forbid(a6)		Monotâche
	lea	COPPER,a5		Adresse de base du copper en A5
	move.w	#$01E0,DMACON(a5)	Blocage du DMA

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Initialisation de la liste du Copper	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	move.l	PointeurCopper1(pc),COP1LC(a5)
	clr.w	COPJMP1(a5)

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Création de la palette de couleurs	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	move.w	#$000,COLOR00(a5)	Couleur 0	R0123 V0123 B0123
	move.w	#$50f,COLOR00+2(a5)	Couleur 1	R0123 V0123 B0123
	move.w	#$05f,COLOR00+4(a5)	Couleur	2	R0123 V0123 B0123
	move.w	#$fff,COLOR00+6(a5)	Couleur 3	R0123 V0123 B0123
	move.w	#$00f,COLOR00+18(a5)	Couleur 9	R0123 V0123 B0123
	move.w	#$f00,COLOR00+20(a5)	Couleur 10	R0123 V0123 B0123
	move.w	#$005,COLOR00+22(a5)	Couleur 11	R0123 V0123 B0123
	move.w	#$0f0,COLOR00+24(a5)	Couleur 12	R0123 V0123 B0123


*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Initialisation du champ de jeu Playfield*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	_DiwStart	1		Valeur de DIWSTRT du champ de jeu 1
	_DiwStop	1		Valeur de DIWSTOP du champ de jeu 1
	_DdfStart	1		Valeur de DDFSTRT du champ de jeu 1
	_DdfStop			Valeur de DDFSTOP du champ de jeu 1

	move.w 	#%0100110000000100,BPLCON0(a5)	Plans de bits

	move.w	#$00,BPLCON1(a5)	Scroling nul
	move.w	#$40,BPLCON2(a5)	Priorité plans pairs / plans impairs
	move.w	#$04,BPL1MOD(a5)	Décalage modulo de 2 mots
	move.w	#$04,BPL2MOD(a5)	Décalage modulo de 2 mots

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Activation du DMA	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	move.w	#$8380,DMACON(a5)

*%%%%%%%%%%%%%%%%%%%%%%%*
*	Le Damier	*
*%%%%%%%%%%%%%%%%%%%%%%%*
	move.l	PointeurImage1,a0	Je pointe sur le début de l' image	
	move.w	#LongueurPlan1-1,d0	Un pavé d' image sur 2
	move.w	#HauteurRectangle*13,d1	16 lignes maximum * 13 longs mots
	move.l	#$ffff0f0f,d2		Motif du pavé de 32 points
	move.w	d1,d3

Remplissage:
	move.l	d2,(a0)+		Motif du pavé mis dans l' image
	subq.w	#1,d3			Décrémentation de la boucle
	bne.s	Début_Scrolling		Jusqu' à 16 lignes
	rol.l	d2			Diagonale de 1 point
	rol.l	d2			Diagonale de 1 point
	swap	d2			Inversion du motif créant le damier
	rol.l	d2			Diagonale de 1 point
	move.w	d1,d3			Compteur remis à D1
Début_Scrolling:
	dbf	d0,Remplissage

*%%%%%%%%%%%%%%%%%%%%%%%*
*	Scrolling	*
*%%%%%%%%%%%%%%%%%%%%%%%*
	moveq.l	#0,d0			Mise à 0 du pas de scrolling vertical
	moveq.l	#0,d1			Mise à 0 du pas de scrolling vertical
	move.l	PointeurCopper1,a1	Pointeur du copper en A1
	move.l	PointeurImage1,a0	Pointeur de l' image en A0

Position:
	move.l	VPOSR(a5),d2		Position (Bit V76543210 H76543210)
	and.l	#$0001FF00,d2		Filtre des seuls bits horizontaux
	cmp.l	#$00001000,d2		Est-ce la ligne souhaitée ?
	bne.s	Position		Non ! Alors je me magne.

	addq.b	#PasVertical,d0		Augmentation du scrolling
	cmp.w	#$80,d0			Jusqu' à 4 fois 32
	bne.s	Vertical		Vertical
	moveq.l	#0,d0			Remise à 0 du scrolling

Vertical:
	move.l	d0,d2			Recopie du compteur de scrolling
	lsr.w	#2,d2			Division par 4 (ligne par ligne)
	mulu	#13*4,d2		Octets par ligne * position scrolling
	add.l	a0,d2			Plus l' adresse du plan
	add.l	#LongueurPlan1,d2	Plus la taille du plan
	move.w	d2,14(a1)		Haut mot du pointeur après BPL2PTL
	swap	d2			Echange du haut et du bas du mot			
	move.w	d2,10(a1)		Bas mot du pointeur après BPL2PTL

	addq.b	#PasHorizontal,d1	Augmentation du scrolling
	cmp.w	#$80,d1			Jusqu' à 4 fois 32
	bne.s	Horizontal		Horizontal
	moveq.l	#0,d1			Remise à 0 du scrolling
Horizontal:
	move.l	d1,d2			Recopie du compteur de scrolling
	lsr.w	#2,d2			Division par 4 (ligne par ligne)
	move.l	d2,d3			Sauvetage de D2
	and.w	#$FFF0,d2		Filtre des 4 bits inférieurs
	sub.w	d2,d3			Les 4 bits inférieurs sont dans D3			
	move.w	d4,BPLCON1		Valeur de scrolling précédante
	move.w	d3,d4			Nouvelle valeur de scrolling en D4
	lsr.w	#3,d2			Multiplication par 8
	add.l	a0,d2			Plus Adresse du champ de jeu 1
	move.w	d2,6(a1)		Haut mot du pointeur après BPL1PTL
	swap	d2			Echange du haut et du bas du mot
	move.w	d2,2(a1)		Bas mot du pointeur après BPL1PTL

	btst	#6,CIAAPRA		Qui qu' a clicqué ?
	bne.s	Position

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Remise en place de l' ancienne liste du copper	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	moveq	#0,d0			Toutes les versions
	lea	Graphics_name(pc),a1	Base en A1
	jsr	OpenLibrary(a6)		Ouverture
	movea.l	d0,a4			Pointeur en A4
	move.l	StartList(a4),COP1LC(a5)	Début de la liste
	clr.w	COPJMP1(a5)		Saut de la première liste annulée
	move.w	#$83e0,DMACON(a5)	Réinitialisation du canal DMA
	jsr	Permit(a6)		Multitâche

*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
*	Libération de la mémoire prise	*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*
	moveq	#LongueurCopper1,d0	Longueur à libérer
	Libère	Copper1			Je rends la mémoire prise

Fin_Plan:
	move.l	#LongueurImage1,d0	Longueur à libérer
	Libère	Image1			Je rends la mémoire prise

Fin_Retour:
	moveq	#0,d0
	rts

*************************
*	VARIABLES	*
*************************
PointeurCopper1: dc.l 0
PointeurImage1:	 dc.l 0
Test:		 dc.l 0
Graphics_name:	 dc.b "graphics.library",0

   END	Fin du programme

