Suivez-nous sur X

|
|
|
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,
ALL
|
|
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
|
|
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
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Assembleur - Sinus-scroll
(Article écrit par Pierre Chalamet 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 plan de bits. 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
|
|