Derniers sujets
Qui est en ligne ?
Il y a en tout 1 utilisateur en ligne :: 0 Enregistré, 0 Invisible et 1 Invité Aucun
Le record du nombre d'utilisateurs en ligne est de 29 le Mer 25 Fév 2015 - 14:01
Connexion
Statistiques
Nous avons 242 membres enregistrésL'utilisateur enregistré le plus récent est AIRBUS44
Nos membres ont posté un total de 8922 messages dans 811 sujets
cc65 et Inline assembler
3 participants
Forum Oric :: Forums :: Forum Public :: Programmation en C
Page 1 sur 1
cc65 et Inline assembler
Hello,
Je test le compilateur frasm avec de l'assembleur dans le code C.
j'aimerais coder mon petit jeux en c avec des petites routines en assembleur, ainsi que des datas graphiques intégrées au code .... !
et la doc cc65.org est apparemment trop brève à ce sujet :o
Si quelqu'un a déjà fait du inline asm, ça m'aiderai de savoir comment il a codé cela...
j'ai des erreurs sur les labels "_label4:"
Je test le compilateur frasm avec de l'assembleur dans le code C.
j'aimerais coder mon petit jeux en c avec des petites routines en assembleur, ainsi que des datas graphiques intégrées au code .... !
et la doc cc65.org est apparemment trop brève à ce sujet :o
Si quelqu'un a déjà fait du inline asm, ça m'aiderai de savoir comment il a codé cela...
- Code:
main()
{
asm(" LDX $D1 "); // Load register X
asm(" _label4: ");
asm(" LDY $CF ");
asm(" DEY ");
asm(" _label1: ");
asm(" LDA ($CD),Y ");
asm(" STA ($CB),Y ");
asm(" DEY ");
asm(" CPY #$FF ");
asm(" BNE _label1 "); // $F7
asm(" CLC ");
asm(" LDA $CB ");
asm(" ADC $D0 ");
asm(" STA $CB ");
asm(" BCC _label2 "); // $02
asm(" INC $CC ");
asm(" _label2: ");
asm(" CLC ");
asm(" LDA $CD ");
asm(" ADC $CF ");
asm(" STA $CD ");
asm(" BCC _label3 "); // $02
asm(" INC $CE ");
asm(" _label3: ");
asm(" DEX ");
asm(" BNE _label4 "); // $DB
asm(" RTS ");
}
;
j'ai des erreurs sur les labels "_label4:"
- Code:
0x6b9 _main
06b9 a6 d1 LDX $D1
_label4:
ERROR - invalid opcode
ERROR - parse error at/before character ":"
06bb a4 cf LDY $CF
06bd 88 DEY
_label1:
ERROR - invalid opcode
ERROR - parse error at/before character ":"
06be b1 cd LDA ($CD),Y
06c0 91 cb STA ($CB),Y
06c2 88 DEY
06c3 c0 ff CPY #$FF
BNE _label1
D:\LCC65\bin\frasm.exe -o 6502.out -l errors.txt C:\WINDOWS\TEMP\vag4889.o
ERROR SUMMARY - ERRORS DETECTED 16
- WARNINGS 0
Impossible de trouver D:\LCC65\Euphoric\PRG_C\test1.tap
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
Bonjour,
Tu utilises cc65 ou lcc65?
cc65 utilise ca65 comme assembleur.
Tu utilises cc65 ou lcc65?
cc65 utilise ca65 comme assembleur.
assinie- Messages : 271
Date d'inscription : 09/02/2014
Re: cc65 et Inline assembler
J'utilise le cc65. Mais je viens de voirque ce serait mieux avec lcc65, j'ai effectivement vu la page suivante :
http://miniserve.defence-force.org/svn/public/pc/tools/osdk/main/Osdk/_final_/sample/mixed/hello_world_mixed/
apparemment on passe les parametres par la pile .
http://miniserve.defence-force.org/svn/public/pc/tools/osdk/main/Osdk/_final_/sample/mixed/hello_world_mixed/
apparemment on passe les parametres par la pile .
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
J'ai testé la compilation de ton exemple avec cc65 + ca65 et le seul "problème" que j'ai rencontré provient des espaces après les noms des labels.
A priori cc65 est un peu chatouilleux sur les espaces "non significatifs" en fin de ligne et lorsqu'il génère le code assembleur il supprime tous les labels qui, selon lui, ne sont pas utilisés.
Du coup, il supprime la déclaration des labels et forcémént au moment de l'assemblage, ca65 ne les trouve pas et remonte des erreurs.
En supprimant les espaces inutiles, ça passe sans problème.
Mais à priori, dans ton cas je pense que c'est une incompatibilité de syntaxe entre le code généré par cc65 et frasm que tu utilises pour l'assemblage.
Dans tous les cas, je pense qu'il vaut mieux faire une librairie en assembleur avec tes procédures et ensuite le programme en C pour les appeler.
C'est plus facile à maintenir que de tout mélanger dans le source C.
Ensuite, il suffit d'indiquer les librairies perso au linker.
Tu peux regarder les sources des librairies standards fournies avec cc65 ou lcc65 suivant le cas pour voir comment on passe les paramètres et les valeurs de retour.
A priori cc65 est un peu chatouilleux sur les espaces "non significatifs" en fin de ligne et lorsqu'il génère le code assembleur il supprime tous les labels qui, selon lui, ne sont pas utilisés.
Du coup, il supprime la déclaration des labels et forcémént au moment de l'assemblage, ca65 ne les trouve pas et remonte des erreurs.
En supprimant les espaces inutiles, ça passe sans problème.
Mais à priori, dans ton cas je pense que c'est une incompatibilité de syntaxe entre le code généré par cc65 et frasm que tu utilises pour l'assemblage.
Dans tous les cas, je pense qu'il vaut mieux faire une librairie en assembleur avec tes procédures et ensuite le programme en C pour les appeler.
C'est plus facile à maintenir que de tout mélanger dans le source C.
Ensuite, il suffit d'indiquer les librairies perso au linker.
Tu peux regarder les sources des librairies standards fournies avec cc65 ou lcc65 suivant le cas pour voir comment on passe les paramètres et les valeurs de retour.
assinie- Messages : 271
Date d'inscription : 09/02/2014
Re: cc65 et Inline assembler
Dans mes tablettes (de chocolat), j'ai a tester le passage de parametres entre CC65 et CA65. Normalement, cela est réalisé comme OSDK par la pile.
Re: cc65 et Inline assembler
cc65 utilise sa propre pile pour le passage de paramètres, il y a plusieurs fonctions disponibles pour les ajouter ou les récupérer via les registres A et X du 6502.
assinie- Messages : 271
Date d'inscription : 09/02/2014
Re: cc65 et Inline assembler
assinie a écrit:J'ai testé la compilation de ton exemple avec cc65 + ca65 et le seul "problème" que j'ai rencontré provient des espaces après les noms des labels.
A priori cc65 est un peu chatouilleux sur les espaces "non significatifs" en fin de ligne et lorsqu'il génère le code assembleur il supprime tous les labels qui, selon lui, ne sont pas utilisés.
Du coup, il supprime la déclaration des labels et forcémént au moment de l'assemblage, ca65 ne les trouve pas et remonte des erreurs.
En supprimant les espaces inutiles, ça passe sans problème.
Mais à priori, dans ton cas je pense que c'est une incompatibilité de syntaxe entre le code généré par cc65 et frasm que tu utilises pour l'assemblage.
Dans tous les cas, je pense qu'il vaut mieux faire une librairie en assembleur avec tes procédures et ensuite le programme en C pour les appeler.
C'est plus facile à maintenir que de tout mélanger dans le source C.
Ensuite, il suffit d'indiquer les librairies perso au linker.
Tu peux regarder les sources des librairies standards fournies avec cc65 ou lcc65 suivant le cas pour voir comment on passe les paramètres et les valeurs de retour.
Merci pour ces éclaircissements, aurais-tu un exemple simple en c d'utilisation d'une librairie en asm (sur une page web ou perso) à me communiquer =)
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
J'ai trouvé une page avec un exemple simple ici (en anglais)
En résumé, si ta fonction assembleur prend un paramètre a de type char et renvoie une valeur de type unsigned int,il faut déclarer ta fonction assembleur dans le code C
Le __fastcall__ permet d'avoir le dernier paramètre directement dans les registres A (poids faible) et X (poids fort).
Sans le __fastcall__, il faut faire un jsr popa ou jsr popax suivant la taille du paramètre.
Si il y a pllusieurs paramètres, ils sont rangés dans l'ordre inverse sur la pile C (ie: l'avant dernier sera le premier récupéré par un jsr popa ou jsr popax).
Le label de la fonction dans le code assembleur doit commencer par un _ pour être reconnu.
Pour la valeur de retour, il suffit de la mettre dans les registres A et X (X doit être mis à 0 dans le cas ou tu renvoies une valeur de type char)
Pour l'exemple ci-dessus, le code assembleur ressemblerait à:
et pour la partie en C:
Si tu mets plusieurs fonctions dans le fichier assembleur, il devrait ressembler à quelque chose comme ça:
Je te conseille de regarder le source des librairies standard de cc65 sur github ou de regarder le code assembleur généré par cc65.
En résumé, si ta fonction assembleur prend un paramètre a de type char et renvoie une valeur de type unsigned int,il faut déclarer ta fonction assembleur dans le code C
- Code:
extern int __fastcall__ testasm(unsigned char a);
Le __fastcall__ permet d'avoir le dernier paramètre directement dans les registres A (poids faible) et X (poids fort).
Sans le __fastcall__, il faut faire un jsr popa ou jsr popax suivant la taille du paramètre.
Si il y a pllusieurs paramètres, ils sont rangés dans l'ordre inverse sur la pile C (ie: l'avant dernier sera le premier récupéré par un jsr popa ou jsr popax).
Le label de la fonction dans le code assembleur doit commencer par un _ pour être reconnu.
Pour la valeur de retour, il suffit de la mettre dans les registres A et X (X doit être mis à 0 dans le cas ou tu renvoies une valeur de type char)
Pour l'exemple ci-dessus, le code assembleur ressemblerait à:
- Code:
;
; testasm.s
; Ajoute 1 au paramètre passé
;
_testasm:
ldx #$00 ; Poids fort de la valeur de retour
clc
adc #01 ; Ajoute 1 au paramètre passé
bne suite
inx
suite:
rts
et pour la partie en C:
- Code:
#include <stdio.h>
extern int __fastcall__ testasm(unsigned char a);
void main(void)
{
unsigned char a=2;
printf("%u\n", testasm(a);
}
Si tu mets plusieurs fonctions dans le fichier assembleur, il devrait ressembler à quelque chose comme ça:
- Code:
;
; Déclare les fonctions exportées (ie: utilisable par le programme C)
;
.export _fonctionA, _fonctionB
.code
.proc _fonctionA
;
; Code assembleur de la fonction A
;
.endproc
.proc _fonctionB
;
; Code assembleur de la fonction B
;
.endproc
fonctionC:
;
; Code assembleur
; cette fonction ne peut pas être appelée depuis le C
;
Je te conseille de regarder le source des librairies standard de cc65 sur github ou de regarder le code assembleur généré par cc65.
assinie- Messages : 271
Date d'inscription : 09/02/2014
Re: cc65 et Inline assembler
C'est super, j'ai toutes les réponses à mes questions !
ma prochaine étape : paramétrer visual studio 2013 pour lcc65
merci assinie de ton aide précieuse, merci à tous
ma prochaine étape : paramétrer visual studio 2013 pour lcc65
merci assinie de ton aide précieuse, merci à tous
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
Assinie a été le plus rapide ...
Ci dessous un lien vers la doc de CC65 qui résume le fonctionnement
https://cc65.github.io/doc/cc65-intern.html#ss1.1
Ci dessous un lien vers la doc de CC65 qui résume le fonctionnement
https://cc65.github.io/doc/cc65-intern.html#ss1.1
Re: cc65 et Inline assembler
Envoyé à Grégoire une integration de CC65 dans VS pour Apple 2.
Joyeux Noel à tous
Joyeux Noel à tous
Re: cc65 et Inline assembler
Je me permet de continuer sur le sujet :
Je suis sous lcc65, et je souhaite passer ma variable ecran dans le code ASM() , enfin si c'est possible .
De plus comment accéder au low et au high byte de la variable ecran dans en code ASM() ?
Enfin question pour les experts ;-)
Puis je passer à asm() des variables de type pointeur ?
Je suis sous lcc65, et je souhaite passer ma variable ecran dans le code ASM() , enfin si c'est possible .
- Code:
unsigned int ecran = 0xA000;
/* ..... */
asm("clc");
asm("ldy 10");
asm("suite1:");
asm("ldx #$FF");
asm("suite:");
asm("lda #65");
asm("sta (ecran),x); /* <----- ici comment passer ma variable ecran ? */
asm("dex");
asm("bne suite");
asm("dey");
asm("bne suite1");
asm("rts");
De plus comment accéder au low et au high byte de la variable ecran dans en code ASM() ?
Enfin question pour les experts ;-)
Puis je passer à asm() des variables de type pointeur ?
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
Je ne sais pas si la syntaxe de lcc65 est similaire à celle de cc65 mais au cas où...
asm() ou __asm__ () de cc65 fonctionnent sur le même principe que la fonction printf(), à savoir que le premier paramètre est en fait une chaine de format et les suivant les paramètres de ce format.
Exemple:
et
La page expliquant le format pour cc65 est ici
Pour récupérer le poids fort ou le poids faible dans un lda par exemple, il faut utiliser la syntaxe:
Si tu utilises lcc65 avec frasm, il me semble que la syntaxe est:
Remarque: sta (ptr),x est incorrect.
asm() ou __asm__ () de cc65 fonctionnent sur le même principe que la fonction printf(), à savoir que le premier paramètre est en fait une chaine de format et les suivant les paramètres de ce format.
Exemple:
- Code:
asm("sta (%v),y", globalEcran);
- Code:
sta (_globalEcran),y
et
- Code:
asm("sta %v,x", globalEcran);
- Code:
sta _globalEcran,x
La page expliquant le format pour cc65 est ici
Pour récupérer le poids fort ou le poids faible dans un lda par exemple, il faut utiliser la syntaxe:
- Code:
lda #>valeur
lda #<valeur
Si tu utilises lcc65 avec frasm, il me semble que la syntaxe est:
- Code:
lda #HIGH(valeur)
lda #LOW(valeur)
Remarque: sta (ptr),x est incorrect.
assinie- Messages : 271
Date d'inscription : 09/02/2014
Re: cc65 et Inline assembler
Merci Assinie de tes explicatons
En fait il fait toujours une erreur, il n'aime pas cette expression
le Lcc65 est peut être plus limité que le CC65
Je vais peut etre devoir me mettre au CC65...
En fait il fait toujours une erreur, il n'aime pas cette expression
- Code:
asm("sta (%v),x", ecran);
le Lcc65 est peut être plus limité que le CC65
Je vais peut etre devoir me mettre au CC65...
assinie a écrit:Je ne sais pas si la syntaxe de lcc65 est similaire à celle de cc65 mais au cas où...
asm() ou __asm__ () de cc65 fonctionnent sur le même principe que la fonction printf(), à savoir que le premier paramètre est en fait une chaine de format et les suivant les paramètres de ce format.
Exemple:génère le code assembleur:
- Code:
asm("sta (%v),y", globalEcran);
- Code:
sta (_globalEcran),y
etgénère le code assembleur
- Code:
asm("sta %v,x", globalEcran);
- Code:
sta _globalEcran,x
La page expliquant le format pour cc65 est ici
Pour récupérer le poids fort ou le poids faible dans un lda par exemple, il faut utiliser la syntaxe:
- Code:
lda #>valeur
lda #<valeur
Si tu utilises lcc65 avec frasm, il me semble que la syntaxe est:
- Code:
lda #HIGH(valeur)
lda #LOW(valeur)
Remarque: sta (ptr),x est incorrect.
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
Quelle erreur as-tu?
Comme indiqué en remarque dans mon post précédent, l'instruction sta (ecran),x est illégale.
En indirect c'est soit sta (ecran),y soit sta (ecran,x)
Comme indiqué en remarque dans mon post précédent, l'instruction sta (ecran),x est illégale.
En indirect c'est soit sta (ecran),y soit sta (ecran,x)
assinie- Messages : 271
Date d'inscription : 09/02/2014
Re: cc65 et Inline assembler
Hélas ni l'un ni l'autre ne fonctionne. Et il n'y a pratiquement pas d'aide sur le Net.
Je ne vois pas le détail de l'erreur sous VS j'ai une ligne avec ... Build Faild - fichier EXEC
J'avais mis en place Visual studio avec LCC65 , je vais peut être devoir le refaire pour CC65 .. :o
Je ne vois pas le détail de l'erreur sous VS j'ai une ligne avec ... Build Faild - fichier EXEC
J'avais mis en place Visual studio avec LCC65 , je vais peut être devoir le refaire pour CC65 .. :o
assinie a écrit:Quelle erreur as-tu?
Comme indiqué en remarque dans mon post précédent, l'instruction sta (ecran),x est illégale.
En indirect c'est soit sta (ecran),y soit sta (ecran,x)
goyo- Messages : 199
Date d'inscription : 02/05/2014
Age : 52
Localisation : Massy
Re: cc65 et Inline assembler
je vais peut être devoir le refaire pour CC65
Oui, vas-y.
La communauté CC65 est plus active (C64, Apple2 ...) et tu devrais pouvoir trouver des aides (cf mon mail)
et j'oserais dire que cela me motivera aussi un peu - plus ca va moins je code et plus je prends de retard dans le mag
bref, je tourne en rond
Forum Oric :: Forums :: Forum Public :: Programmation en C
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
|
|
Dim 31 Mar 2024 - 14:35 par kenneth
» Bla Bla général du Jury
Jeu 21 Mar 2024 - 8:51 par Dom50
» carte mère Oric (re)tracée
Mar 5 Mar 2024 - 18:54 par kenneth
» Meurtre à Grande Vitesse
Dim 25 Fév 2024 - 5:09 par Iurius
» ORIC-1 sur LE BON COIN
Ven 23 Fév 2024 - 23:01 par Mcar
» ORIC ATMOS sur LE BON COIN
Dim 4 Fév 2024 - 12:06 par kiwilevrai
» Problème d'affichage des couleurs avec un Oric Atmos
Sam 27 Jan 2024 - 1:26 par pierbail
» Bienvenue dans le Forum des Oriciens
Mar 9 Jan 2024 - 12:33 par Dom50
» Rencontre avec Laurant Weill, co-fondateur de Loriciel, et mon garçon de 12 ans
Ven 29 Déc 2023 - 14:13 par Arcade-des-Monts
» Bonnes fêtes
Mar 26 Déc 2023 - 10:21 par Dom50
» Murders in Venice / Meutres à Venise
Sam 18 Nov 2023 - 22:44 par retroric
» Un clavier PS/2 pour tester un ORIC
Dim 27 Aoû 2023 - 9:49 par Voyageur
» Disquette 3" Sedoric
Mar 1 Aoû 2023 - 14:22 par AtomeX
» faire un 6502 avec des phototransistor
Dim 16 Juil 2023 - 17:26 par Voyageur
» Oricutron linux et DSK
Jeu 29 Juin 2023 - 18:34 par Voyageur