MSX Village forum

La Place des Développeurs Coder en C avec SDCC

ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5469

Le 11/02/2021 à 11h50

Reprise du message précédent

Ben, le gars demande comment faire une PAUSE, pas de faire une synchro...
Ma routine mets en pause le programme pour X frames...
Je ne comprend pas où tu veux en venir en fait...


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2680

Le 11/02/2021 à 12h00
Je peux me tromper, mais je pense pas qu'il souhaite mettre son MSX en pause et ne rien en faire pendant X frames. A mon avis, il veux juste un moyen de synchroniser sa boucle de gameplay pour qu'elle ait une durée fixe et consistante... sans pour autant s'empêcher d'utiliser ce temps pour faire des choses.


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

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1482

Le 11/02/2021 à 13h15
Citation :
How do I make a pause? I.e. in milliseconds or something, just so I can adjust the speed of the program.

Non, le gars veut juste une routine de pause standard, du genre wait(3) pour attendre 3 millisecondes.
Un bête FORI=0TO1000:NEXTI, quoi ...



MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5469

Le 20/02/2021 à 14h20
@aoineko : est-ce que tu as fait une routine pour déplacer l’adresse de la zone des sprites en. Ram ?
Si oui et si non peux tu expliquer la méthode et les contraintes ?
(Je m’y étais déjà mis, mais sans succès)

Merci d’avance ^^ Edité par ericb59 Le 20/02/2021 à 14h20


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2680

Le 20/02/2021 à 15h51
Tu as vraiment de la chance, je l'avais faite y a longtemps, mais je l'ai justement corrigé hier ! ^^
En fait, le trick, comme pour la plupart des zones dédiés au VDP en VRAM, c'est qu'en fonction du mode écran, il y a des particularités à tenir compte.
Voici mes fonctions :

Code C :
 
//-----------------------------------------------------------------------------
/// Set sprite attribute table address
/// @param        addr        VRAM address where to place the table (16 or 17-bits long depending on VDP_VRAM_ADDR definition)
///                            Address must be a multiple of 80h for MSX1 screen modes and  multiple of 200h for MSX2 ones.
void VDP_SetSpriteAttributeTable(VADDR addr) __FASTCALL
{
    g_SpriteAtributeLow = (u16)addr;
 
    u8 reg;
    reg = (u8)(addr >> 7);
    #if (MSX_VERSION >= MSX_2)
        switch(g_VDP_Data.Mode)
        {
        case VDP_MODE_GRAPHIC4:
        case VDP_MODE_GRAPHIC5:
        case VDP_MODE_GRAPHIC6:
        case VDP_MODE_GRAPHIC7:
            reg |= 0b111;
            break;
        };
    #endif
    VDP_RegWrite(5, reg);
    #if (VDP_VRAM_ADDR == VDP_VRAM_ADDR_17)
        reg = (u8)(addr >> 15);
        VDP_RegWrite(11, reg);
        g_SpriteAtributeHigh = addr >> 16;
    #endif
    addr -= 0x200;
    g_SpriteColorLow = (u16)addr;
    #if (VDP_VRAM_ADDR == VDP_VRAM_ADDR_17)
        g_SpriteColorHigh = addr >> 16;
    #endif
}
//-----------------------------------------------------------------------------
/// Set sprite pattern table address
/// @param        addr        VRAM address where to place the table (16 or 17-bits long depending on VDP_VRAM_ADDR definition)
///                            Address must be a multiple of 800h.
void VDP_SetSpritePatternTable(VADDR addr) __FASTCALL
{
    g_SpritePatternLow  = (u16)addr;
    #if (VDP_VRAM_ADDR == VDP_VRAM_ADDR_17)
        g_SpritePatternHigh = addr >> 16;
    #endif
 
    u8 reg = (u8)(addr >> 11);
    VDP_RegWrite(6, reg);
}
 


- VADDR correspond soit à un 16-bits pour MSX1 ou si on souhaite n'utiliser que 64K de VRAM, soit à un 32-bits pour accéder à 128K de VRAM.
- g_VDP_Data.Mode est une variable global qui stock le screen mode (tu peux utiliser l'info en RAM, SCRMOD (en 0xFCAF), si tu gardes le Bios).
- Je stock l'adresse des tables dans des variables (pas juste la valeur du registre correspondant) pour accélérer l'écriture en VRAM ultérieur. Toutes les fonctions de manipulation des sprites, utilisent ces valeurs.

Hier j'ai commencé un tableau pour lister les particularités des tables du VDP :

Comme c'était pour mon projet MSX1, je n'ai fini que la partie des screen modes MSX1 mais tu peux déjà voir tous les cas particuliers qu'il faut gérer niveau code.
Ma lib est à jours de tous ces cas ; je te préviendrais quand je commit-erai sur GitHub (surement demain soir) comme ça tu auras toutes mes fonctions comme réf.

EDIT : J'ai mis à jour l'image avec tous les screen modes. J'au aussi upload un PDF avec toutes les infos : ScreenModeTables.pdf


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: 5469

Le 20/02/2021 à 19h31
Merci :top
Je vais tacher de comprendre tout ça :) Edité par ericb59 Le 20/02/2021 à 19h31


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2680

Le 20/02/2021 à 23h45
Finalement, j'ai déjà tout commit sur GitHub.
Tu trouveras toutes les fonctions dans le module VDP : https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/vdp.c
Les fonctions en question :

Code C :
void VDP_SetLayoutTable(VADDR addr); // aussi connu sous le nom de Pattern Name Table (ou PNT)
void VDP_SetColorTable(VADDR addr);
void VDP_SetPatternTable(VADDR addr);  // aussi connu sous le nom de Pattern Generator Table (ou PGT)
void VDP_SetSpriteAttributeTable(VADDR addr);
void VDP_SetSpritePatternTable(VADDR addr);


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: 2680

Le 04/03/2021 à 23h41
@Eric, j'ai fait un crt0 pour une ROM 48K (pages 0~2) qui vient remplacer le système d'interruption par défaut : https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/crt0/crt0_rom48_isr.asm
L'entête de la ROM est en 4000h (page 1) et le code de boot s'occupe de switch les pages 0 et 2 pour qu'elles soient sur le slot de la ROM, et d'installer le code d'interruption au bon endroit (0038h).
Le gros avantage, c'est qu'ensuite tu n'as plus besoin de faire de switch et tu as la maitrise totale du contenu des adresses 0000h à BFFFh. :tchin
La contrepartie, c'est que tu ne peux évidemment plus utiliser les routines du Bios.
C'est pas gênant pour moi vu que toute ma lib est faite pour ne pas dépendre du Bios mais dans Fusion-C, il faudrait bien faire attention aux fonctions qu'on utilise.
En tout cas, ça pourrait surement intéresser certains de tes utilisateurs.


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: 5469

Le 05/03/2021 à 09h35
D'accord. Je te remercie :top

Ca veut dire que ca serait bien que je vire tout mes appels au Bios ça !
Encore du boulot en perspective :lol

Mais bon... là ca fait un mois que je bug, et que je ne produit rien ! Faut que ça cesse ! :( :siffle Edité par ericb59 Le 05/03/2021 à 09h40


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2680

Le 06/03/2021 à 12h03
ericb59 :
Ca veut dire que ca serait bien que je vire tout mes appels au Bios ça !
Encore du boulot en perspective :lol


Je trouve ça bien qu'on ait une lib C qui utilise le Bios. :top

Après, l'un empêche pas l'autre.
Ce que tu pourrais faire (plus tard), c'est juste marquer dans ta doc les fonctions compatibles ou non avec un ROM sans Bios.


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: 5469

Le 06/03/2021 à 13h11
aoineko :
[quote=ericb59]
Après, l'un empêche pas l'autre.
Ce que tu pourrais faire (plus tard), c'est juste marquer dans ta doc les fonctions compatibles ou non avec un ROM sans Bios.


Oui c'e see y ce que j'avais prévu de faire.

L'une des fonctions à faire sans Bios qui m'ennuie le plus c'est la fonction "Screen"
pour initialiser un mode écran.

J'ai vu que de ton côté tu utilises des fonctions distinctes suivant le mode écran à initialiser.

c'edt le plus simple , mais ça s'éloigne de ma philosophie.


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2680

Le 06/03/2021 à 14h27
Coté utilisateur, il n'y a qu'une fonction (https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/vdp.h) :
Code C :
void VDP_SetMode(const u8 mode) __FASTCALL;


Les différentes fonctions du module VDP sont "invisibles".
D'ailleurs, je pourrais n'avoir qu'une seule fonction et utiliser le numéro du screen comme index dans un tableau avec les valeurs d'initialisation des registres.


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: 2680

Le 23/11/2021 à 11h45
Hello,

Voici une (demi) bonne nouvelle pour les programmeurs C !
Les auteurs de SDCC ont changé leur système de passage de paramètres aux fonctions, ce qui peut offrir des gains de performance importants.

A partir de la version 4.1.12, les paramètres sont maintenant transmit par défaut aux fonctions via les registres (sans passer par la pile) dans certains cas :
- 1 paramètre 8/16/32 bits (registres A/HL/HLDE ; l'équivalent de __z88dk_fastcall )
- 2 paramètres 8 bit (registres A et L)
- 1 paramètre 8/16 bits + 1 paramètre 16 bit (registres A/HL et DE)

Si la fonction possède plus de paramètres, les autres sont passés par la pile.

Voici le listing de tous les prototypes de fonction qui passe maintenant entièrement par les registres (avec le nom du registre associé) :
Code C :
 
void f(char a);
void f(short hl);
void f(long dehl);
void f(char a, char l);
void f(char a, short de);
void f(short hl, short de);
 


Si vous êtes attentifs, il n'y a qu'une combinaison de 2 paramètres qui n'est pas géré entièrement via les registres, c'est quand le 1er est un 16 bits et le 2e un 8 bits.
Dans ce cas, le 2e paramètres est passé par la pile.

Si au début, je parlais de "demi" bonne nouvelle, c'est que s'il s'agit d'une grosse amélioration pour un utilisateur standard de SDCC, pour ceux qui utilisaient déjà __z88dk_fastcall , ça n'apporte pas beaucoup de chose en plus.
La véritable révolution, ça serait de pouvoir choisir dans quel registre passer chaque paramètre (pour optimiser le code et interfacer facilement les librairies en assembleur et les BIOS).
A priori c'est envisagé, mais pas à court terme.

En tout cas, merci à la team SDCC pour son super compilateur. :top


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: 5469

Le 24/11/2021 à 07h17
Intéressante nouveauté.
Merci pour ce point Aoineko.

Je me pose quand même des questions...

Est-ce que c'est totalement transparent ?
Y a t-il des précautions à prendre ? Dans le cas d'usage de routines ASM faut il sauver tous les registres dans la pile avant d'utiliser une routine ASM , et les de-poper avant la sortie ?
Est-ce que les anciennes sources fonctionnent sans modification? Edité par ericb59 Le 24/11/2021 à 07h20


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2680

Le 24/11/2021 à 10h08
Pour ceux qui ne codent qu'en C, ces modifications sont totalement transparentes.

Pour nous autre bidouilleur qui avons des tas de fonctions dont le corps est en assembleur en ligne, il faut faire attention effectivement.
Déjà, tu as un flag de compilation –-sdcccall 0 pour revenir à l'ancienne convention d'appel des fonctions et tu peux appliquer la nouvelle à la main, fonction par fonction, avec la directive __sdcccall(1) . Comme ça, pas de soucis.

Ou bien tu peux faire l'inverse et laisser globalement la nouvelle convention d'appel et la désactiver pour les fonctions ou tu sais que ça ne va pas marcher avec un __sdcccall(0) .
La 2e est bien meilleure en matière de performance, mais il faut faire attention à ne pas oublier de fonctions. ^^

Personnellement, ce que je compte faire pour ma lib :
  1. Compiler une première fois avec –-sdcccall 0 juste pour vérifier qu'il n'y a pas de soucis autre que le changement de convention d'appel.
  2. Remettre la nouvelle convention d'appel et la désactiver avec __sdcccall(0) sur toutes les fonctions avec de l'assembleur.
  3. Retirer __sdcccall(0) sur les fonctions qui ont déjà __z88dk_fastcall vu que c'est le même comportement (et du coup, retirer aussi __z88dk_fastcall ).
  4. Enfin, le plus long, réécrire les fonctions en assembleur, une par une, pour utiliser les registres plutôt que la pile et retirer le __sdcccall(0) quand c'est fait.

Entre chaque étape, il est important non seulement de compiler, mais surtout de bien tester le résultat car les bugs en assembleur ne se détectent généralement pas à la compilation.
Personnellement, j'ai une batterie de samples pour chaque partie de ma lib (VDP, PSG, input, ...) et je les testerai tous entre chaque étape pour être sûr.

Au final, le gain de performance devrait être assez significatif. :top


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: 5469

Le 24/11/2021 à 14h36
Oui on va sans doute gagner de la vitesse mais c'est beaucoup de contraintes en attendant !

Toutes nos routines spécifiques sont en ASM, du coup y a quand même pas mal de boulot pour les remettre en conformité avec ce protocole.
:|

J'suis fatigué rien qu'à y penser ! :sick


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