home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ANews 3
/
AnewsCD3.iso
/
atari
/
ARTICLES
/
ASM
/
PLOT.S
< prev
Wrap
Text File
|
1999-09-25
|
8KB
|
249 lines
* Routine d'affichage de points en ST Basse
*
* Voici le premier exemple du deuxime numro de cette initiation
* l'ASM. Je n'ai pas test cette routine mais elle doit pouvoir
* faire plus de 800 points par VBL.
*
* Je vais commencer par vous expliquer comment est structure la
* mmoire vido en ST Basse :
* Atari a opt pour un systme dit "planaire" qui peut avoir ses
* avantages mais qui est une gne la plupart du temps comme vous
* vous en appercevrez par la suite.
* Pour coder les 16 valeurs correspondant chaque couleur il
* faut 4 bits (car 2^4=16) mais les 4 bits decrivant la couleur ne
* se suivent pas ! En fait l'ecran est cod par goupe de 16 pixels
* soit 16*4=64 bits. Le premier plan (qui correspond au premier bit
* de la couleur de chacun des pixels) est stock sous forme de 16
* bits se suivant (donc un word) ensuite un second qui definit le
* deuxime plan, un troisime et enfin le quatrime. Donc pour
* dfinir la couleur du 6me pixel du groupe de 16 il faut modifier
* le 6me bit du 1er word (exceptionnelement comptez les bits de
* gauche droite pour cet exemple), puis le 6me bit du 2me word,
* 6me du 3me word et enfin 6me du 4me word. Si on compte bit
* par bit on a modifi le 6me, le 22me, le 38me et le 54 me !
*
* Ici on veut afficher un pixel donc il faut copier un word
* dont tous les bits valent 0 sauf un vers le bon groupe de 16
* pixels. Nous avons donc besion de determiner 2 choses partir
* des coordones du point : tout d'abord l'adresse en memoire ecran
* correspondant au bon groupe de 16 pix et le nø du bit qu'il faudra
* mettre 1. On pourrait utiliser les 16 couleurs et donc copier le
* word sur le bon plan chaque fois mais on ne le fera pas cette
* fois ci (bien qu'en fait ca ne complique pas vraiment le programme).
* on va donc toujours utiliser la couleur un et donc ne modifier que
* le plan 1. Lorsqu'on a le nø du bit mettre 1 on pourrait
* faire un decalage mais il y a plus rapide : il suffit de stocker
* les 16 word possibles et en fonction de la valeur obtenue aller
* directement au bon. C'est ce que nous ferons : les 16 word possibles
* sont la fin de ce programme (label pix).
*
section text
bsr init ; ici je vais une sous-routine qui
; sauve quelques trucs, change de reslution
; etc... nous verons ca plus tard. A la fin
; de cette routine on a l'adr de l'ecran
; en a1
move.l a1,a0 ; on copie a1 dans a0
move.l #7999,d0 ; On donne d0 la valeur 7999 car on va
eff_ecran: ; executer une boucle 8000 fois : on efface
clr.l (a0)+ ; les longs situs l'adresse a1 et on
; incrmente pour chaque fois passer au
; suivant (sinon on effacerait 8000 fois le
; 1er long de l'ecran toujours au meme endroit.
dbf d0,eff_ecran ; on fait un dbf vers le label eff_ecran et on
; decrmente d0 chaque fois, au bout de 8000
; fois il vaudra -1 donc on passera la suite.
; l'instruction clr dont je n'avais pas encore parl ne fait que mettre tous
; les bits du registre (ou du long word ou octet en memoire) 0.
move.w #195,d0 ; abscisse du point
move.w #57,d1 ; ordonne du point
; vous pouvez les changer pour essayer mais
; n'oubliez pas que l'abscisse doit etre comprise
; entre 0 et 319 et l'ordonne entre 0 et 199.
move.w d0,d2 ; on fait une copie de l'abscisse dans d2
and.w #%1111111111110000,d2 ;et on fais ce and qui ne modifiera que les
; 4 derniers bits en les mettant 0. L'interet est de savoir
; sur quel groupe de 16 pixels on va devoir afficher le sprite
; car en metteant ces 4 bits 0 on transforme d0 en son multiple
; de 16 le plus proche par defaut. En effet si on a
; %00110101=53 si on fait un and %11110000 on obtient
; %00110000=48 (sui est bien le multiple de 16 le plus proche
; par defaut
sub.w d2,d0 ; ensuite on saustrait le resultat obtenu donc on obtient en d0
; la valeur qui manque d2 (cette valeur vaut donc de 0 15)
lsr.w #1,d2 ; on divise par 2 car chaque groupe de 16 pixels fait 8 octets
; donc pour aller au pixel 48 donc le 3me groupe il faut ajouter
; 3*8=24 l'adr ecran et 48/2 = 24 ! Magique !
add.w d2,a1 ; donc on ajoute d2 a1
add.w d0,d0 ; on multiplie d0 par 2 car il va servir pointer sur le bon
; word copier et comme un word fait 2 octets un decalage de
; 3 bits corrrespondra a 6 octets apres le bebut de la table
; (label pix).
move.w d1,d2 ; on copie d1 en d2, l'ancienne valeur de d2 est perdue mais
; on n'en aura plus besion.
add.w d2,d2 ; ici on va faire une multiplication par 160 avec des addition !
; la on a ajout d2 lui meme donc on l'a multipli par 2
add.w d2,d2 ; on le refait don ca fait *4 depuis le bebut
add.w d2,d1 ; on avait copi d1 dans d2 donc on a d2=4*d1, on ajoute donc
; 4*d1 d1 donc maintenant d1 vaut 5 fois sa valeur initiale
lsl.w #5,d1 ; on decale de 5 bits ce qui correspond une multiplicaition
; par 2^5=32. Et 5*32 = 160 ! On a russi !
; "Mais pourquoi il veut absoluement multiplier d1 par 160
; cet oiseau ?" Ben en fait une ligne fait 320 pixels, soit
; 20 groupes de 16 pixels donc 20*8=160 octets, voila pourquoi !
add.w d1,a1 ; on ajoute donc l'abscice * 160 a1 donc a1 pointe maintenant
; sur le bon word !
lea.l pix,a0 ; lea est une instruction qui copie l'adresse d'un
; label. J'aurai pu aussi faire move.l #pix,a0
move.w (a0,d0.w),d0
; on copie le word l'adresse a0+d0 dans d0
or.w d0,(a1) ; et on affiche avec un or pour ne pas effacer les eventuels
; autres points quand on modifiera la routine pour qu'elle en
; affiche plusieurs.
wspace: cmp.b #$39,$fffffc02.w ; la on attends que la touhe espace
bne.s wspace ; soit appuye (j'en parlerai plus tard
bsr end ; la je branche sur une sous routine qui restaure
; la rez, etc.
move.w #0,-(sp) ; et on fait un GEMDOS 0 pour
trap #1 ; induquer la fin du programme (j'en parlerai plus tard)
end: move.l #mouse_on,-(sp)
move.w #0,-(sp)
move.w #25,-(sp)
trap #14
addq.l #8,sp
move.w #$30,-(sp)
trap #1
adda #2,sp
cmp.w #$1900,d0
bgt.s r_f
move.w rez,-(sp)
move.l physk,-(sp)
move.l logk,-(sp)
move.w #5,-(sp)
trap #14
lea.l 12(sp),sp
bra.s user
r_f: move.w rez,-(sp)
move.w #3,-(sp)
move.l physk,-(sp)
move.l logk,-(sp)
move.w #5,-(sp)
trap #14
lea.l 14(sp),sp
user: move.l super,-(sp)
move #$20,-(sp)
trap #1
addq.l #6,sp
rts
init: pea 0.w
move #$20,-(sp)
trap #1
addq.l #6,sp
move.l d0,super
move.w #2,-(sp)
trap #14
addq.l #2,sp
move.l d0,physk
move.w #3,-(sp)
trap #14
addq.l #2,sp
move.l d0,logk
move.w #$30,-(sp)
trap #1
adda #2,sp
cmp.w #$1900,d0
bgt.s f
move.w #4,-(sp) ;st rez
trap #14
addq.l #2,sp
bra.s s_rez
f: move.w #-1,-(sp) ;falc rez
move.w #88,-(sp)
trap #14
addq.l #4,sp
s_rez: move.w d0,rez
move.l #mouse_off,-(sp)
move.w #0,-(sp)
move.w #25,-(sp)
trap #14
addq.l #8,sp
move.w #0,-(sp)
move.l #-1,-(sp)
move.l #-1,-(sp)
move.w #5,-(sp)
trap #14
lea.l 12(sp),sp
move.w #2,-(sp)
trap #14
addq.l #2,sp
move.l d0,a1
rts
section data
pix:
dc.w %1000000000000000
dc.w %0100000000000000
dc.w %0010000000000000
dc.w %0001000000000000
dc.w %0000100000000000
dc.w %0000010000000000
dc.w %0000001000000000
dc.w %0000000100000000
dc.w %0000000010000000
dc.w %0000000001000000
dc.w %0000000000100000
dc.w %0000000000010000
dc.w %0000000000001000
dc.w %0000000000000100
dc.w %0000000000000010
dc.w %0000000000000001
mouse_off:
dc.b 18,0
mouse_on:
dc.b 8,0
section bss
super: ds.l 1
physk: ds.l 1
logk: ds.l 1
rez: ds.w 1
even