1

Hello,

Je parcours depuis un moment déjà ce forum et je ne souhaitais pas intervenir avant d'avoir appris l'asm 68k. Histoire de ne pas raconter trop de bétises smile
J'ai profité des vacances pour apprendre l'asm, m'acheter un 1040 STE et installer de SatanDisk.

Pour ceux que ça intéresse j'ai suivi la méthode du Lapin Féroce et ça passe tout seul les bases du langage sont vite maitrisées. CA aurait du être un bouquin tellement c'est bien expliqué !

Il me manque encore qques subtilités que n'ai pas trouvées et si vous avez un peu de temps j'aimerais vous les soumettre :

- Tout d'abord l'écran : j'arrive à tracer des lignes, polygones, pixels assez facilement avec la Ligne A mais j'ai lu dans un ancien post que ce n’était pas recommandé et qu'il fallait mieux ecrire directement en mémoire.
=> pour un écran en basse résolution, comment fait-on ? Je sans récupérer l'adresse de l'ecran par contre je ne sais pas comment il est organisé..

- Ensuite le déroulement d'un programme, jusqu'a présent sur d'autre machines plus récentes , je faisait :

boucle_sans_fin
{
traitement;
traitement;
...
wait_vbl();
}
Ca marcherait sur atari ? ou alors il vaut mieux travailler sur deux écrans et faire des flips ?

- Et pour finir en ASM pur : Comment gère-t-on les nombre à virgule ? enfin si ca existe smile. L'idée serait de tester un affichage en perspective du genre en C :

#define PI 3.14159265359
#define FUITE 512

float q;
float x,y;
q = 1 - ze/FUITE ;
x = xe/q ;
y = ye/q ;


Voila pour commencer ^^,
CeL.

2

Salut a toi et bienvenu ici smile

Meme si tu pense que c'est une bétise, faut pas avoir peur ou hésité on a tous été dans ton cas de figure, il faut bien commencé quelque part.

Bon je reprends ton poste a l'envers, sur un ST pas de gestion de chiffre a virgule car il y a que le 68000 et celui ci ne dispose pas virgule.

Il vaut mieux travailler sur deux écrans, car a cause de la vitesse de la machine tu va te retrouvé avec des scintillements et des effets visuellement pas terrible.

Pour répondre a ta premiere question, il me faut en posé une, c'est pour dev quoi ? Si c'est pour un jeu / démo tapé dans la mémoire vidéo est le seul moyen pour arrivé a une vitesse décente, si c'est pour un utilitaire / programme propre tu as deux parties de la machine (Vdi / Aes) qui sont des librairies pour presque tout faire (Gestion des fenetres, tracés graphiques etc....)


GT smile
avatar
Accrochez vous ca va être Cerebral !!

3

Merci pour ta réponse,

> Pour répondre a ta premiere question, il me faut en posé une, c'est pour dev quoi ?

Pour mon niveau, j’espère déjà faire qque chose de light genre un cube en perspective qui tourne, donc plutôt jeu/demo.
Une fois bien familiarisé avec les différentes tech, j'espere me lancer sur un petit jeu.

Enfin déjà il faudrait que je comprenne comment afficher un pixel de couleur 15 en x=10,y=12 par ex.

J'imagine que ça doit être qque chose du genre : Adresse_ecran +???*(320*y+x).
A partir du début de l'adresse de l'ecran est-ce que chaque long correspond à un pixel + ses attributs (genre sa couleur)... ou pas du tout...

J'ai du mal à trouver une doc qui parle précisément de cette partie.

CeL.

4

J'imagine que ça doit être qque chose du genre : Adresse_ecran +???*(320*y+x). A partir du début de l'adresse de l'ecran est-ce que chaque long correspond à un pixel + ses attributs (genre sa couleur)... ou pas du tout...

Réponse B. Pas du tout...
En fait l'écran ST est organisé par plans, il doit y avoir pas mal de sites qui décrivent ça très bien.
Ici, tu verras une explication des différences entre mode planar et chunky (ce que tu pensais) :
http://alive.atari.org/alive8/c2p.php


Et tu auras d'autres infos ici : topics/128442-programmation-asm-sur-falcon (ça parle Falcon, mais le post ./15 devrait répondre à ta question)
avatar
De nouveaux jeux pour vos vieilles consoles ? En 2024 ?
https://yastuna-games.com

5

Comme l'a dit Fadest, l'organisation de la mémoire ecran d'un ST est 'spéciale'. En gros tu as 4 bitplans (16 couleurs affichables, ce qui te fait un codage sur 4 bits donc 4 bitplans grin ) mais vu que chez Atari on est des marrants on entrelace ces plans O_o

En gros le premier mot (word) de ton ecran, representes tes 16 premiers pixels mais juste leur bit 0, un word plus loin leur bit 1, un word encore plus loin le 3, et après le 4 et après bien sur on recommence les 16 pixels suivants et leur bit 0.

Faut que je fouilles dans mes archives, je dois bien encore avoir une init avec un affichage de points qui doi trainé. Je sais pas encore quand mais je vais taché de te retrouvé cela.


GT Entrelacé O_o

avatar
Accrochez vous ca va être Cerebral !!

6

ah oui quand même ! j’imaginais pas du tout une organisation comme celle ci.
J'ai à peu prêt compris le truc, me faut un peu de temps pour digérer ça et écrire par moi même une fonction putpixel.
Je vais déjà me concentrer là dessus avant d'aller plus loin.

7

xCeLfr (./6) :
ah oui quand même ! j’imaginais pas du tout une organisation comme celle ci.
J'ai à peu prêt compris le truc, me faut un peu de temps pour digérer ça et écrire par moi même une fonction putpixel.


Tu dev sur Atari, c'est signé pour en bavé wink

L'orga de la mémoire ecran est le pire truc, une fois que tu connais bien cela, après le reste c'est presque du 'pipeau'.


GT smile
avatar
Accrochez vous ca va être Cerebral !!

8

@xCeLfr : j'en suis au même point que toi, je débute et je taquine un peu les pixels. Les bitplans c'est de la torture mentale ce truc, je pense qu'avec l'expérience ça va aller tout seul, comme le suggère GT smile
Les cours du Féroce Lapin c'est pas mal, de mon côté je suis parti sur ceux du site ST Graveyard (en anglais). L'un des tutos (le 5ème) parle de la structure de la mémoire écran.
Hélas, ce site est fermé mais j'ai toutes les docs (PDF, sources...) sur mon PC, donc si l'anglais ne te fais pas peur je peux te fournir tout ça. Ou mieux, le mettre sur un site web.

edit : les archives de ST Graveyard sont sur Atari-Forum : http://www.atari-forum.com/viewtopic.php?f=68&t=4330
avatar
Site perso : http://strider.untergrund.net/
Atari STF / STe / Mega STE / Falcon030 / Falcon CT60

9

ohh ! excellente doc, ça a l'air très complet ! je vais étudier ça, merci pour le lien !

10

GT Turbo (./7) :
Tu dev sur Atari, c'est signé pour en bavé wink.gif
Peuh. Coder en assembleur sur ST, ça se fait les doigts dans le nez comparé à la même chose sur 286+EGA/VGA hehe

Pour le reste, (re)lire de vieux bouquins ne peut pas faire de mal : http://letotd.free.fr/livres.htm
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

11

GT Turbo (./7) :
Tu dev sur Atari, c'est signé pour en bavé wink.gif
Peuh. Coder en assembleur sur ST, ça se fait les doigts dans le nez comparé à la même chose sur 286+EGA/VGA hehe
[/cite]

Je parlais de vrais machines smile


GT octopus
avatar
Accrochez vous ca va être Cerebral !!

12

tusors
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

13

ahh je commence à aimer ça smile
je crois que j'ai choppé le truc pour l’écran.
Bon j'imagine que le code qui suit est moche et ultra pas optimisé mais bon je débute et j'ai essayé de ne pas piocher du code à gauche et à droite pour comprendre ce que je fais.
Maintenant j'aimerais comprendre les différentes technique d'optimisation, j'ai déjà lu qu'il fallait remplacer les div et mul par des opérations binaires ?
INCLUDE "c:\dev\start.s" INCLUDE "c:\dev\cel_lib.s" ; sauve la resolution move.w #4,-(sp) trap #14 addq.l #2,sp move.w d0,old_res ; passe en basse resolution SET_RES #0 ; on recupere l'adresse de l'ecran move.w #2,-(sp) getphysbase trap #14 addq.l #2,SP movea.l d0,a0 ; a0 pointe l'ecran ; on efface l'ecran move.l d0,a1 move.l #7999,d1 ; taille de l'ecran clear move.l #0,(a1)+ dbra d1,clear START move.l #160,d0 ; d0 = X move.l #100,d1 ; d1 = Y move.b #%1000,d2 ; d2 = couleur = 8(#%1000=#8=bleu) ; Xeme colonne de la Yeme ligne ; 16px = 4words, 1ligne = 320px ; => 1ligne = 320/16px * 4words = 80words = 160bytes ; on se place a Y*160 debug mulu.w #160,d1 adda.w d1,a0 ; ecran point le debut de la Yeme ligne divu.w #16,d0 ; x/16 => d0(reste,quotient) move.w d0,d1 ; copie quotient dans d1 mulu.w #8,d1 ; quotient*8 car on se deplace en 4words(8bytes) adda.w d1,a0 ; ecran pointe sur 160*Y+(quotient*8) swap.w d0 ; on echange le reste avec le quotient lea tab,a2 ; adresse du tableau dans a2 mulu.w #2,d0 ; *2 car compteur en byte move.w 0(a2,d0.w),d3 ; mask dans d3 bit0 btst #0,d2 ; couleur bit0 beq bit1 eor d3,0(a0) bit1 btst #1,d2 ; couleur bit1 beq bit2 eor d3,2(a0) bit2 btst #2,d2 ; couleur bit2 beq bit3 eor d3,4(a0) bit3 btst #3,d2 ; couleur bit3 beq bit4 eor d3,6(a0) bit4 WAIT_KEY FIN SET_RES old_res r‚tabli l'ancienne res move.w #0,-(sp) trap #1 SECTION DATA old_res dc.w 0 tab 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 SECTION BSS ds.l 256 PILE ds.l 1

14

xCeLfr (./13) :
j'ai déjà lu qu'il fallait remplacer les div et mul par des opérations binaires ?

Le truc classique (et pas uniquement 68000 ou spécifiquement ST) pour les multiplications ou divisions binaires par une puissance de 2, c'est de faire un décalage de bits.
Par exemple 5*8, ça donne :
00000101 décalé de 3 bits à gauche = 00101000, soit 40

avatar
De nouveaux jeux pour vos vieilles consoles ? En 2024 ?
https://yastuna-games.com

15

xCeLfr (./13) :
Maintenant j'aimerais comprendre les différentes technique d'optimisation, j'ai déjà lu qu'il fallait remplacer les div et mul par des opérations binaires ?
Oui, c'est le premier truc indispensable, parce qu'avec des mul et des div ton code va être effroyablement lent smile

Les équivalences pour les nombres non signés :
• Multiplier par 2N : décaler de N bits vers la gauche.
• Diviser par 2N : décaler de N bits vers la droite.
• Calculer le reste de la division par 2N : faire un AND avec (2N - 1).
• Arrondir au multiple de 2N supérieur : ajouter (2N - 1), puis faire un AND avec (NOT ((2N - 1)).

Pour optimiser tes multiplications par une constante, tu peux :
• décomposer la multiplication : par exemple, x * 160 = x * 5 * 32 = ((x * 4) + x) * 32 = ((x * 22) + x) * 25. À partir de là, voir ci-dessus.
• si tu as de la place en mémoire et que la plage de valeurs de x n'est pas trop grande, précalculer une table de multiplication.

Pour optimiser tes divisions par une constante, tu peux :
• multiplier par l'inverse : au lieu de diviser x par y, tu multiplies x par (2N / y), puis tu divises par 2N (plus N est grand, plus c'est précis, mais attention à ne pas dépasser la valeur maximum d'un entier).
• comme pour la multiplication, utiliser une table de division précalculée.

L'optimisation suivante, c'est d'inclure la routine qui affiche un pixel dans la fonction appelante. Par exemple, pour tracer une ligne, tu ne vas plus appeler la fonction "pixel" pour chaque point, mais chercher à tracer plusieurs points d'un coup et économiser beaucoup de calculs (parce que si tu connais la position en mémoire du point précédent, celle du point suivant est calculable de manière beaucoup plus simple).
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

16

clair, net et complet, parfait merci !
Avec ça je devrais pouvoir faire un petit starfield basique.

17

hello
XCeLfr, neopang sur st ? (excellent boulot)

Bonne continuation


ps: au passage je remercie GT pour son aide (perso je suis en standby mais c'est génial de voir grandir ma pitite Jeanne wink ).
avatar
Tous mes travaux sont centralisés sur mon piti blog. N'hésitez pas à y faire un tour : https://ricco59.blogspot.com/

18

Si ma version était supérieure à la version ST ça aurait été une bonne idée smile
Sinon pour m’entrainer, le refaire sur ST pourrait être un bon exercice.

19

Ça y est cette fois j'ai la logique, manque les petits trucs plus pointus smile
J'ai fait un petit champs d'étoiles, on est loin des belles démos dont on est tous fan.
Voici le code et le prg, si ça intéresse un autre débutant ^^

J'aimerais bien savoir si il y a des erreurs grossières ou des subtilités pas notées dans les docs ou n'importe quoi d'autre intéressant en optimisation.

Par ex: un if, elseif ... ou un switch ..en C, il existe une notation plus élégante en ASM que la suivante ?
; soustractions cmp.w #100,d0 bgt sub3 cmp.w #50,d0 bgt sub2 sub1 sub.w #3,d1 ; x-3 bra sub_ok sub2 sub.w #2,d1 ; x-2 bra sub_ok sub3 sub.w #1,d1 ; x-1 sub_ok

Je pense que la suite logique consistera à jouer avec les sprites...

20

Je viens de mettre un oeil rapide et je suis tombé la dessus :

move.l (a6)+,d5 ; 1 point dans d5 ; 12 cycles
move.w d5,d6 ; y dans d6 ; 4 cycles
swap d5 ; x dans d5 ; 4 cycles

ce qui nous fait 20 cycles pour récupéré ton X et ton Y alors que :

move.w (a6)+,d5
move.w (a6)+,d6

fait 2 * 8 = 16 cycles ce qui fait un code plus court et plus rapide. ( Fait juste gaffe je sais pas si d5 et d6 sont dans le bon ordre (Sinon ton X et on Y seront permutés))


ensuite :

sub1 sub.w #3,d1 ; x-3
bra sub_ok

sub2 sub.w #2,d1 ; x-2
bra sub_ok

sub3 sub.w #1,d1 ; x-1

sub_ok

cmp.w #0,d1 ; compare X a 0
bgt plus ; si plus grand on sauve

ton cmp.W #0,D1 est inutile et oui !! Car toute operation mathematique normale positionne les flags conditions (En gros fait un test en 'douce') donc tous tes sub avant font le test en meme apres la soustraction directement donc tu peux le viré wink

Pour la gestion des touches pour quitter, il y a un reg en $fffc02 qu'il suffit de lire pour avoir le 'scancode' de la touche, en gros on utilise couramment :

cmp.b #$39,$fffc02
bne Start

mais attention pour faire cela il faut accèder a la partie basse de la mémoire qui est protégé, il faut y acceder en superviseur sinon plantage.

Pour un début, bravo, ce que j'écris ce sont juste des optims ou des choses que tu connaitras par coeur d'ici quelque mois, mais rien que le fait de le faire en assembleur merite un Bravo smile

Il y a des grosses optims possibles mais comme écrit avant ca sera pour plus tard a moins que tu veuilles quelque explications.


GT smile
avatar
Accrochez vous ca va être Cerebral !!

21

GT Turbo (./20) :
move.l (a6)+,d5 ; 1 point dans d5 ; 12 cycles
move.w d5,d6 ; y dans d6 ; 4 cycles
swap d5 ; x dans d5 ; 4 cycles

ce qui nous fait 20 cycles pour récupéré ton X et ton Y alors que :

move.w (a6)+,d5
move.w (a6)+,d6

fait 2 * 8 = 16 cycles ce qui fait un code plus court et plus rapide. ( Fait juste gaffe je sais pas si d5 et d6 sont dans le bon ordre (Sinon ton X et on Y seront permutés))

Ça parait tellement évident après coup ^^
GT Turbo (./20) :
on cmp.W #0,D1 est inutile et oui !! Car toute operation mathematique normale positionne les flags conditions (En gros fait un test en 'douce') donc tous tes sub avant font le test en meme apres la soustraction directement donc tu peux le viré wink.gif

Bien vu, je vais garder ça à l'esprit pour la suite
GT Turbo (./20) :
Il y a des grosses optims possibles mais comme écrit avant ca sera pour plus tard a moins que tu veuilles quelque explications.

J'imagine que sur un petit programme comme celui ci le gain ne sera pas énorme mais je suis toujours preneur pour de nouvelles techniques.
Autant essayer d'optimiser au fur et à mesure au lieu d'y revenir après coup pour optimiser.

22

xCeLfr (./21) :
J'imagine que sur un petit programme comme celui ci le gain ne sera pas énorme mais je suis toujours preneur pour de nouvelles techniques.
Autant essayer d'optimiser au fur et à mesure au lieu d'y revenir après coup pour optimiser.


Il y a de super grosse optims possibles, mais pour ton premier code chapeau, j'ai galèré plus que toi pour mon premier prog.


GT smile
avatar
Accrochez vous ca va être Cerebral !!

23

xCeLfr (./1) :
L'idée serait de tester un affichage en perspective du genre en C :

#define PI 3.14159265359
#define FUITE 512

float q;
float x,y;
q = 1 - ze/FUITE ;
x = xe/q ; y = ye/q ;


Premier objectif atteint, je pensais que ça allait être plus simple et ben non, j'ai quand même bien galéré.
En tout cas le principe est en place : CUBE.PRG

24

wow y'a encore du monde qui commence à coder sur ST??? naaaaan
STK rulez!

25

Hello,

Ça c'est du déterrage de topic smile

J'me remets doucement à l'ASM (j'aurais jamais dû laisser passer 2ans sans y toucher).

Je recherche des infos sur les fonctions XBIOS.
J'ai déjà trouvé la liste des fonctions ici : http://toshyp.atari.org/en/004014.html
maintenant j'aimerais bien savoir ce que retournent ces fonction ?

ex: Getrez
Si on se base sur le proto en C "int16_t Getrez( void );" on se doute que que ça retourne un word (j'imagine dans D0).
Mais quand j'exécute avec le debugger j'ai bien 1 (640*200) dans D0 mais aussi un long dans D1 (E01036 dans mon cas)

Donc pour résumer, savez-vous où je pourrais trouver la liste ainsi que leur taille des retours de fonctions xbios ?

EDIT: j’espère avoir été clair wink
Il me semble qu'il y a deux ans j'avais ces infos mais je ne sais plus comment je les trouvais

26

avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

27

D'après les binding du C (OSBIND.H), la réponse des appels est toujours dans D0.

Dans ma mémoire, les registres d0-d2 a0-a2 ne sont pas "protégé" et peuvent donc être utilisé pas le système sans être sauvegardé/restauré. Tu dois les sauvegarder si tu les utilises avant l'appel. Donc normal que ces registres subissent des modifications mais ce ne sont pas des "réponses".

Il n'y a qu'une seule réponse direct renvoyé par les fonctions (en D0). Pour les autres type de réponse, tu dois généralement passé un pointeur en paramètre pour y recevoir des données supplémentaire.

En résumé, il n'y a que D0 qui sert de réponse.


GT Turbo pourra t'en dire plus (et me corriger éventuellement ^^)

!call GT Turbo

28

(ton call n'a pas marché)

Mais sinon, c'est bien ça :
http://www.yardley.cc/atari/compendium/atari-compendium-chapter-4-XBIOS.htm :The XBIOS, like the BIOS may utilize registers D0-D2 and A0-A2 as scratch registers and their contents should not be depended upon at the completion of a call. In addition, the function opcode placed on the stack will be modified. The XBIOS places its return code value in d0.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo

29

(c'est un bug ou je m'y prend mal ? (mon premier call ^^) )

Merci pour l'info.

30

Ça ne fonctionne pas si tu édites ton post, il faut le mettre dans le post d'origine.
avatar
Zeroblog

« Tout homme porte sur l'épaule gauche un singe et, sur l'épaule droite, un perroquet. » — Jean Cocteau
« Moi je cherche plus de logique non plus. C'est surement pour cela que j'apprécie les Ataris, ils sont aussi logiques que moi ! » — GT Turbo