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

Le 08/01/2021 à 15h23

Reprise du message précédent

OK. Donc tu as 2 jeux d'instructions MSX1 et MSX2.

Citation :
Déjà, le plus important à savoir c’est que quand l’affichage est désactivé, il n’y a aucune limitation de vitesse d’écriture/lecture

Question, comment tu coupes l'affichage sur MSX 1 ? :gne


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2576

Le 08/01/2021 à 17h28
ericb59 :
OK. Donc tu as 2 jeux d'instructions MSX1 et MSX2.


Pas vraiment. Toutes les fonctions sont utilisables sur toutes les MSX. Par contre, si tu utilises une copie rapide sur MSX sans désactiver l'affichage, ça va merder.
Comme d'hab, je préfère la rapidité et la flexibilité aux barrières de sécurité. ;)


ericb59 :
Question, comment tu coupes l'affichage sur MSX 1 ? :gne


Comme sur MSX2 avec le flag BL (bit#6) du registre VDP #1.

EDIT : Tu peux aussi utiliser les deux routines suivantes en Main-ROM :

Code TEXT :
#define DISSCR 0x0041 // Inhibits the screen display
#define ENASCR 0x0044 // Displays the screen


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

Le 08/01/2021 à 17h58
Ha ! J’étais persuadé qu’on ne pouvais désactiver l’affichage que sur msx2 :siffle


banniere-ericb59e
Site web    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5450

Le 08/01/2021 à 19h35
DIs moi, as tu fait ou prévu de faire des routines pour trouver dans quel slot est la RAM, et swapper les pages de RAM pour disposer de plus d'espace ?


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2576

Le 08/01/2021 à 20h24
Oui, on en avait discuté sur le Village y a qq semaines.
On m'a conseillé la manière forte : écriture/lire sur chaque page de chaque slot/sous-slot pour voir si c'est de la RAM.
(normalement en écrivant au début de la page, y a pas de risques d'écraser un truc important)
J'ai fait une fonction pour un des mes samples (test-cases), mais je l'ai pas intégré à ma lib.

Par contre, je comprends pas ce que tu veux faire. Quel que soit le support, au démarrage, le système sélectionne déjà toute la RAM qu'il peut.
- DOS : RAM sur les pages 0-3
- Basic BIN : Main-ROM sur les pages 0-1 + RAM sur les pages 2-3
- ROM 4000h : Main-ROM sur la page 0 + Cartouche sur la page 1 + RAM sur les pages 2-3
- ROM 8000h : Main-ROM sur la page 0 + Je sais pas quoi sur la page 1 (RAM ? Sub-ROM ?) + RAM sur la page 3

Après, c'est au programme de switcher les pages au besoin.
De ce que j'ai compris (même si ça m'étonne un peu), la seul RAM accessible par switch de page (en dehors des memory mapper donc), est celle qui se trouve sur le slots sélectionné au démarrage dans la page 3 (tous les supports).
Un simple accès au PPI (ou doit y avoir une variable/fonction Bios) permet donc de récupérer ce slot.


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

Le 08/01/2021 à 20h42
Voici la fonction que j'utilise pour récupérer le slot d'une page.

Code C :
#define P_PPI_A 0xA8    // Port to access the primary Slot selection register
__sfr __at(P_PPI_A) g_PortPrimarySlot;
#define M_EXPTBL    0xFCC1    // Slot expansion
const u8 __at(M_EXPTBL) g_EXPTBL[4];
#define M_SLTSL    0xFFFF    // Access address to selection register of secondary slots
const u8 __at(M_SLTSL) g_SLTSL;
 
inline u8 GetPageSlot(u8 page)
{
    u8 slot = (g_PortPrimarySlot >> (page * 2)) & 0x03;
    if(g_EXPTBL[slot] & 0x80)
    {
        slot |= SLOT_EXP;
        slot |= (((~g_SLTSL) >> (page * 2)) & 0x03) << 2;
    }
    return slot;
}


C'est pas du tout optimisé mais ça fonctionne. :)
Un GetPageSlot(3) te donnera le slot ID de la RAM sous la forme :
Code C :
// ExxxSSPP
// │   ││└┴─ Primary slot number (00-11)
// │   └┴─── Secondary slot number (00-11)
// └──────── Expanded slot (0 = no, 1 = yes)


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

Le 08/01/2021 à 20h56
Ce que je veux dire c'est ceci.
Example :
Pas de memory mapper.
UN MSX de 64K pas de lecteur Floppy
On a une ROM de 32 K en SLOT 1
Donc on va avoir
Page 0 -> BIOS - SLOT 0
Page 1 -> ROM - SLOT 1
Page 2 -> ROM - SLOT 1
Page 3 -> RAM - SLOT ???

1) Comment sait-on sur quel Slot se trouve la RAM
2) Comment je switch cette première page de 16K RAM avec l'une des 3 autre pages de RAM Dispo sur ce MSX ?




Edit : Avec ta routine ci-dessus ? Edité par ericb59 Le 08/01/2021 à 20h57


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2576

Le 08/01/2021 à 21h08
Au démarrage, la taille de la ROM n'importe pas. Le système va chercher l'entête "AB" au début de chaque page (ou uniquement 4000h et 8000h d'après ce que j'ai lu).
Pour ta ROM 32K, le système va trouver l'entête de cartouche en 4000h et va sauter à l'adresse de programme défini dans ton ctr0.
A ce moment de l'initialisation, tu vas voir :
- Page 0 : Main-ROM
- Page 1 : Ta cartouche
- Page 2 : RAM
- Page 3 : RAM

C'est d'ailleurs la raison pour laquelle le ctr0 commence par mettre la page 2 sur le même slot que la page 1 (sur ta cartouche).
Donc au début de ton main(), tu as :
- Page 0 : Main-ROM
- Page 1 : Ta cartouche
- Page 2 : Ta cartouche
- Page 3 : RAM

Donc oui, au début de ton main(), si tu appelles ma fonction sur la page 3, tu obtiendra le slot ID de la RAM.

Sans Memory Mapper, la page 0 visible par le CPU correspondra toujours à la page 0 d'un des slots.
Vu qu'il n'y qu'un seul slot de RAM apparemment sur les MSX (en dehors des Memory Mapper), tu ne pourras pas avoir plus d'une zone de RAM dans la page 3.
La page 3 pointera toujours vers la page 3 du slot de RAM.

Si tu veux plus de RAM avec une cartouche 32K sans Memory Mapper, faut la mettre en pages 0 et 1 (donc remplacer le Bios).
Dans ce cas, non seulement tu peux avoir la RAM en pages 2 et 3, mais en plus, comme tu remplaces le Bios, tu peux utiliser à ta guise la Working area qui prends 3K en page 3.
C'est pas que pour rien que j'œuvre à virer le Bios. ;)

Sinon, faut soit se contenter du peu de RAM dispo... soit utiliser les Memory Mapper.
Tu peux aussi t'arranger pour que ton code soit en page 1 (premier 16K de ta ROM ; garder le reste pour les datas) et dans ce cas tu peux switch la page 2 entre la RAM et ta ROM en fonction de tes besoins.


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

Le 09/01/2021 à 06h58
Citation :
La page 3 pointera toujours vers la page 3 du slot de RAM..


d'accord mais est-ce que l'on peut swapper les pages de ram ?
si je veux que ma Page 3 pointé vers la page 1 du slot 3 pour utiliser une bank de 16K supplémentaire, on doit pouvoir le faire ?


ps : J'avoue qu'au niveau Rom je ne suis pas très informé des techniques et possibilités.


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2576

Le 09/01/2021 à 10h14
Tu ne peux pas.
La Page 3 du CPU pointera toujours vers la Page 3 d'un slot.
Tu peux la faire pointer vers la Page 3 de n'importe quel slot, mais pas vers une autre page.
Page 3 du CPU -> Page 3 du Slot 0, Page 3 du Slot 1, Page 3 du Slot 3-0, etc.

C'est tout l'intérêt des Memory Mapper que de permettre de faire sauter cette limitation.


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

Le 09/01/2021 à 10h56
et donc la page 0 ? Pointe toujours vers une page 0 De Slot ?
Idem page 1 et 2 alors je suppose ?

Citation :
C'est tout l'intérêt des Memory Mapper que de permettre de faire sauter cette limitation.

Oui j'avais déjà étudié le Memory Mapper, et justement je comprenais mal la différence avec les slots.
Là, maintenant je comprend.



Sur ce schéma c'est la configuration des slots de base, sur un MSX2 VG-8235



Si je comprend bien, cela veut dire que si je veux accéder à la SUB ROM, je dois faire un appel interslot ?
Et si je mets une cartouche 32K dans cette machine, elle va se placer en page 1 et 2 du Slot 1. Du coup le DiskRom sera "masqué", et je devrais faire un changement de slot ou un appel inters lot pour y accéder ?
C'est ça ? Edité par ericb59 Le 09/01/2021 à 11h03


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2576

Le 09/01/2021 à 16h29
ericb59 :
et donc la page 0 ? Pointe toujours vers une page 0 De Slot ?
Idem page 1 et 2 alors je suppose ?


Toutafé.

ericb59 :
Sur ce schéma c'est la configuration des slots de base, sur un MSX2 VG-8235
[...]
Si je comprend bien, cela veut dire que si je veux accéder à la SUB ROM, je dois faire un appel interslot ?
Et si je mets une cartouche 32K dans cette machine, elle va se placer en page 1 et 2 du Slot 1. Du coup le DiskRom sera "masqué", et je devrais faire un changement de slot ou un appel inters lot pour y accéder ?
C'est ça ?


Alors, pour le VG-8235, voici l'état des slots au démarrage en fonction des différents cas :
- Démarrage sous Basic (RAM en page 2 et 3) ;
- Démarrage sous DOS (RAM sur toutes les pages) ;
- Démarrage depuis une cartouche avec un boot en 4000h (au moment ou notre crt0 prend la main) ;
- Démarrage depuis une cartouche avec un boot en 4000h (après l'exécution du crt0 qui set la page 2 sur le même slot que la page 1).



Du coup, il n'y a pas de cas ou la Sub-ROM ou la Disc-ROM soient sélectionnées au démarrage de ton programme.
Rien ne t'empêche de switcher les pages comme bon te semble selon tes besoins mais il faut faire attention à :
- Il faut garder les interruptions disable pendant toute la durée du switch de la page 0 (à moins que la page 0 du slot vers lequel tu switches contienne lui aussi une gestion d'interruption) ;
- Il est très compliqué de switch la page 3 car elle contient la stack ! Je l'ai déjà fait une fois via une routine qui n'utilisait pas la stack (donc pas push/pop/call/etc.) ;
- Pareil, en fonction de là ou se trouve ton programme, il peut être compliqué de switch les pages 1 et 2 d'une cartouche 32K. Dans ce cas, le mieux est de garder une page pour le code (la page 1 par ex.) et une page pour les data (la page 2). Comme ça il est facile de switch la page qui contient les datas.

Enfin, si tu as "juste" besoin d'appeler des routines qui se trouve dans un autre slot, le plus simple est d'utiliser les fonctions d'appelles inter-slots.
Pour ça il faut :
- Soit que tu codes toi-même ces fonctions et que tu les places dans ta page de code (c'est asses simple via les ports du PPI) ;
- Soit tu t'assures que la Main-ROM est bien sélectionné sur la page 0 (slot 0 normalement) et dans ce cas tu peux utiliser CALSLT et CALLF ;
- Soit sous MSX-DOS, tu t'assures que la RAM est bien sélectionné sur la page 0 et dans ce cas, tu peux aussi utiliser ces fonctions (aux mêmes adresses).

Sur MSX2, il a aussi des fonctions dans la Main-ROM pour appeler directement une fonction de la Sub-ROM (SUBROM et EXTROM).

PS : Encore une fois, autant j'ai beaucoup lu de docs techniques ces derniers temps, autant j'ai encore très peu d'expérience pratique avec le MSX ; donc il est pas totalement impossible que je me trompe. ^^


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

Le 09/01/2021 à 17h18
Je me suis trompé sur mon schéma j'ai fait n'importe quoi !! je l'ai vu après...


Merci pour tes explications. :top
Je pense avoir bien compris cette partie. (C'est plus simple d'utiliser le MSX-DOS :lol )

J'ai 2 autres questions.
Sur une ROM, peut on être certain que le code reste en page 1 ?
Est-ce que le compilateur va bien commencer à placer le code à partir de 0x4000 et augmenter dans les adresses au fur et à mesure ?
Pour tout ce qui est des DATAs, le mieux est donc de les placer en page 2, (pour éventuellement pouvoir switcher cette page si besoin).
Pour placer les DATAs à partir de 0x8000, je ne connais que cette méthode :
Code C :
const unsigned char __at(0x8000) map[50][50];


Mais cela oblige à tenir le compte de tous les datas, pour pouvoir les placer à la suite. C'est contraignant.
Y a t-il d'autres méthodes d'après toi ?


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2576

Le 09/01/2021 à 18h12
ericb59 :
Je me suis trompé sur mon schéma j'ai fait n'importe quoi !! je l'ai vu après...

Merci pour tes explications. :top
Je pense avoir bien compris cette partie. (C'est plus simple d'utiliser le MSX-DOS :lol )

J'ai 2 autres questions.
Sur une ROM, peut on être certain que le code reste en page 1 ?
Est-ce que le compilateur va bien commencer à placer le code à partir de 0x4000 et augmenter dans les adresses au fur et à mesure ?
Pour tout ce qui est des DATAs, le mieux est donc de les placer en page 2, (pour éventuellement pouvoir switcher cette page si besoin).
Pour placer les DATAs à partir de 0x8000, je ne connais que cette méthode :
Code C :
const unsigned char __at(0x8000) map[50][50];


Mais cela oblige à tenir le compte de tous les datas, pour pouvoir les placer à la suite. C'est contraignant.
Y a t-il d'autres méthodes d'après toi ?


Une solution "sûr" c'est de compiler ton code d'un côté et tes datas d'un autre, puis de merger les deux binaires (en remplissant les vides pour que les adresses restent alignées sur les pages).
Comme ça tu vois facilement la taille de chacun de ces morceaux et t'assurer qu'il reste bien dans la taille d'une page (<= 16 KB).
En assembleur, on peut utiliser les segments pour ranger facilement le code et les datas (et je pense que linker emmétra une erreur sur les sections se chevauchent).
Quand j'avais eu besoin de placer mes datas, j'avais juste placé ma première struct à une adresse précise (avec un __at), puis les suivantes en adresse relative par rapport au data précédent.
C'est pas super pratique, mais ça marchait bien.
Je vais regarder coté SDCC ce qu'on peut faire.


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

Le 10/01/2021 à 22h31
C'est bon, j'ai trouvé !

Y a une option --constseg <Name> pour SDCC qui permet de placer tous les datas constants dans un segment de notre choix (j'utilise "RODATA" car c'est le nom du segment dans z88dk).
Ensuite, il suffit de placer ce segment dans les crt0 à l'endroit souhaité.
Pour une cartouche 32 KB, tu peux le mettre en 8000h.

Ca a un double avantage :
- Les données sont placées en 3e page (laissant toute la 2e page pour le code)
- Si ton code (en 2e page) dépassé la taille de sa page, tu auras un message d'erreur (si ce n'est dans le linker, au moins dans hex2bin)

Et voilà :)


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

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 10/01/2021 à 23h21
Vindiou les gars, j'ai encore du chemin à parcourir ;)


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie