Obligement - L'Amiga au maximum

Vendredi 24 mai 2019 - 05:49  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles en d'autres langues


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Programmation : Assembleur - Sinus-scroll
(Article écrit par Jérôme Étienne et extrait d'Amiga News Tech - décembre 1991)


Le principe de ce "scroll" (défilement) est assez simple : il est d'abord créé dans une zone qui ne sera jamais affichée (hidden_screen) puis recopié tranche par tranche grâce au Blitter. Mais pour faire ce genre de travail, il faut beaucoup de temps et utiliser deux écrans en alternance (double tampon mémoire).

Durant la VBL, on effectue les opérations suivantes :
  • Permutation des écrans.
  • Effacement de l'écran non affiché.
  • On rentre les lettres s'il le faut dans la zone "hidden_screen" et on donne un coup de Blitter pour faire bouger de droite à gauche.
  • On recopie par tranche de deux colonnes la zone "hidden_screen" dans l'écran caché. Le Blitter ne permettant des transferts que d'un mot minimum, on est obligés de ruser et de faire un OR avec la source et la destination, car sinon on effacerait les autres tranches. Il ne faut donc pas s'étonner de voir que bltBpt et bltDpt pointent sur la même adresse (A or B -> D).
Remarques
  • L'image à insérer au label lettres doit être de 320 pixels (40 octets) sur 256 lignes au format RAW (surtout pas IFF !) et un seul bitplan. Chaque lettre fait 32 pixels de large sur 32 de haut.
  • L'impression d'une onde qui passe est donnée par le déplacement d'un pointeur sur la table des déplacements.
Il est possible d'optimiser le programme (code relatif au PC, initialisation du Blitter avant d'entrer dans les boucles...) mais pas des masses, car le Blitter prend un sacré temps pour recopier tous les blocs d'image, même s'il tourne à plein régime (le bit 10 de dmacon est mis).

Listing 1 : MakeSinus.bas

c=0
OPEN "o",#1,"sinus.s"
FOR a=0 TO 2*3.14159 STEP .01
b=INT(SIN(a)*100+105)
PSET(c,b)
c=c+1
b=b*40
IF c=1 THEN
a$=CHR$(9)+"dc.w"+STR$(b)
END IF
IF c>1 THEN
   IF LEN(a$)<60 THEN
   a$=a$+","+STR$(b)
  ELSE
   PRINT #1,a$
   a$=CHR$(9)+"dc.w"+STR$(b)
   END IF
END IF
NEXT a
PRINT #1,a$
CLOSE #1

Listing 2 : Registers.i

dmacon=$96
dmaconr=$02
intreq=$9c
intreqr=$1e
intena=$9a
intenar=$1c
ciaapra=$bfe001
color00=$180
cop1lc=$80
copjmp1=$88
startlist=38
diwstrt=$8e
ddfstrt=$92
bplcon0=$100
bplcon1=$102
bplcon2=$104
bpl1mod=$108
bpl2mod=$10a
bpl1ptH=$e0
bpl1ptL=$e2
forbid=-132
permit=-138
openlibrary=-552
closelibrary=-414
execbase=4
bltapt=$50
bltbpt=$4c
bltdpt=$54
bltamod=$64
bltbmod=$62
bltdmod=$66
bltafwm=$44
bltalwm=$46
bltcon0=$40
bltcon1=$42
bltsize=$58
bltadat=$74

Listing 3 : Save_All.s

save_all
	lea $dff000,a5
	move.b #%10000111,$bfd100	arrete drives
	move.l execbase,a6		base d'exec
	jsr forbid(a6)			enleve multitache
	move.l $6c,save_vecteur_irq	vecteur irq
	move.w intenar(a5),save_intena	intena
	or.w #$8100,save_intena		met bit 15
	move.w dmaconr(a5),save_dmacon	dmacon
	or.w #$c000,save_dmacon		met bit 15
	rts				fin
restore_all
	lea $dff000,a5			adresse base custom chip
	move.l save_vecteur_irq,$6c	remet vecteur irq
	move.w #$7fff,intena(a5)	vire intena
	move.w save_intena,intena(a5)	remet save_intena
	move.w #$7fff,dmacon(a5)	vire dmacon
	move.w save_dmacon,dmacon(a5)	remet damcon_save
	move.l execbase,a6		base d'exec
	lea name_glib,a1		pointeur sur gfx lib
	moveq #0,d0			vide d0
	jsr openlibrary(a6)		ouvre gfx lib
	move.l d0,a0			recupere addresse
	move.l startlist(a0),cop1lc(a5)	met ancienne adresse coplist
	clr.w copjmp1(a5)		valide coplist
	move.l d0,a1			adresse gfx lib dans a1
	jsr closelibrary(a6)		ferme gfx
	jsr permit(a6)
	rts
save_intena		dc.w 0
save_dmacon		dc.w 0
save_vecteur_irq	dc.l 0
name_glib		dc.b "graphics.library",0
	even

Listing 4 : SinusScroll.s

	include Registers.i
	
	bsr save_all
	
	lea $dff000,a6			inits
	move.w #$7fff,d0		ecran
	move.w d0,dmacon(a6)		et vbl
	move.w d0,intena(a6)
	move.l #$003800d0,ddfstrt(a6)
	move.l #$2c8129c1,diwstrt(a6)
	move.w #0,bpl1mod(a6)
	move.w #0,bpl2mod(a6)
	move.w #$1200,bplcon0(a6)
	move.w #0,bplcon1(a6)
	move.w #0,bplcon2(a6)
	move.l #$00000fff,color00(a6)
	move.l #vbl,$6c
	move.l #coplist,cop1lc(a6)
	clr.w copjmp1(a6)
	move.w #$87c0,dmacon(a6)
	move.w #$c020,intena(a6)

mickey
	btst #6,ciaapra
	bne mickey
	bsr restore_all	
	moveq.l #0,d0
	rts

	include Save_All.s
vbl
	movem.l d0-d7/a0-a6,-(sp)
	lea $dff000,a6
	btst #5,intreqr+1(a6)		test la provenance
	beq pas_vbl			de l'interrupt niveau 3
	bsr flip_screen			permute les ecrans
	bsr clear_hidden_screen		efface l'ecran caché
	bsr do_scroll			deplace le scroll caché
	bsr put_scroll			copie scroll caché dans ecran caché
	move.w #$20,intreq(a6)		fin vbl
pas_vbl
	movem.l (sp)+,d0-d7/a0-a6
	rte

next_screen
	dc.l ecran1			adresse de l'ecran caché
	
wait_blit
	btst #14,dmaconr(a6)
loop_blit
	btst #14,dmaconr(a6)
	bne loop_blit
	rts

flip_screen
	move.l next_screen,d0		echange les ecrans
	move.l #ecran1,d1		pour faire du double-buffering
	cmp.l d0,d1
	beq put_ecran1
	
	move.l #ecran2,bpl1ptH(a6)
	move.l #ecran1,next_screen
	rts
	
put_ecran1
	move.l #ecran1,bpl1ptH(a6)
	move.l #ecran2,next_screen
	rts

clear_hidden_screen
	bsr wait_blit			afface l'ecran caché
	clr.w bltadat(a6)
	clr.w bltamod(a6)
	move.w #$ffff,bltafwm(a6)
	move.w #$ffff,bltalwm(a6)
	move.w #$01f0,bltcon0(a6)
	move.w #$0,bltcon1(a6)
	move.w #$0,bltdmod(a6)
	move.l next_screen,bltdpt(a6)
	move.w #256*64+20,bltsize(a6)
	rts

do_scroll
	move.l pointeur_text,a0		fait entrer les letttres
	move.w letter_count,d0		dans l'écran caché
	beq new_letter
	sub.w #1,letter_count
	bra scroll
new_letter
	move.w #7,letter_count
	clr.l d0
	move.b (a0)+,d0
	bne continue
	lea text,a0
	move.b (a0)+,d0
continue
	cmp.b #32,d0			test pour le character
	bne continue2			espace chr=32=$20
	move.b #"Z"+1,d0
continue2
	sub.b #"A",d0			A est la base de la table
	lsl.l #1,d0			table composée de mot => *2
	lea table_pos,a1
	bsr wait_blit
	move.l #0,a2			/ calcul adresse lettre
	move.w 0(a1,d0.l),a2		/ dans image
	add.l #lettres,a2		/
	move.l a2,bltapt(a6)
	move.w #36,bltamod(a6)
	move.l #hidden_screen+42,bltdpt(a6)
	move.w #44,bltdmod(a6)
	move.w #$09f0,bltcon0(a6)
	move.w #$0,bltcon1(a6)
	move.w #32*64+2,bltsize(a6)
	
scroll
	bsr wait_blit				scroll tout le texte
	move.l #hidden_screen+2,bltapt(a6)	caché
	move.w #2,bltamod(a6)
	move.l #hidden_screen,bltdpt(a6)
	move.w #2,bltdmod(a6)
	move.w #$c9f0,bltcon0(a6)
	move.w #$0,bltcon1(a6)
	move.w #32*64+23,bltsize(a6)
	move.l a0,pointeur_text
	rts

put_scroll
	move.l #159,d0				met scroll dans
	move.l pointeur_onde,a1			écran caché
	move.l #hidden_screen+2,a2
	move.l next_screen,a0
	lea table_mask,a4
loop_cut
	move.l a0,a3			et on le met 2 colones par
	clr.l d1			2 colones
	move.w (a1)+,d1

	bne continue_loop
	lea table_sinus,a1
	move.w (a1)+,d1
continue_loop
	add.l d1,a3			a3=adresse d'arrivée
*					a2=adresse source
	bsr wait_blit
	move.l a2,bltapt(a6)
	move.w #46,bltamod(a6)
	move.l a3,bltbpt(a6)
	move.w #38,bltbmod(a6)
	move.l a3,bltdpt(a6)
	move.w #38,bltdmod(a6)
	move.w (a4),bltafwm(a6)
	move.w (a4)+,bltalwm(a6)
	move.w #$0dfc,bltcon0(a6)	on fait un or pour ne pas
	move.w #$0,bltcon1(a6)		effacer les autres tranches
	move.w #32*64+1,bltsize(a6)	transfer !
	cmp.w #0,(a4)			test les masques
	beq change_bloc			si =0 alors on reprend au debut
	bra next_bloc			sinon on continue
change_bloc
	lea table_mask,a4
	add.l #2,a0
	add.l #2,a2
next_bloc
	dbf d0,loop_cut

	move.l pointeur_onde,a0		fait avancer le pointeur
	add.l #10,a0			de l'onde => donne impression
	move.w (a0),d0			qu'une onde passe
	bne fin_sinus
	move.l #table_sinus,pointeur_onde
	rts
fin_sinus
	move.l a0,pointeur_onde
	rts

pointeur_text
	dc.l text
letter_count
	dc.w 0
text
	dc.b "SINUS SCROLL POUR ANT      ",0
	even
table_pos
	dc.w 0,4,8,12,16,20,24,28,32,36
	dc.w 1280,1284,1288,1292,1296,1300,1304,1308,1312,1316
	dc.w 2560,2564,2568,2572,2576,2580,2584
pointeur_onde
	dc.l table_sinus
table_sinus
	include Sinus.s
	dcb.l 3,0
table_mask
	dc.w $c000,$3000,$c00,$300,$c0,$30,$c,$3
	dc.w 0
	
	section ecran,data_c
ecran1
	dcb.b 10240,$0			ecran de 40*256
ecran2
	dcb.b 10240,$0			ecran de 40*256
hidden_screen
	dcb.b 1536,0			hidden_screen de 48*32
lettres
	incbin Font
coplist
	dc.w color00,0
	dc.w $640f,$fffe
	dc.w color00,$2
	dc.w $8c0f,$fffe
	dc.w color00,$5
	dc.w $b40f,$fffe
	dc.w color00,$9
	dc.w $dc0f,$fffe
	dc.w color00,$d
	dc.w $ff0f,$fffe
	dc.w color00,$f
	dc.l $fffffffe


[Retour en haut] / [Retour aux articles]