;Programmé par Yragael pour Stash of Code (http://www.stashofcode.fr) en 2017.

;Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 France.

;Une Copper line (avant la ligne $FF !)

;---------- Directives ----------

	SECTION yragael,CODE_C

;---------- Constantes ----------

;Registres

INTENA=$09A
INTENAR=$01C
INTREQ=$09C
INTREQR=$01E
DMACON=$096
DMACONR=$002
COLOR00=$180
COP1LCH=$080
COP1LCL=$082
COPJMP1=$088
VPOSR=$004

;Programme

COPPERLIST=1000		;Arbitraire, on se dit que tout tiendra
LINE=100			;<= 255

;---------- Initialisations ----------

;Empiler les registres

	movem.l d0-d7/a0-a6,-(sp)
	lea $dff000,a5

;Allouer de la mémoire en CHIP mise à 0 pour la Copper list

	move.l #COPPERLIST,d0
	move.l #$10002,d1
	movea.l $4,a6
	jsr -198(a6)
	move.l d0,copperList

;Couper le système

	movea.l $4,a6
	jsr -132(a6)

;Couper le matériel comme un gros sale

	move.w INTENAR(a5),intena
	move.w #$7FFF,INTENA(a5)
	move.w INTREQR(a5),intreq
	move.w #$7FFF,INTREQ(a5)
	move.w DMACONR(a5),dmacon
	move.w #$07FF,DMACON(a5)

;---------- Copper list ----------

	movea.l copperList,a0

;Attendre le début visible ($3E) de la ligne (<= 255)

	move.w #(LINE<<8)!$3E!$0001,(a0)+
	move.w #$8000!($7F<<8)!$FE,(a0)+

;Enchaîner 40 modifications de la couleur de fond

	lea _gradientStart,a1
	moveq #40-1,d0
_copperListColors:
	move.w #COLOR00,(a0)+
	move.w (a1)+,(a0)+
	cmpi.l #_gradientEnd,a1
	bne _copperListColorsNoLoop
	lea _gradientStart,a1
_copperListColorsNoLoop:
	dbf d0,_copperListColors

;Passer la couleur de fond à noir

	move.w #COLOR00,(a0)+
	move.w #$0000,(a0)+

;Fin

	move.l #$FFFFFFFE,(a0)

;---------- Programme principal ----------

;Rétablir les DMA

	move.w #$8280,DMACON(a5)	;DMAEN=1, COPEN=1

;Activer la Copper list

	move.l copperList,COP1LCH(a5)
	clr.w COPJMP1(a5)

;Boucle principale

	lea _gradientStart,a0
_loop:

	;Attendre un blanc vertical

_waitVERTB0:
	move.l VPOSR(a5),d0
	lsr.l #8,d0
	and.w #$01FF,d0
	cmp.w #$0000,d0
	blt _waitVERTB0
_waitVERTB1:
	move.l VPOSR(a5),d0
	lsr.l #8,d0
	and.w #$01FF,d0
	cmp.w #$0001,d0
	bne _waitVERTB1

	;Modifier les 40 MOVE

	movea.l a0,a1
	movea.l copperList,a2
	lea 4+2(a2),a2
	moveq #40-1,d0
_setColors:
	move.w (a1)+,(a2)
	lea 4(a2),a2
	cmpi.l #_gradientEnd,a1
	bne _setColorsNoLoop
	lea _gradientStart,a1
_setColorsNoLoop:
	dbf d0,_setColors

	;Cycler les couleurs

	lea 2(a0),a0
	cmpi.l #_gradientEnd,a0
	bne _cycleColorsNoLoop
	lea _gradientStart,a0
_cycleColorsNoLoop:

	btst #6,$BFE001
	bne _loop

;---------- Finalisations ----------

;Couper les interruptions hardware et les DMA

	move.w #$7FFF,INTENA(a5)
	move.w #$7FFF,INTREQ(a5)
	move.w #$07FF,DMACON(a5)

;Rétablir les interruptions hardware et les DMA

	move.w dmacon,d0
	bset #15,d0
	move.w d0,DMACON(a5)
	move.w intreq,d0
	bset #15,d0
	move.w d0,INTREQ(a5)
	move.w intena,d0
	bset #15,d0
	move.w d0,INTENA(a5)

;Rétablir la Copper list

	lea graphicslibrary,a1
	movea.l $4,a6
	jsr -408(a6)
	move.l d0,a1
	move.l 38(a1),COP1LCH(a5)
	clr.w COPJMP1(a5)
	jsr -414(a6)

;Libérer la mémoire

	movea.l copperList,a1
	move.l #COPPERLIST,d0
	movea.l $4,a6
	jsr -210(a6)

;Rétablir le système

	movea.l $4,a6
	jsr -138(a6)

;Depiler les registres

	movem.l (sp)+,d0-d7/a0-a6
	rts

;---------- Données ----------

dmacon:			DC.W 0
intena:			DC.W 0
intreq:			DC.W 0
copperList:		DC.L 0
graphicslibrary:	DC.B "graphics.library",0
	even
_gradientStart:
				DC.W $0074, $0163, $0252, $0341, $0430, $0521, $0612, $0703, $0814, $0925, $0A36, $0B47, $0C58, $0D69, $0E7A, $0F8B, $0E9C, $0DAD, $0CBE, $0BCF, $0ADE, $09ED, $08FC, $07EB, $06DA, $05C9, $04B8, $03A7, $0296, $0185
_gradientEnd: