Derniers sujets
» rs
basic & lib ASM___[RESOLU] EmptyAujourd'hui à 6:36 par didierv

» TranspOrictable
basic & lib ASM___[RESOLU] EmptyDim 15 Sep 2019 - 22:55 par Voyageur

» CEO-MAG 351
basic & lib ASM___[RESOLU] EmptySam 14 Sep 2019 - 21:30 par didierv

» Apprendre l'Assembleur ORIC
basic & lib ASM___[RESOLU] EmptySam 14 Sep 2019 - 9:42 par ]0[v]

» Jeux Non Oric - retrogaming
basic & lib ASM___[RESOLU] EmptyVen 13 Sep 2019 - 20:05 par Dbug

» Emulation de disquette avec un GOTEK (firmware HxC, clé USB) sur un Jasmin 2 pour Oric Atmos
basic & lib ASM___[RESOLU] EmptyJeu 12 Sep 2019 - 19:25 par Dbug

» Mystery Towers
basic & lib ASM___[RESOLU] EmptyMar 10 Sep 2019 - 7:43 par Dom50

» Une websérie sur le jeu video made in France
basic & lib ASM___[RESOLU] EmptyMar 10 Sep 2019 - 7:17 par didierv

» Depannages post visu
basic & lib ASM___[RESOLU] EmptyLun 9 Sep 2019 - 20:29 par retroric

» basic & lib ASM___[RESOLU]
basic & lib ASM___[RESOLU] EmptyLun 9 Sep 2019 - 15:23 par ]0[v]

» Le labo d Heliox - du DIY
basic & lib ASM___[RESOLU] EmptyLun 9 Sep 2019 - 12:27 par kenneth

» The House of death
basic & lib ASM___[RESOLU] EmptyDim 8 Sep 2019 - 18:21 par Dom50

» des pages cachées sur sur le forum ?
basic & lib ASM___[RESOLU] EmptyVen 6 Sep 2019 - 18:52 par froggy

» optimisation scrolling horizontal
basic & lib ASM___[RESOLU] EmptyMar 3 Sep 2019 - 18:14 par goyo

» Aux couleurs de l'Atmos
basic & lib ASM___[RESOLU] EmptyMar 3 Sep 2019 - 1:05 par kenneth

Qui est en ligne ?
Il y a en tout 4 utilisateurs en ligne :: 0 Enregistré, 0 Invisible et 4 Invités :: 1 Moteur de recherche

Aucun

Le record du nombre d'utilisateurs en ligne est de 29 le Mer 25 Fév 2015 - 14:01
Connexion

Récupérer mon mot de passe

Statistiques
Nous avons 193 membres enregistrés
L'utilisateur enregistré le plus récent est Oric Man

Nos membres ont posté un total de 7787 messages dans 672 sujets
Portail ORIC




basic & lib ASM___[RESOLU]

Aller en bas

basic & lib ASM___[RESOLU] Empty basic & lib ASM___[RESOLU]

Message par ]0[v] le Mer 4 Sep 2019 - 17:18

Petit question afin de me confirmer une hypothèse... Rolling Eyes
j'ai développé un petit driver pour une interface pour l'oric. Il y a 14 fonctions en tout écrites en asm. Cela compile (ça veut pas dire que ça marche, hein  Laughing )
par example j'implante cette lib en $8000
Si je souhaite appeller ces fonctions depuis le basic, cela peut seulement se faire au travers d'un CALL #, non?
Et du coup la première sera facilement appelable et pour les autres faudra que je fasse une extraction de l'adresse car les longueurs de chacune des fonctions n'est pas constante.
j'ai bon?! Wink


Dernière édition par ]0[v] le Jeu 5 Sep 2019 - 10:24, édité 1 fois
]0[v]
]0[v]

Messages : 51
Date d'inscription : 25/07/2019

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par assinie le Mer 4 Sep 2019 - 20:26

Tu peux les appeler avec un CALL #xxxx oui.

Après il y a plusieurs façon de faire pour les autres.
Le plus simple est de mettre l'adresse des différentes fonctions dans une table au début en #8000. De cette façon, l'adresse de la 1ère fonction est en #8000, l'adresse de la seconde en #8002, etc.
Code:

adresse_fonction1
adresse_fonction2
...
Ensuite pour les appeler, il suffit de faire un CALL (DEEK(#800x)).

Tu peux simplifier l'appel en modififant la table pour mettre un JMP devant chaque adresse de fonction:
Code:

JMP fonction1
JMP fonction2
...
Pour appeler la première fonction CALL #8000, pour la deuxième CALL #8003,...

Une autre solution est de modifier le vecteur de la fonction &() ou USR() du BASIC pour la faire pointer faire une petite routine qui va récupérer la valeur qui sera fournie à la fonction.
Pour uiliser &(), il faut mettre l'adresse de la fonction en $02FC.
Pour récupérer la valeur passée en paramètre, il faut faire JSR $D922, ensuite on dans dans le registre A le poids fort de la valeur et  dans Y le poids faible.

Il suffit alors de se servir de la valeur de Y comme index dans la table des adresses des fonctions.
Code:

enrty:
    jsr $d922              ; Conversion Flotttant -> entier
    tya                       ; Poids faible de la valeur
    asl                       ; Multiplie par 2
    tax                       ; Index dans la table
    lda table,x
    sta saut+1            ; saut+11 -> octet xx du jmp plus bas
    inx
    lda table,x
    sta saut+2            ; saut+2 -> octet yy du jmp

saut:
    jmp xxyy

table:
    .word fonction0        ; &(0)
    .word fonction1        ; &(1)

Mettre l'adresse de entry en $02FC.

(On peut aussi utiliser la pile et un RTS à la place du JMP.)

Il y a d'autres solutions possibles avec la commande "!" ou pour passer des paramètres.
assinie
assinie

Messages : 254
Date d'inscription : 09/02/2014

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par ]0[v] le Mer 4 Sep 2019 - 21:14

merci @assinie, pour cette réponse rapide et très développée Wink
L'idée des CALL est d'accéder rapidement aux diverses fonctions, comme c'est fait par le linker en C au final
Ensuite je souhaite utiliser le basic au minimun, c'est malheureusement le language choisit pour cette machine... toutes n'ont pas eut la chance d'être des jupiter ace ou Hector Cool
 Merci quand même d'avoir détaillé le fonctionnement
Oui après il y a la solution de faire une table ce qui apporte l'énorme avantage de savoir exactement qu'elle adresse appeler pour chaque fonctions au détriments d'une petite perte de temps, mais c'est très pratique aussi, dans mon cas je sais pas à tester en tout cas!
Si tu passes l'addresse via la pile ensuite tu recomposes l'adresse pour l'utiliser avec un JSR donc on gagne taille de code mais on perd en temps de d'execution, non? Et cela revient au même que d'utiliser un CALL, non?
]0[v]
]0[v]

Messages : 51
Date d'inscription : 25/07/2019

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par assinie le Mer 4 Sep 2019 - 22:47

Le coup de la pile et du RTS permet d'avoir un code plus compact pour la routine d'appel et évite de modifier dynamiquement le porgramme comme c'est fait dans les exemples que j'ai donnés (le JMP est modifié à la volée).

Le principe est le suivant, on empile l'adresse de la routine -1, ensuite le RTS utilise cette adresse comme adresse de retour.
Le RTS ajoute  1 à l'adresse empilée par un JSR d'où le -1 dans la table:

Code:

lda table,x
pha                  ; empile le poids fort
inx
lda table,x
pha                 ; empile le poids faible
rts                   ; <=> JMP

table:
.byte (fonction0 -1) >>8, (fonction0 -1) & $FF    : ATTENTION: poids fort en premier (contrairement à la norme pour le 6502)
.byte (fonction1 -1) >>8, (fonction1 -1) & $FF

D'un point de vue temps d'exécution, le RTS prend 6 cycles et un JMP n'en prend que 3, mais c'est en partie compensé par le PHA qui prend 3 cycles contre 4 pour un STA.

On peut encore gagner en taille et en vitesse, en utilsant 2 tables au lien d'une. La première contient les poids faibles des adersses et la seconde les poids forts, comme ça on évite  la multiplication par 2 de l'index, le INX et on peut avoir deux fois plus de fonctions (de 0 à 255 contre 0 à 127 avec une seule table).

Le code complet du post précédent devient:
Code:

enrty:
    jsr $d922              ; Conversion Flotttant -> entier
    lda table_l,y
    sta saut+1            ; saut+11 -> octet xx du jmp plus bas
    lda table_h,y
    sta saut+2            ; saut+2 -> octet yy du jmp

saut:
    jmp xxyy

table_l:
    .byte fonction0  & $ff      ; &(0)
    .byte fonction1  & $ff     ; &(1)

table_h:
    .byte fonction0  >> 8      ; &(0)
    .byte fonction1  >> 8     ; &(1)

et la version avec un RTS
Code:

enrty:
    jsr $d922              ; Conversion Flotttant -> entier
    lda table_h,y         ; Empile le poids fort
    pha
    lda table_l,y          ; Empile le poids faible
    pha

saut:
    rts

table_l:
    .byte fonction0  & $ff     ; &(0)
    .byte fonction1  & $ff     ; &(1)

table_h:
    .byte fonction0  >> 8     ; &(0)
    .byte fonction1  >> 8     ; &(1)

En fonction de l'assembleur  utilisé, l'écriture des tables peut être simplifié.

La version sans le RTS utilise 21 cycles, celle avec le RTS utilise 20 cycles (hors JSR $D922).
La taiile totale de la version sans le RTS est de 18, celle de la version avec le RTS n'est que de 12 octets (hors tables).

Globalement tu gagnes donc 1 cycle et 6 octets, les gains par rapport à la version du post précédent sont encore plus importants.
assinie
assinie

Messages : 254
Date d'inscription : 09/02/2014

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par Dbug le Jeu 5 Sep 2019 - 9:32

Code:
table_l:
    .byte fonction0  & $ff    ; &(0)
    .byte fonction1  & $ff    ; &(1)

table_h:
    .byte fonction0  >> 8    ; &(0)
    .byte fonction1  >> 8    ; &(1)
Ton assembleur ne supporte par la syntaxe < et > pour indiquer poids faible/fort?

_________________

Dbug
Dbug

Messages : 192
Date d'inscription : 06/01/2013

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par ]0[v] le Jeu 5 Sep 2019 - 10:14

Merci @assinie, j'avais vu ça dans une demo présente dans le sdk 4KKong (premiere version de Mario, me semble-t-il Smile)
C'est plus élégant que ma méthode des CALL pour lequel je dois fournir l'adresse d'implantation de la fonction. Là il suffit de connaître l'index de la fonction dans la table! Jusque là ça me dérangeais pas trop car j'avais fait un petit script bash qui automatisait le build et qui me récupérait les addresses pour chacune des fonctions depuis le fichier "map" et modifier le fichier ASM pour implanter la table des JMP, ça fait le job mais ça reste moins propre que la solution que tu as exposé Wink
Le coup des doubles tables me paraît parfait, de plus 1 cycle & 6 octets sur ces vieilles machines c'est énorme comme gain!!!
Du coup j'adopte cette solution!!! Very Happy
]0[v]
]0[v]

Messages : 51
Date d'inscription : 25/07/2019

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty basic & lib ASM

Message par ]0[v] le Jeu 5 Sep 2019 - 10:21

@Dbug: cela fonctionne aussi en tout cas avec XA, et il y a surtout encore mieux en terme de lisibilité. J'ai vu ça dans un code je me souviens plus lequel par contre mais en gros il suffit de définir
Code:
#define  LO(x)     <(x)
#define  HI(x)     <(x)
donc quand tu l'utilises ça devient encore plus parlant que le coup du '<' qui est moins lisible selon moi que l'opérateur de décalage '>> 8'.
finalement il n'y a que l'embarras du choix Laughing
]0[v]
]0[v]

Messages : 51
Date d'inscription : 25/07/2019

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par assinie le Jeu 5 Sep 2019 - 11:05

Pour l'écriture des tables, c'est ce que je disais, en fonction de l'assembleur utilisé c'est plus ou moins lisible ou simple, on peut aussi avoir un script externe qui génère ces tables.
Je n'ai pas voulu donner une syntaxe spécifique mais plutôt simplement indiquer le principe.

Sinon, avec ca65 c'est encore plus simple avec les instructions .lobytes et .hibytes:
Code:

table_l:
    .lobytes fonction0, fonction1, fonction2

table_h:
    .hibytes fonction0,fonction1, fonction2
assinie
assinie

Messages : 254
Date d'inscription : 09/02/2014

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par retroric le Jeu 5 Sep 2019 - 12:36

Hello,

Concernant ce qu'on appelle en fait le "RTS trick" pour l'implémentation de tables de saut, je m'étais intéressé au sujet il y a qq mois et j'avais trouvé un article très bien fait à ce sujet dans le Wiki consacré à la NES: NESdev wiki - RTS trick.

[EDIT: le site NESdev wiki était temporairement offline, mais est de nouveau accessible.]

Autre chose, j'avais noté à l'époque que cette astuce était en fait apparemment utilisée dans la ROM de l'Oric, car il y a des tables de saut prévues pour être utilisées avec un RTS (donc avec les adresses "moins un" des routines) pour toutes les commandes BASIC, les opérateurs et les fonctions arithmétiques: cf. le bouquin "L'Oric A Nu", pp. 68-71.

De mon côté, le sujet m'intéresse pour l'OSDK, j'avais commencé à creuser l'idée de faire une version des libs graphique et son qui puissent être compatibles Oric1/Atmos (actuellement les libs OSDK appelant la ROM fonctionnent uniquement sur Atmos) en utilisant des tables de saut qui pourraient être configurées au lancement du programme après détection de la machine, ou en utilisant les tables de saut déjà dans la ROM quand c'est possible.


Dernière édition par retroric le Jeu 5 Sep 2019 - 22:54, édité 2 fois

_________________
retrOric (Laurent D)https://github.com/retroric
retroric
retroric

Messages : 522
Date d'inscription : 09/08/2014
Age : 48
Localisation : Paris

https://github.com/retroric

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par ]0[v] le Jeu 5 Sep 2019 - 15:18

@assinie, ce n'est pas en $9D2C la conversion Float -> Int?
]0[v]
]0[v]

Messages : 51
Date d'inscription : 25/07/2019

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par assinie le Jeu 5 Sep 2019 - 15:35

Je pense ue tu veux dire $D92C Smile

En fait, en $D922, la routine vérife que la valeur n'est pas négative avant de faire la conversion et renvoie une erreur "ILLEGAL QUANTITY ERROR" dans ce cas.
Si tu utilises $D2FC, cette verification n'est pas faite ce qui peux te poser problème ensuite, dans ce cas tu peux aussi directement aller en $DF8C et récupérer le poids faible en $D4.

Note: les adresses sont celles de la version 1.1 de la ROM (Atmos)
assinie
assinie

Messages : 254
Date d'inscription : 09/02/2014

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par assinie le Jeu 5 Sep 2019 - 15:49

Pour vraiment limiter les problèmes, il faudrait même ajouter un test au retour de $D922 pour vérifier que le programme ne demande pas à exécuter une fonction qui n'existe pas.

Pour ça, il faut vérifier que le registre A est bien nul et que Y contienne une valeur qui n'est pas supérieure ou égale au nombre de fonctions de ta librairie et renvoyer une erreur le cas échéant (un JMP $D336 affiche "ILLEGAL QUANTITY ERROR" par exemple)
assinie
assinie

Messages : 254
Date d'inscription : 09/02/2014

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par ]0[v] le Lun 9 Sep 2019 - 15:23

@assinie: oui c'est bien de faire de la gestion d'erreur si ça ne me prend pas trop de place car mon driver fait déjà 920 octets.  Bon là ça doit rajouter 5 ou 6 octets de plus... Smile
Pour l'instant c'est pas ma priorité.
Et oui c'est bien de cette adresse là, $D922, dont je parlais Wink
]0[v]
]0[v]

Messages : 51
Date d'inscription : 25/07/2019

Revenir en haut Aller en bas

basic & lib ASM___[RESOLU] Empty Re: basic & lib ASM___[RESOLU]

Message par Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum