MSX Village forum

La Place des Développeurs Première Mondiale : La première Rom avec Fusion-C !

aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2904

Le 10/12/2020 à 00h40

Reprise du message précédent

Yep, dans ce cas, le mieux est d'avoir des structures en mémoire qui correspondent à celle en VRAM et d'envoyer les données par paquet par HMMC (ou via l'écriture séquentielle).

C'est du détail, mais pour tes 4 outi finaux, tu devrais faire le di juste avant le premier, et le ei juste avant le dernier pour limiter le temps ou tu désactives les interruptions. Depuis que je fais mumuse avec le HBlank, je me rends compte de l'importance de limiter au maximum les temps de désactivations des interruptions (mais ça vaut aussi pour la musique par ex.).


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

Le 11/12/2020 à 17h51
Tiens, je viens de découvrir un truc relou avec SDCC.
Dans certain cas, il génère du code anormalement lourd quand on accède à une variable globale.
Code ASM :
 
    ld  iy, #_g_MyVar ; 14 cycles
    ld  a, 0 (iy)     ; 19 cycles
 

Au lieu d'un simple :
Code ASM :
 
    ld  a, (#_g_MyVar + 0) ; 13 cycles
 


33 cycles ou lieu de 13. :(
Heureusement, j'ai trouvé un moyen de l'obliger à généré le bon code : il "suffit" de dire au compilo que notre variable est une "valeur pointée par une adresse" et utiliser en C *((char*)&g_MyVar) plutôt que g_MyVar .
C'est un peu lourd à écrire (même encapsulé dans une macro), mais pour 20 cycles gagnés à chaque lecture de mes variables, je prends. :)
J'essaye de voir du coté de SDCC s'il y a une solution propre (notamment via le peephole) mais en attendant c'est mieux que rien.


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 16/12/2020 à 19h25
Peep hole.
Ca devrait le faire ça ...

Code TEXT :
 
replace restart{
    ld    iy,%1
    ld    a,0 (iy)
} by {
    ld    a, (%1+0)
}
 


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2904

Le 16/12/2020 à 20h10
Si iy est réutilisé plus loin dans la fonction ça va faire un beau bug... :gne


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 16/12/2020 à 20h31
aoineko :
Si [font= courier new]iy[/font] est réutilisé plus loin dans la fonction ça va faire un beau bug... :gne


De toute façon avec SDCC 4.07 je ne suis pas certain que l'option --peep-file fonctionne :hum

J'ai essayé avec ce fichier d'optimisation, mais je n'ai remarqué aucune différence avec ou sans ...

peep.txt


banniere-ericb59e
Site web    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5566

Le 16/12/2020 à 20h37
J'ai aujourd'hui réussi à faire ma première Rom 48K avec Fusion-C :)

En fait, j'utilise exactement le même crt0 que pour la rom 32K

Dans mon code je force un bloc de données à se placer en 0x0000
Code C :
const  unsigned char __at(0x00)  datas[] = ... 


Puis avec 2 routines ASM, j'échange la Page 0 que vois le Z80 soit avec le Bios, soit avec la page 0 de la ROM.
et vice versa ...

Par contre quand le Bios n'est pas présent, aucune interruption n'est permise.
Mais doit y avoir moyen de feinter :hum Edité par ericb59 Le 16/12/2020 à 20h39


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2904

Le 16/12/2020 à 21h34
A ma connaissance, la seule feinte possible c'est d'avoir le code d'interruption à l'adresse 0038h dans ta ROM.

Perso, pour ma ROM 48K, j'ai laissé la page 0 sur le Bios par défaut. Du coup, cette page de la ROM ne sert que pour stocker des datas.
Pour l'utiliser il faut :
- désactiver les interruptions,
- switch la page 0 sur la ROM,
- copier ce dont on a besoin en RAM,
- switch la page 0 sur le Bios,
- réactiver les interruptions,
- (copier les données RAM en VRAM si besoin).
C'est bien pour charger des graphismes au début d'un niveau par ex., mais c'est pas vraiment utilisable en plein gameplay.

Mais mon but à terme c'est de remplacer complètement le Bios (pour avoir un code d'interruption bcp plus léger et sans certains défauts de celui de base).
Quand ça sera fait, toutes mes ROM pourront commencer en page 0 (le code d'interruption sera placé en 0038h).


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/12/2020 à 09h37
aoineko :
A ma connaissance, la seule feinte possible c'est d'avoir le code d'interruption à l'adresse 0038h dans ta ROM.


Oui c'est bien à cela que je pensais.
Mais quel est le code à mettre dans la ROM ?
Une copie de la fonction KEYINT du bios ?

La commande KEYINT en 0x38 est en fait un
JP #0cx0c3c

Et à cet endroit on a toute une routine... qui fait je ne sais pas trop quoi... son travail... quoi...
Code ASM :
 
;       Subroutine      KEYINT
;       Inputs          ________________________
;       Outputs         ________________________
;       Remark          Entry at the same adres as MSX1
J0C3C:  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
        CALL    C1479
        JP      P,J0D02
        CALL    H.TIMI
        EI
        LD      (STATFL),A
        AND     20H     ; " "
        LD      HL,TRPTBL+11*3
        CALL    NZ,C0EF1
        LD      HL,(INTCNT)
        DEC     HL
        LD      A,H
        OR      L
        JR      NZ,J0C73
        LD      HL,TRPTBL+17*3
        CALL    C0EF1
        LD      HL,(INTVAL)
J0C73:  LD      (INTCNT),HL
        LD      HL,(JIFFY)
        INC     HL
        LD      (JIFFY),HL
        LD      A,(MUSICF)
        LD      C,A
        XOR     A
J0C82:  RR      C
        PUSH    AF
        PUSH    BC
        CALL    C,C1131
        POP     BC
        POP     AF
        INC     A
        CP      03H     ; 3
        JR      C,J0C82
        LD      HL,SCNCNT
        DEC     (HL)
        JR      NZ,J0D02
        IF INTHZ EQ 60
        LD      (HL),2                  ; scanfrequency 2*1000/60 = 33 ms
        ELSE
        LD      (HL),1                  ; scanfrequency 1*1000/50 = 20 ms
        ENDIF
        XOR     A
        CALL    C1202
        AND     30H     ; "0"
        PUSH    AF
        LD      A,01H   ; 1
        CALL    C1202
        AND     30H     ; "0"
        RLCA
        RLCA
        POP     BC
        OR      B
        PUSH    AF
        CALL    C121C
        AND     01H     ; 1
        POP     BC
        OR      B
        LD      C,A
        LD      HL,TRGFLG
        XOR     (HL)
        AND     (HL)
        LD      (HL),C
        LD      C,A
        RRCA
        LD      HL,TRPTBL+12*3
        CALL    C,C0EF1
        RL      C
        LD      HL,TRPTBL+16*3
        CALL    C,C0EF1
        RL      C
        LD      HL,TRPTBL+14*3
        CALL    C,C0EF1
        RL      C
        LD      HL,TRPTBL+15*3
        CALL    C,C0EF1
        RL      C
        LD      HL,TRPTBL+13*3
        CALL    C,C0EF1
        XOR     A
        LD      (CLIKFL),A
        CALL    C0D12
        JR      NZ,J0D02
        LD      HL,REPCNT
        DEC     (HL)
        JR      NZ,J0D02
        LD      (HL),1
        LD      HL,OLDKEY+0
        LD      DE,OLDKEY+1
        LD      BC,11-1
        LD      (HL),0FFH
        LDIR
        CALL    C0D4E
J0D02:  POP     IX
        POP     IY
        POP     AF
        POP     BC
        POP     DE
        POP     HL
        EX      AF,AF'
        EXX
        POP     AF
        POP     BC
        POP     DE
        POP     HL
        EI
        RET
 


Je vais essayer de mettre ca dans ma page 0 de ROM 48K, pour voir si ca continue de faire tourner les interruptions.

Je suis bien conscient que tout ceci à déjà été questionné, pensé, réfléchi, plus ou moins expliqué depuis belle lurette... Mais comme on ne trouve pas de document clair et précis sur "comment c'est t'y qu'on fait"... et bien on ré-invente la roue à chaque curieux qui veut mettre les pieds dans le plat :p :(
Edité par ericb59 Le 17/12/2020 à 11h07


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2904

Le 17/12/2020 à 16h52
Voici un pseudo code d'après les infos fournis par Grauw sur son site :

Code TEXT :
- Stack all registers
- Invoke H.KEYI hook
- Read VDP status register S#0
if(Turbo R)
    - Check PAUSE key
- Check VDP interrupt
if(VDP interrupt)
    - Invoke H.TIMI hook
    - Enable Interrupts (EI)
    - Save S#0 in STATFL
    - ON INTERVAL GOSUB
    - Increase TIME variable (JIFFY)
    - Handle PLAY
if(JIFFY % 2 == 0) // Every second VDP interrupt
    - Keyboard scan
    - Processing keys
    - ON STRIG GOSUB
    - Key repetition
- Restore all registers
- Enable Interrupts (EI)
- RETurn from Interrupt (RETI)


Le problème c'est qu'il y a plein de call qui sont fait à partir de ce code vers du code situé ailleurs.
Il faudrait donc embarquer tout ces bouts de code à leur bonne adresse.
C'est pas impossible, mais de toute façon, perso, je préfère largement avoir mon propre code optimisé pour les jeux.
(et ça évitera quelques incohérences qu'on est obligé d'avoir dans nos libs à cause de ce code d'interruption par défaut comme le fait de devoir toujours reset le registre VDP de status à 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: 5566

Le 17/12/2020 à 17h25
Oui j’ai passé une grosse partie de la journée à décortiquer cette partie du Bios, et à rassembler toutes les sous routines qui vont avec l’interruption... c’est du boulot !!
Après on est sans doute pas obligé de. Gérer toutes les routines, comme celles de la Fonction Play et du clavier.

Pour le reste de ton commentaire, j’ai du mal à concevoir que tu veuille remplacer le Bios par tes propres routines. C’est un boulot dingue :|
J’imagine que si c’est efficace, quelqu’un d’autre aura déjà expérimenté la chose ? :hum

J’ai toujours lu ici et ailleurs que pour préserver la compatibilité du code avec tous les MSX il fallait utiliser le Bios.
J’ai même eu des réflexions (pas désobligeantes) sur les routines hors Bios de Fusion-c que j’ai implantées ici ou là , alors que l’equivalent existait dans le Bios...
Quid ? :hum Edité par ericb59 Le 17/12/2020 à 17h37


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2904

Le 17/12/2020 à 18h38
A partir du moment ou tu utilises directement le PPI, le VDP et le PSG via les ports, tu n'es déjà plus dans l'utilisation "pure" du Bios.
D'un autre coté, à priori, il n'y a aucun cas d'incompatibilité connu à utiliser ces périphériques sans passer par le Bios (à part une obscure carte graphique MSX2 pour les MSX1 brésilien).
Du coup, la question pourrait plutôt être « pourquoi utiliser le Bios ? ».
Ca peut avoir du sens dans l'approche généraliste de ta lib, mais pour moi qui ne m'intéresse qu'aux jeux, je n'ai aucun besoin du Bios (les accès via les ports sont suffisants).
Au contraire, il prends des ressources (RAM et temps CPU) que je veux récupérer pour mes jeux.

Et pour en revenir au code d'interruption, la version que je compte faire ne sera pas compliqué car... elle ne fera que ce dont j'ai besoin. :)
Dans un premier temps, elle ne gérera que les V-Blank et les H-Blank (je préfère gérer les inputs clavier/joystick coté jeu).

La où ça deviendra plus coton, c'est quand je m'attaquerai à la gestion du disque.
Mais pour le moment j'en ai pas besoin et de toute façon, les ROM du MSX sont toujours accessibles via les accès inter-slot si besoin.


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