MSX Village forum

La Place des Développeurs Les ROM Mapper les mieux supportés

Jipe Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10012

Le 03/01/2022 à 18h18

Reprise du message précédent

pour la cartouche qui démarre en 0000h il faut que je teste en vrai car il y a plusieurs ROMS Konami de 8k qui l'utilisent

CRAZY TRAIN 41 42 60 01 00 00 00 00 00 00 00 00 00 00 00 00

JUNO FIRST 41 42 0D 03 00 00 00 00 00 00 00 00 00 00 00 00

SPARKIE 41 42 CF 00 00 00 00 00 00 00 00 00 00 00 00 00



:noel
Site web    
Jipe Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10012

Le 03/01/2022 à 19h49
test dans OpenMSX avec

Crazy Train Page 0 Address $0000 slot 1 Segment R0 reflet de 0000h en 2000h
Juno First Page 0 Address $0000 slot 1 Segment R0 reflet de 0000h en 2000h
Sparkie Page 0 Address $0000 slot 1 Segment R0 reflet de 0000h en 2000h

il serait interessant d'analyser ces jeux car ça voudrait dire qu'il ne font pas appel au bios


:noel
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2487

Le 03/01/2022 à 22h19
Crazy Train a un entête "AB" en 0000h, en 2000h, en 4000h et en 6000h.
En fait, ça semble être une ROM de 8K qui est dupliqué 4 fois.

Si j'ai bien compris, il n'y a que l'entête en 4000h qui est censé être détecté par le BIOS.
Par contre, je ne comprends pas comment l'entête trouvé en 4000h (page #1) peut sauter sauter à l'adresse 'init' en 0160h (page #0).

Je sais que le BIOS set automatique le slot dans la cartouche quand il trouve l'entête, mais je pensais que le set était fait sur la page de l'entête, pas sur celle de l'adresse du 'init'.

EDIT : D'après OpenMSX, les pages #0 et #1 sont sur la cartouche et les pages #2 et #3 sur la RAM.
Donc soit la cartouche inclue un gestionnaire d'interruption, soit les interruptions sont coupées.


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

Le 03/01/2022 à 23h55
La ROM de Juno First que j'ai trouvé fait 8K, a un entête "AB" à l'offset 0000h du fichier et un code d'initialisation à l'adresse 030Dh (page #0).

D'après OpenMSX, elle est placé en page #0 (la page #1 est sur la BASIC-ROM et les #2 et #3 sur la RAM).

J'imagine que la cartouche est visible par miroir en 4000h et que l'adresse du code d'initialisation en 030Dh fait que le BIOS switch la page #0.

D'ailleurs, je mettrai une pièce sur le fait qu'à l'origine Crazy Train était aussi une cartouche 8K en miroir (peut-être les hackers en ont fait une cartouche 32K pour facilité son utilisation sur certains émulateurs).


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

Le 04/01/2022 à 17h05
Sparkie c'est comme Crazy Train : ROM 8K dupliqué 4 fois faite pour tourner en page #0.

Ca m'amène a une question sur l'effet miroir.
De ce que je comprends, l'effet miroir sur les ROM vient juste du fait que certains bits (les plus hauts) sont ignorés, ce qui implique que plusieurs adresses sur le bus, pointent donc vers la même adresse dans la ROM (comme si on appliquait un masque AND avec les bits haut à 0).
Est-ce le comportement standard des ROM de moins de 64K ?
Sinon, que ce passe-t-il si une cartouche de 8K n'est pas visible en miroir !?
Dans ce cas, que renvoi une instruction du genre LD A, (8000h) ?


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

Le 04/01/2022 à 17h05
Sparkie c'est comme Crazy Train : ROM 8K dupliqué 4 fois faite pour tourner en page #0.

Ca m'amène a une question sur « l'effet miroir ».
De ce que je comprends, l'effet miroir sur les ROM vient juste du fait que certains bits (les plus hauts) sont ignorés, ce qui implique que plusieurs adresses sur le bus, pointent donc vers la même adresse dans la ROM (comme si on appliquait un masque AND avec les bits hauts à 0).
Est-ce le comportement standard des ROM de moins de 64K ?
Sinon, que ce passe-t-il si une cartouche de 8K n'est pas visible en miroir !?
Dans ce cas, que renvoi une instruction du genre LD A, (8000h) ?


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

Le 07/01/2022 à 17h16
<<<@aoinek : finalement comment envisages tu la création des MegaRom ?


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2487

Le 07/01/2022 à 20h47
Je fais plus que envisager puisque le pipe de création est totalement fonctionnel. :)

Voilà comment ça marche :
Prenons l'exemple d'une ROM de 128K avec un mapper ASCII-8, composé donc de 16 segments.

1) Le Build Tool compile un premier bloc de 32K comme pour une ROM plain 32K classique (ce sont les 4 premiers segments).
Les mappers ont leur propre crt0 qui initialise les segments et aide donc les émulateurs à les détecter.

2) Ensuite, l'outil va chercher l'existence de fichiers pour les segments restants (segment 5 à 16 dans l'exemple).
J'utilise la nomenclature suivante : {nom_projet}_s{num_segment}_b{num_bank}.c .
Par exemple, si j'ai un projet "test", je peux ajouter du code dans le segment #5 qui doit être visible en bank #3 (A000h~BFFFh) en ajoutant simplement le fichier : test_s5_b3.c .
Le Build Tool le compile automatiquement à la bonne adresse de base.
Comme ça on peut y mettre du code ou des données.

3) Enfin, le Build Tool concatène la ROM de base et tous les segments. Pour les segments ou l'utilisateur n'a pas fournis de fichier, l'outil va ajouter des blocs vides.

Et voilà, le tour est joué. Tu te retrouve avec une ROM de 128K avec 16 segments.
J'ai une fonction qui permet ensuite de switcher le segment actif sur n'importe laquelle des banks.

Voici tous les formats que je peux générer avec un même fichier source : https://github.com/aoineko-fr/CMSX/tree/master/proj/targets/emul/rom

Par exemple, une ROM 512K avec un mapper ASCII-8 : https://webmsx.org/?ROM=https://github.com/aoineko-fr/CMSX/raw/master/proj/targets/emul/rom/s_target_ROM_ASCII8_512K.rom


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

Le 08/01/2022 à 07h13
Ok je vois.
Y a quelques trucs que je pige pas.
Si on prend l'exemple que tu donnes plus haut, comment ton code qui se trouve en bank 4 peut il être exécuter ?
j'arrive pas à saisir comment on crée on bank de code supplémentaire et l'utiliser.
Quand on a des datas, je comprend. On switch la page de la rom pour qu'elle arrive en bank3.
mais on y accède avec les adresses ?
Ou bien via une variable tableau ?
Comment sont compilés les datas ?

Par exemple, supposons que tu veux insérer dans tes datas une image complète en screen8.
soit quasi 64K
comment tu procèdes ? Edité par ericb59 Le 08/01/2022 à 07h14


banniere-ericb59e
Site web    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1459

Le 08/01/2022 à 12h36
Tu peux sélectionner une page à partir de n'importe quelle autre. Donc si tu veux exécuter du code qui est dans une autre page, tu la sélectionnes dans le slot et tu fait un 'jp' ou un 'call' à l'adresse. C'est tout.

En pratique, tu peux utiliser une page dans laquelle il y a le code principal, et qui gère la sélection de toutes les autres pages, soit pour y exécuter du code ou pour récupérer des données.

Les pages sont toujours compilées en connaissant l'adresse à laquelle elles vont être sélectionnée par le programme. Donc si ta page contient du code et qu'elle sera sélectionnée pour être en 0C000h, elle est compilée avec l'adresse de début 0C000h.

Edité par Metalion Le 08/01/2022 à 12h48


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

Le 08/01/2022 à 15h50
ericb59 :
Si on prend l'exemple que tu donnes plus haut, comment ton code qui se trouve en bank 4 peut il être exécuter ?


Précision, mes banques vont de #0 à #3, donc on parle ici du bank #3 : adresse A000h~BFFFh pour un mapper 8K.

Si on reprends mon exemple :
- Tu crées un fichier "test_s10_b3.c" avec une fonction dedans (qui peut elle-même appeler d'autres fonctions).
- Le build Tool va détecter automatiquement ce fichier, le compiler avec A000h comme adresse de base (le "b3") et va l'ajouter à la ROM à la place du segment #10 (le "s10").
- Dans ton jeu, tu peux switcher le bank #3 sur le segment #10 et appeler ta fonction en A000h.
- Quand ce segment est en bank #3, tu peux l'utiliser comme si c'était une ROM 32K ; la seule limitation, c'est que tu ne peux pas appeler des fonctions entre 2 bank qui ont été compilé pour être utilisé dans le même bank.

Ce que je n'ai pas fait (parce que j'en ai pas besoin pour le moment) c'est de compiler les segments additionnels avant de compiler la base de la ROM et de réinjecter les symboles dans segments pour qu'ils soient visibles et qu'on puisse utiliser directement le nom des fonctions et des tableaux.

ericb59 :
Comment sont compilés les datas ?


Idem pour les tableaux. Ils vont être compilés à partir de l'adresse de la bank dans laquelle on souhaite les rendre visibles.
Si tu mets 10 tableaux dans le fichier "test_s10_b3.c" de l'exemple, ils vont être mis les uns dernières les autres dans le fichier binaire.
Pour y accéder, comme je disais plus haut, je n'utilise pas les fichiers de symboles donc je note les adresses dont j'ai besoin (elles sont dispo dans le fichier .sym).

ericb59 :
Par exemple, supposons que tu veux insérer dans tes datas une image complète en screen8.
soit quasi 64K
comment tu procèdes ?


Ca tu peux pas. Un tableau ne peux pas être plus gros que la taille d'un segment (donc 8 ou 16K).
Certains outils MSX, comme pcmenc par ex., permettent justement de splitter une donnée en bloc de 8K.


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

Le 08/01/2022 à 17h13
ah oui... donc, en ce qui concerne le code qui est compilé en 0xA000 et qui contiendrait par exemple
la fonction suivante :
void MachinChose (char Size, char X, Char Y) {
...
}

Une fois que tu as switché le segment pour qu'il se trouve en 0xA000 ;
depuis ton programme principal, tu ne peux par appeler la fonction comme cela : MachinChose(32,10,10) ?
Tu dois l'appeler par son adresse, qui sera 0xA000, c'est cela ?
Comment tu fait ca en C, comment tu passes les paramètres ?



Secundo :
Les blocs de data, tu les fabriques de façon "classique" ?
Par exemple en utilisant BIN2HEX ? Tu récupères un tableau que tu vas installer à une adresse spécifique ?
Par exemple:

cont unsigned char __at(0xA100) DATA[512]=",1,1,1,1, ......"; Edité par ericb59 Le 08/01/2022 à 17h17


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2487

Le 08/01/2022 à 18h35
Y a surement plusieurs façons d'utiliser une fonction du genre MachinChose(32,10,10) .
- Soit en réinjectant les symboles des segments dans le build de la ROM de base,
- Soit en créant des fakes fonction à une adresse fixe (genre __at(0xXXXX) void MachinChose (char Size, char X, Char Y) {} ) dans la ROM de base,
- Soit en créant une macro pour simuler un call en C (elle mettrait les paramètres sur la stack avant de faire un call).

Pour les données, idem.
Vu que le segment va être compilé avec l'adresse de base de la bank où tu souhaites l'utiliser, il n'y a pas besoin de forcer l'adresse (les données vont s'accumuler automatiquement les unes derrières les autres).
Le gros problème avec les adresses fixes, c'est que ça empêche le compilateur de gérer proprement les chevauchements de donnée.
Du coup, il faut faire super gaffe et gérer les adresses à la main.
Mais oui, c'est une option simple pour savoir ou se trouve tes données.


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

Le 08/01/2022 à 21h11
Moi ca me semble compliqué d'avoir des segments avec du code complémentaire... J'arrive pas à voir comment l'utiliser.

Pour les données oui, je vois bien, c'est le même principe qu'une ROM 48K, mais avec plus de segments.

Par contre je me dis une chose.
Si tu créée une ROM 32K avec un CRT0 d'ASCII16, et que tu concaténes manuellement à la suite, un fichier d'image MSX .SC8,
on doit pouvoir accéder aux données de l'image par segments de 16K facilement, et pouvoir l'afficher à l'écran non ?

Quand on veut utiliser 128K de RAM d'un MSX 2, pour switcher les segments vers les pages 0, 1, 2, ou 3 on utilises les ports
0xFC, 0xFD, 0xFE, 0xFF
un OUT 0xFE,5 va connecter sur la page sur le segment 5 de la RAM.

Dans le cas où tu switch avec des pages d'une ROM, quelle est la technique ?


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2487

Le 09/01/2022 à 11h04
ericb59 :
Moi ca me semble compliqué d'avoir des segments avec du code complémentaire... J'arrive pas à voir comment l'utiliser.


En, réinjectant les symboles des segments lors du link ça devrait être totalement transparent pour l'utilisateur.
J'y jetterai un œil, mais j'ai d'autres prio pour le moment.
En attendant, ça permet au moins de pouvoir lancer facilement du code spécifique ayant un point d'entrer principal.

De toute façon, si on met toutes nos données volumineuses dans les segments au delà des 2 premiers, ça laisse les premiers 16K uniquement pour le code.
Ca suffit très largement pour un jeu amha et ça laisse 2 bank (8000~9FFFh et A000~BFFFh) pour switcher les données.
En tout cas, c'est cette configuration que je vais choisir pour Final Smash.

ericb59 :
Si tu créée une ROM 32K avec un CRT0 d'ASCII16, et que tu concaténes manuellement à la suite, un fichier d'image MSX .SC8,
on doit pouvoir accéder aux données de l'image par segments de 16K facilement, et pouvoir l'afficher à l'écran non ?


Oui, c'est tout à fait possible.
C'est uniquement une limitation de mon Build Tool qui ajoute segment par segment (donc des bouts de 8/16K).
Je pensai déjà permettre d'ajouter directement des fichiers binaires (sans les compiler) mais je pourrai facilement permettre d'ajouter des blocs plus gros qu'un segment et incrémenter le compteur d'autant.
C'est même possible pour du code ou des données en C si l'utilisateur compte les utiliser dans des segments contiguës.
Dans mon exemple, l'utilisateur pourrait très bien utiliser 2 segments de 8K à compiler à partir de 8000h et qui irait jusqu'à BFFFh.
En les mettant dans les bank #2 et #3, il aurait alors un espace contiguë de 16K ou il pourrait utiliser les symboles du C pour appeler des fonctions ou accéder à des données.

ericb59 :
Dans le cas où tu switch avec des pages d'une ROM, quelle est la technique ?


Tout dépend du mapper.
Généralement, on switch un bank en écrivant le numéro de segment à une adresse particulière de la ROM.
Mais il y a quelques cas particulier qui passe par les I/O.
Cf. https://www.msx.org/wiki/MegaROM_Mappers et http://bifi.msxnet.org/msxnet/tech/megaroms.


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

Le 10/01/2022 à 08h22
Comment ça marche la création de mégalomanie avec un Assembleur ASM ?
Comment les datas sont intégrés? D’un seul bloc ou par segments de 8/16k ?


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