MSX Village forum

La Place des Développeurs Projet GOS Et oui, encore trop d'ambitions ^^

aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 13/01/2021 à 17h07

Reprise du message précédent

Vu qu'il n'y a pas (à ma connaissance) de hook pour la de gestion des H-Blank, je check le flag qui le gère dans le hook H.KEYI.
Le problème c'est que dans le mode d'interruption par défaut (IM1), toutes les interruptions passe par le même code (38h) donc la quantité de code qu'il y a entre le début de l'interruption et l'exécution du hook H.KEYI et le même que l'interruption ait été déclenché par le H-Blank ou le V-Blank.
Je sais pas si en mode IM2 le VDP nous renverrai un code différent pour ces deux interruptions ?
Si c'est le cas, on pourrait géré ces cas séparément sans que la gestion de l'un ne ralentisse celle de l'autre.
L'autre solution c'est de remplacer le code de gestion en 38h (c'est mon but) pour avoir quelque chose de plus optimal pour un jeu (en gros, ne check que les flags du VDP).


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

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10731

Le 13/01/2021 à 17h10
pas testé sur MSX1 car quand j'ai mis le programme dans une flashrom avec OPF en le lançant par reset écran noir

j'ai vu ensuite que j'avait vérolé ma compactflash :( illisible

du coup formatage et remis les programmes dedans

je vais en dédier une petite uniquement aux test

celle que j'ai sera pour les jeux en ROM uniquement ;)


:noel
Site web    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 13/01/2021 à 17h32
aoineko :
Vu qu'il n'y a pas (à ma connaissance) de hook pour la de gestion des H-Blank, je check le flag qui le gère dans le hook H.KEYI.
Le problème c'est que dans le mode d'interruption par défaut (IM1), toutes les interruptions passe par le même code (38h) donc la quantité de code qu'il y a entre le début de l'interruption et l'exécution du hook H.KEYI et le même que l'interruption ait été déclenché par le H-Blank ou le V-Blank.

Il n'y a pas tant de code que ça avant l'appel du hook. Voici le code BIOS appelé par $38 :
PUSH HL
PUSH DE
PUSH BC
PUSH AF
EXX
EX AF,AF'
PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH IY
PUSH IX
CALL H.KEYI
IN A,(VDP.SR)
AND A
JP P,INTRET
CALL H.TIMI


Comme tu peux le voir H.KEYI est appelé tout de suite (et est donc appelé pour toute interruption, VDP ou non). C'est effectivement le bon hook pour les interruptions HBLANK (le hook H.TIMI n'est appelé uniquement que dans le cas d'une interruption VBLANK du VDP).

Déjà, la sauvegarde de tous les registres (et leur restauration à la sortie) prends 266 cycles, soit un peu plus d'une ligne ... Edité par Metalion Le 13/01/2021 à 17h36


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)
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 13/01/2021 à 18h33
Après, faut ajouter le check du bit #0 de S#1 dans mon hook H.KEYI, le saut vers ma fonction de gestion du H-Blank puis le code assembleur de cette fonction C.
Elle est pas très compliqué donc ça explique difficilement les 4 lignes de décalage en version ROM... et encore plus difficilement les 10 lignes de décalage sous DOS ! :heink
J'ai essayé de retirer tous les updates que je faisais durant la frame pour faire bouger mes sprites, mais ça change absolument rien (de toute façon, je minimise vraiment les temps de DI).
Du coup... aucune idée d'où peu venir se décalage variable en fonction de l'OS... :moue

Pour info, ma fonction C qui gère le H-Blank (ça me semble pas trop dégueu pour du code compilé ^^)
Code ASM :
_HBlankHook::
    ld    l, #0x00
    call    _VDP_SetColor ; VDP_SetColor(0);
    ld    a,(#_g_Phase + 0)
    or    a, a
    jr    NZ,00102$ ; if(g_Phase == 0)
    ld    l, #0x03
    call    _VDP_SetSpriteFlag ; VDP_SetSpriteFlag(VDP_SPRITE_SIZE_16 + VDP_SPRITE_SCALE_2);
    ld    l, #0x71
    call    _VDP_SetHBlankLine ; VDP_SetHBlankLine(SPRITE_8_LINE);
    ld    iy, #_g_Phase
    inc    0 (iy) ; g_Phase++;
    ld    l, #0x0c
    jp    _VDP_SetColor ; VDP_SetColor(12);
00102$:
    ld    l, #0x00
    call    _VDP_SetSpriteFlag ; VDP_SetSpriteFlag(VDP_SPRITE_SIZE_8);
    ld    l, #0x06
    jp    _VDP_SetColor ; VDP_SetColor(6);
00104$:
    ret


Les sprites sont en 16x16 scale 1 dans la partie haute de l'écran, 16x16 x2 au milieu et 8x8 x1 en bas.


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

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 13/01/2021 à 19h54
4 lignes, cela fait 912 cycles.
Si on retire les 266 cycles pour les registres, il reste 646 cycles soit 80 instructions (en moyenne).
Ce n'est pas grand chose et cela peut aller très vite, donc cela ne m'étonne pas fondamentalement.

10 lignes sous DOS, c'est un peu plus long effectivement, mais je ne connais pas bien ce que fait l'ISR du DOS.
Ceci dit, l'avantage du DOS, c'est qu'il te reste toujours la possibilité de réécrire toi-même l'ISR pour qu'elle soit plus rapide.



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)
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 13/01/2021 à 23h23
Metalion :
Ceci dit, l'avantage du DOS, c'est qu'il te reste toujours la possibilité de réécrire toi-même l'ISR pour qu'elle soit plus rapide.


C'est bien mon objectif à moyen termes.
J'attends d'avoir complété ma lib (ce qui est pas loin d'être le cas), puis je couperai le cordon ombilical avec le 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: 5566

Le 14/01/2021 à 09h59
@aoineko j'ai vu dans ta lib, des fonctions qui font appel au BIOS pour récupérer des infos tels que la taille des sprites et autres petites choses qui sont en fait dispo dans les variables système.
Mais je suppose qu'il y a une raison pour laquelle tu as gardé ces fonctions dans ta lib. ^^

je mets une liste ici, au cas ou ça serve à quelqu'un
Code C :
 
 
 
#define         IsVsync() ((VDPstatusNi( 0 ) & 0x80) != 0)
#define         IsHsync() ((VDPstatusNi( 1 ) & 0x01) != 0)
 
#define             _SpriteOn           (((*(char *)0xFFE7) >> 1) & 0x01)       // Returns 0 when sprites are activated, 1 when sprites are desactivated
#define             _SpriteSize         (((*(char *)0xF3E0) >> 1) & 0x01)       // Returns 0 when sprite size is 8x8, 1 when size is 16x16
#define             _SpriteMag          (((*(char *)0xF3E0)) & 0x01)            // Returns 0 when Mag is simple, 1 when sprite are double
#define             _ActivePage         (*(char *)0xFAF6)                       // Returns the active VRAM Page (MSX2)
#define             _DisplayPage        (*(char *)0xFAF5)                       // Returns the displayed VRAM Page (MSX2)
#define             _VDPfreq            (((*(char *)0xFFE8) >> 1) & 0x01)       // Returns 1 for 50 Hz, 0 for 60 Hz (MSX2)
#define             _VDPlines           (((*(char *)0xFFE8) >> 7) & 0x01)       // Returns 1 for 212 lines, 0 for 192 lines (MSX2) 
#define             _ForegroundColor    (*(char *)0xF3E9)                  // Returns the foreground color
#define             _BackgroundColor    (*(char *)0xF3EA)                  // Returns the background color 
#define             _BorderColor        (*(char *)0xF3EB)                  // Returns the border color 
#define             _ScreenMode         (*(char *)0xFCAF)                  // Returns the actual Screen mode
#define             _SpritePatternAddr  (*( (volatile unsigned int*)(0xF926)))                 // Returns Default Sprite Pattern table Address in Vram for the current screen mode
#define             _SpriteAttribAddr   (*( (volatile unsigned int*)(0xF928)))                 // Returns Default Sprite attributs table Address in Vram for the current screen mode
#define             _SpriteColorAddr    ((*( (volatile unsigned int*)(0xF928)))-512)           // Returns Default Sprite colors table Address in Vram for the current screen mode (MSX2 & upper only)
#define             _WidthScreen0       (*(char *)0xF3AE)                                      // Returns the actual Screen width for screen mode 0
#define             _WidthScreen1       (*(char *)0xF3AF)                                      // Returns the actual Screen width for screen mode 1
#define             _Time               (*(unsigned int *)0xFC9E)                              // Returns Current MSX TImer 0..65535
#define             _FusionVer          (char)13                                               // Fusion-C Version (Divide by 10 to understand version number)
#define             _FusionRev          (unsigned int)11211                                    // Fusion-C last Revision Date First digit is number of year after 2019. 2 next digits is day of revision, 2 last digits are month of revision 
 
 
 


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 14/01/2021 à 11h10
Toujours la même raison... pouvoir se débarrasser un jour du Bios. ;)

Mais je vais laissé la possibilité de garder le Bios (ça peut être pratique pour certain programme) donc la plupart des variables de la Work area de l'OS seront toujours utilisables.
Comme pour beaucoup de chose dans ma lib, j'ajouterai un define qui dira au moment du build si on garde le Bios ou si on le remplace (ce qui modifiera le crt0 et les fonctions disponibles).

Mais pour ce qui est du traitement du VDP, je pense que je vais laissé uniquement ma version dans tous les cas.


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

Le 17/01/2021 à 03h37
C'est surtout pour Ericb, mais je post ici au cas ou ça puisse également intéresser quelqu'un d'autre.
J'ai fini ma lib de Print et tout est publié sur GitHub : https://github.com/aoineko-fr/cmsx
Voici les fonctionnalités :
- 3 modes de rendu : RAMtoVRAM, VRAMtoVRAM et Sprites.
- 2 modes couleurs : monochrome ou 1 couleur par ligne.
- 2 effets : shadow (ombrage) et outline (détourage).
- Taille de pattern variable (8 px max en largeur)
- Screen modes supportés : Screen 5, 6, 7 et 8.

Le tout est configurable via des defines qui permettent d'avoir, selon les besoins, soit un code bien optimisé, soit beaucoup de fonctionnalités.


Il me reste un truc bizarre avec les sprites à régler.
Pour les tables de pattern/attribute, j'ai parfois des soucis quand je les places au-delà de 10000h (même si je respecte le multiple spécifique à chaque table).
Faut que je vois s'il a des limitations que je ne connais pas ou si c'est juste un bug dans mon code.

Ensuite je vais passer au player music/sfx et je devrais avoir tout ce qu'il me faut pour le projet GOS.


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

Le 17/01/2021 à 09h04
Super ! :| :top

T'as oublié une option :
La redéfinissions des caractères dans les mode 0 à 4.
Bon, c'est trivial, il suffit de faire un Copy Ram to Vram, c'est juste pour chipoter :p


banniere-ericb59e
Site web    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 17/01/2021 à 10h46
aoineko :
Il me reste un truc bizarre avec les sprites à régler.
Pour les tables de pattern/attribute, j'ai parfois des soucis quand je les places au-delà de 10000h (même si je respecte le multiple spécifique à chaque table).
Faut que je vois s'il a des limitations que je ne connais pas ou si c'est juste un bug dans mon code.

J'ai déjà eu ce problème ... Impossible de placer les tables au delà de 10000h, ça plantait.
Et je n'ai jamais trouvé la cause. J'ai vérifié tellement de fois les valeurs des registres que ça me rendait fou.
Finalement, j'ai abandonné, et j'ai réorganisé la VRAM pour pouvoir mettre ces tables avant 10000h.


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)
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 17/01/2021 à 10h51
ericb59 :
T'as oublié une option :
La redéfinissions des caractères dans les mode 0 à 4.


J'avance en fonction de mes besoins. Et pour le moment j'ai pas besoin des modes textes. ^^

Au fait, par rapport aux questions sur la vitesse des routines RAM to VRAM, j'ai trouvé une solution plus rapide : Je décode un caractère complet dans un buffer en RAM avant de l'envoyer d'un coup en VRAM. Je comprends pas vraiment pourquoi c'est plus rapide, mais c'est le cas. :p


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

Le 17/01/2021 à 11h20
Citation :
Je décode un caractère complet dans un buffer en RAM avant de l'envoyer d'un coup en VRAM.

J'avais testé ça aussi, en utilisant HMMC, mais j'ai pas trouvé que c'était plus rapide. Avec une routine RamToVram, c'est peut être plus rapide, mais dans ce cas, comment formater les données pour avoir un seul bloc de 8x8 non linéaire ?


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 17/01/2021 à 13h46
Metalion :
J'ai déjà eu ce problème ... Impossible de placer les tables au delà de 10000h, ça plantait.
Et je n'ai jamais trouvé la cause. J'ai vérifié tellement de fois les valeurs des registres que ça me rendait fou.
Finalement, j'ai abandonné, et j'ai réorganisé la VRAM pour pouvoir mettre ces tables avant 10000h.


Argh... ça sape un peu mes espoirs.
Surtout que j'ai vérifié que la bonne valeur était bien envoyé au VDP (via le debugger de OpenMSX).
Et j'ai rien trouvé dans la doc du V9938 non plus.

Mais bon, je vais continuer à creuser. ;)

ericb59 :
J'avais testé ça aussi, en utilisant HMMC, mais j'ai pas trouvé que c'était plus rapide. Avec une routine RamToVram, c'est peut être plus rapide, mais dans ce cas, comment formater les données pour avoir un seul bloc de 8x8 non linéaire ?


Avec HMMC, ta source doit être linéaire ; c'est la commande VDP s'occupe de split les datas par lignes.
Du coup, tu as juste besoin de décoder ton pattern dans un buffer de taille W x H avec :
- W qui représente le nombre d'octets d'une ligne ; donc ça dépend de la largeur du pattern et du nombre de bit-par-couleur du mode. Par exemple, pour une font avec des patterns de 6 points de large pour le mode G4 (Screen 5) qui est en 4 BPC, tu as besoin de 3 octets par ligne,
- H qui représente le nombre de lignes (pas forcement 8 ; sauf pour le mode d'affichage via les sprites).
Ensuite un seul HMMC sur ce buffer suffit à placer les données d'un caractère en VRAM.

J'utilise la technique à la fois pour afficher du texte sur l'écran visible, et aussi pour mon mode d'affichage VRAMtoVRAM to initialiser la font en VRAM.

A noter aussi que j'utilise la commande VDP PSET pour l'affichage pour les modes ou j'ai besoin de la transparence (notamment les effets de Shadow/Outline).
J'avais essayé avec LMMC, mais c'est trop lourd à mettre en place (cette commande fonctionne avec 1 octet par couleur quelque soit le mode graphique) et le gain était minime.

EDIT : Ah, je crois que j'ai mal compris ta question. Si tu utilises une fonction d'écriture "directe" vers la VRAM, elle ne peux pas gérer les splits par ligne. C'est tout l'intérêt de HMMC. Donc dans le cas de l'écriture directe, le mieux est d'envoyer les paquets ligne par ligne. Même si la copie est aussi rapide via une écriture directe (voir p'être plus rapide), tu perds beaucoup de temps en setup et en call de ta fonction à chaque ligne. C'est surement pour cette raison qu'un HMMC unique est (légèrement) plus rapide.


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

Le 17/01/2021 à 15h00
Oui, oui, je sais utiliser HMMC.
Je l’avais fait pour un affichage caractère par caractère.
Mais je ne gagnais pas de temps comparé à l’affichage ligne par ligne du CopyRam2Vram... ce qui m’avait surpris !

La différence est peut être sur le setup de ta commande HMMC, je vais regarder comment tu l’a mise en place.
Pour le mode transparent, je l’avais fait LMMC, c’est un peut plus lent que HMMC.


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2907

Le 17/01/2021 à 15h24
ericb59 :
Pour le mode transparent, je l’avais fait LMMC, c’est un peut plus lent que HMMC.


LMMC est surtout lent pour les modes 4-bits par couleur (comme les screen 5 et 7) et le mode 2-bits par couleur (comme le screen 6) car on doit envoyer 2 et 4 fois plus de data respectivement.

Metalion :
J'ai déjà eu ce problème ... Impossible de placer les tables au delà de 10000h, ça plantait.


Dans mon cas, c'était un bug dans mon code (un shift d'une mauvaise valeur). ^^

Par contre, j'ai découvert un truc marrant.
Je pensais que les bit#7 à 9 de l'adresse de SAT devaient toujours être à 1 sur le V9938 pour que les sprites s'affichent.
C'est bien le cas du bit#9, mais les bits bit#7 et 8 ont un comportement différent ; ils semble modifier la façon dont est géré les couleurs des sprites.
En tout cas, en jouant avec des bits (pas de vilain jeu de mot ;) ) on a des effets intéressants.
Je vais creuser la question pour voir si c'est exploitable ou pas.


On est toujours ignorant avant de savoir.
Github    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie