MSX Village forum

La Place des Développeurs FUSION-C Codez en C pour MSX les doigts dans le nez !

aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 30/11/2020 à 20h40

Reprise du message précédent

Ah... une dernière chose !
J'ai pas vérifié si c'était bien le cas avec SDCC, mais la norme C99 demande qu'une variable static soit initialisé automatiquement à 0.
Du coup, si dans ton programme tu as un " static char a; " par ex., le compilo/linker va le traiter comme une variable initialisé donc si tu fais pas la copie de _INITIALIZER vers _INITIALIZED , tu vas avoir une variable avec une valeur indéterminée (alors qu'avec la version du crt0 de Konamiman que tu utilises pour les binaires Basic, cette variable sera bien initialisée à 0).


On est toujours ignorant avant de savoir.
Github    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 16/12/2020 à 19h02
Devenez ingénieur grâce à Fusion-C

C'est maintenant comme cela que je vais faire connaitre Fusion-C...
Mais non, je ne rigole pas !

Frederic Garcia Nieto, élève de l'école Technique supérieur d'ingénierie informatique à Valence (Espagne) à rédiger son mémoire sous la forme d'un Tutorial sur la création d'un jeu sur MSX.
Et pour se faire, il utilise ... Fusion-C bien entendu.

Son mémoire expose de A à Z, comment réaliser un Bomb Jack sur MSX avec Fusion-C.
Des travaux préparatoires au code, tests, avec une grosse partie sur le MSX et sur Fusion-C. :D




Si ca vous branche vous trouverez le mémoire, le jeu, les sources du projet ici :


https://m.riunet.upv.es/handle/10251/145214?fbclid=IwAR0NBQ4lNfduBfP6XNkzIV3cWa3DfYtKmOywnkIsk8C5CSTPZaydH4YDLcA Edité par ericb59 Le 16/12/2020 à 19h06


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 16/12/2020 à 19h10
Félicitations à lui... et à toi. :)

EDIT : J'ai survolé son rapport ; ça semble du super boulot (même si je maitrise pas la langue de Konamiman)


On est toujours ignorant avant de savoir.
Github    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 28/12/2020 à 02h34
Il me semble qu'il y a un problème dans ta fonction HMMC dans Fusion-C 1.3.
A la fin, tu fais un " in a,(#0x99) " après avoir sélectionner S#0 (Status Register 0).
En faisant ça, tu risques de rater un V-Blank !

Quelques autres remarques moins importantes :
- Ton initialisation des registres R#36-R#46 serait plus rapide via l'écriture séquentielle sur le port 9Bh (Indirect register access port).
- Tu bloques les interruptions pendant toute la durée de la copie...
-- Si tu veux utiliser cette fonction in-game (durant l'affichage du jeu) c'est un problème pour tout ce qui dépend des interruptions (musique, H-Blank, RS232, etc.). Si j'ai bien compris, tu as juste besoin de mettre des DI/EI sur les pairs de out .
-- Si tu considères (comme moi) que c'est une fonction uniquement pre-game (durant l'initialisation/chargement du jeu) alors tu peux laisser le blocage des interruptions, mais dans ce cas, sort l'initialisation du registre S#2 de ta boucle, ça ira plus vite.
- C'est du pinaillage de haut vol, mais tu peux aussi passer de 14 à 12 T-states sur le check des flags CE et TR en utilisant un sra suivi d'un rla plutôt que des and . ^^


On est toujours ignorant avant de savoir.
Github    
TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5788

Le 28/12/2020 à 04h00
Moi j'aime bien les explications de aoineko car il sait de quoi il parle et c'est marrant car même si au début je me dis "Je vais rien comprendre.... Ils sont fou ces MSXiens :fou"
Et bien fait non, je comprend dans le principe (même si j'ignorais même l'existence jusque la de la fonction HMMC :D:oups), et comme votre dualité est enrichissante, enfin pour ceux qui suivent hein :lol (Franck : |-) ). En définitive, c'est pas du pinaillage, c'est de l'optimisation :tea

Sinon, félicitations à Frederic Garcia Nieto,.... Comme quoi le Msx n'est pas mort :tea :glass Edité par TurboSEB Le 28/12/2020 à 04h02



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 28/12/2020 à 09h27
@TurboSeb : HMMC est une commande interne au VDP du MSX2, qui permet le transfert rapide d'un bloc de données de la RAM vers la VRAM.
Le VDP dispose d'un certain nombre de commandes, pour accélérer certains traitements. Il "suffit" de donner les paramètres que la commande attends, puis d'appeler celle-ci.

Citation :
A la fin, tu fais un " in a,(#0x99) " après avoir sélectionner S#0 (Status Register 0).
En faisant ça, tu risques de rater un V-Blank !

Ici en effet, je pense pouvoir enlever le in a,(#0x99) de fin, qui ne sert à rien.

Toute fois, dans bon nombre d'exemples de code que j'ai trouvé, c'est la routine GetVDPStatus qui sert à terminer les commandes VDP pour faire un RESET du VDP, et ça n'a pas l'air de poser un problème.
Code ASM :
 
ReadReg: 
out ($99),a
ld a,15+128
out ($99),a
in a,($99)
ret


il y a un exemple ici et


Citation :
Ton initialisation des registres R#36-R#46 serait plus rapide via l'écriture séquentielle sur le port 9Bh

Oui, mais il faudrait que mes variables soient accessibles. Si je mes mettait dans une structure par exemple.
Ce qui m'ennui, c'est la lisibilité du code et de la fonction dans ce cas, et le fait de devoir faire 2 étapes pour appeler la fonction.
-1, attribuer les variables
-2, appeler la commande

A moins que tu n'ai une autre solution ?

Citation :
Tu bloques les interruptions pendant toute la durée de la copie

Alors oui, en théorie seuls certains OUT 99,a nécessiterai d'être sans interruption. J'ai essayé de ne mettre des DI/EI qu'à des endroits stratégiques, mais tous mes essais on toujours plantés.
Et tu remarqueras que dans les examples, cités plus haut, tout la fonction est sous un DI.
donc ? Je donne ma langue au chat sur la possibilité de faire autrement.

Citation :
tu peux aussi passer de 14 à 12 T-states sur le check des flags CE et TR en utilisant un sra suivi d'un rla plutôt que des and

:hum Ca à le même effet sur le flag Z ?
Edité par ericb59 Le 28/12/2020 à 09h29


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 28/12/2020 à 10h00
ericb59 :
Citation :
A la fin, tu fais un " in a,(#0x99) " après avoir sélectionner S#0 (Status Register 0).
En faisant ça, tu risques de rater un V-Blank !

Toute fois, dans bon nombre d'exemples de code que j'ai trouvé, c'est la routine GetVDPStatus qui sert à terminer les commandes VDP pour faire un RESET du VDP, et ça n'a pas l'air de poser un problème.


Quelques remarques :
- Après avoir modifié la valeur du registre de status (R#15), il faut toujours le remettre à 0 car la routine du Bios qui gère les interruptions check S#0 sans initialiser cette valeur (héritage du MSX1).
- Si tu veux attendre la fin de l'exécution de ta commande, tu vas avoir besoin de lire S#2 puis de réinitialiser le registre de status sur S#0, mais PAS de lire S#0.
- A moins que tu souhaites utiliser la fonction de détection automatique de collision/superposition de sprites ET que tu es sûr que tu te trouves suffisamment avant ou après le V-Blank, il ne faut surtout pas lire S#0 ou le Bios risque de ne pas pouvoir détecter le prochain V-Blank (ce qui est un GROS problème ^^).
- Pour ce qui est de l'attente de fin de commande VDP, il vaut toujours mieux le faire juste avant la commande suivante. Comme ça, tu laisses du temps au CPU pour faire d'autres tâches avant de se mettre en attente.

ericb59 :
Citation :
Ton initialisation des registres R#36-R#46 serait plus rapide via l'écriture séquentielle sur le port 9Bh

A moins que tu n'ai une autre solution ?


Actuellement, c'est la triple peine : le compilo doit charger tous tes paramètres dans la pile avant le call de ta fonction, puis il doit tout décharger avec le couteux registre IX, puis initialiser les registres du VDP un à un.
Si tu passes par une structure, tu auras toujours le cout du chargement des paramètres (dans la RAM (heap) plutôt que dans la pile), mais tu élimines le passage des paramètres sur la pile et tu peux utiliser un otir (ou mieux, une série de outi) pour écrire séquentiellement dans les registres du VDP depuis ta structure.
Ce soir je vais essayer de finir le clean de ma lib VDP ; je te dirai quand ça sera dispo sur GitHub si tu veux jeter un œil.

ericb59 :
Citation :
tu peux aussi passer de 14 à 12 T-states sur le check des flags CE et TR en utilisant un sra suivi d'un rla plutôt que des and

:hum Ca à le même effet sur le flag Z ?


Nop, dans ce cas il faut utiliser le flag C (retenu).

Code ASM :
        // Read  to check CE & TR flags
        in      a, (P_VDP_STAT)
        sra     a                    // check CE (bit#0)
        jp        nc, write_finished    // CE==0 ? command finished
        rla                            // check TR (bit#7)
        jp        nc, write_loop        // TR==0 ? VDP not ready
 


On est toujours ignorant avant de savoir.
Github    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 28/12/2020 à 14h22
Code ASM :
         in  a,(#0x99)        
         and #1
         jp z, exitHMMC       ; if CE = 1 Exit
         and #128
         jp nz, loopHMMC      ; if TR = 0 Loop


D'ailleurs, ton deuxième test est toujours faux car le premier AND met le bit#7 (TR) à 0.
Si ça marche quand même, c'est que ta boucle est plus lente que le temps d'écriture du VDP (29 cycles dans le pire des cas) donc en fait, il n'est pas nécessaire de check TR. :)

Donc tu peux laisser le premier AND (plus rapide qu'un SRA) et supprimer le second (qui ne sert à rien dans ton cas).


On est toujours ignorant avant de savoir.
Github    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 28/12/2020 à 15h33
Je viens de que dans ma fonction LMMC
j'ai ceci pour mes check !!

Code C :
 
loopLMMC:
         ld  a,#2
         call  statusLMMC
         rra
         jp nc, exitLMMC    ; is CE finish ?
         rla
         rla
         jp nc, loopLMMC    ; TR? transferring?
         inc hl 
         ld a,(hl)
         out  (#0x9b),a
         jp loopLMMC
  exitLMMC:
        xor a
        call  statusLMMC
        ei
        pop ix
        ret
  statusLMMC:
        out (#0x99),a
        ld  a,#0x8f
        out (#0x99),a
        in  a,(#0x99)
        ret
 


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 28/12/2020 à 18h46
Elle me semble très bizarre cette fonction :heink
Elle fonctionne bien ?
Je comprends pas l'intérêt de lire S#0 dans la boucle ; ça me semble super dangereux.


On est toujours ignorant avant de savoir.
Github    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 28/12/2020 à 19h38

Je voulais te montrer les RRA et RLA à la place du AND #1

Oui elle fonctionne.

aoineko :
Elle me semble très bizarre cette fonction :heink
Elle fonctionne bien ?
Je comprends pas l'intérêt de lire S#0 dans la boucle ; ça me semble super dangereux.


Tu parles de la partie Exit ?

Comme je te disais plus haut, la plupart des routines que j'ai trouvées font comme ça. Sans doute pour économiser de la place ?
Car c'est vrai que le denier IN ne sert à rien.


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 28/12/2020 à 19h45
Ca me semble ni court ni performant, mais peut-être que je rate un truc... :hum

Tous ces calls au milieu d'une boucle qui se veux rapide, c'est un contre-sens pour moi, mais bon.


On est toujours ignorant avant de savoir.
Github    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 21/02/2021 à 07h25
@aoineko :
Tu m’avais indiqué dans un autre sujet que tu avais réglé le bug des sons AYFX qui ne terminaient pas avec le player PT3.
J’ai oublié de te demander ce que tu avais fait au code...
Est-ce que tu as encore en tête la modif du code que tu as appliqué ?


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2694

Le 21/02/2021 à 11h20
ayFX et PT3 sont complètement indépendant pour leur update et n'entrent en concurrence que pour écrire dans le buffer qui sera envoyé aux registres du PSG à chaque frame.
Donc ton problème est certainement spécifique à ayFX.
De mon coté, j'ai ajouté une fonction callback (un hook) qui est appelé à la fin d'un son. Par défaut, c'est la fonction de Mute qui est appelé.
(cf. https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/ayFX/ayfx_player.c ligne 229)


On est toujours ignorant avant de savoir.
Github    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 12/01/2022 à 20h28
Ami du soir, bonsoir,

J'ai enfin retravaillé sur FUSION-C 1.3 la suite, après plusieurs mois de black-out.
J'ai finalisé ma première ROM viable en 48K que je vous partage ici ...
Alors c'est rien du tout d'interessant, c'est une compilation de deux jeux 16K que j'ai réunit en une seule ROM de 48K. Mais comme j'suis content je vous la poste ! ^^
Cela m'a permis de mieux comprendre le mécanisme des slots, et d'ajouter les routines qui vont avec.


pitfall48.ROM

A la prochaine Étienne. Edité par ericb59 Le 15/01/2022 à 11h34


banniere-ericb59e
Site web    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie