La Place des Développeurs ROM 48K et slots
aoineko
Membre non connecté
Conseiller Municipal
Reprise du message précédent
Je vois 2 façons viables d'utiliser une cartouche 48K.Dans tous les cas, les 16K de la page 3 (adresses C000h à FFFFh) pointent toujours vers la RAM. C'est compliqué de switch cette page car c'est là ou se trouve, entre autre, la pile d'appel (indispensable pour appeler une fonction en C ou en assembleur).
Dans tous les cas, les 32K des pages 1 et 2 (adresses 4000h à BFFFh) pointent toujours vers la cartouche. Comme pour une cartouche de 32K.
La différentiation se fait sur l'utilisation de la page 0 (adresses 0000h à 3FFFh), là ou se trouve la Main-ROM (les fonctions principales du BIOS et le gestionnaire d'interruption).
- Dans mon jeu Final Smash par ex., je fais toujours pointer la page 0 vers la cartouche. Ma cartouche est donc toujours visible sur les pages 0, 1 et 2 sans jamais avoir besoin de switcher les pages. C'est bon grand avantage en termes de performance et de simplicité. Par contre, cela ne fonction que parce que ma librairie peut se passer des fonctions du BIOS et parce que je place dans ma cartouche un gestionnaire d'interruption fait maison là ou le MSX s'attend à trouver celui du BIOS.
- L'autre façon de faire c'est de laisser la page 0 pointer vers la Main-ROM. Du coup, le programme n'a pas à fournir son propre code d'interruption et peut continuer à utiliser les fonctions du BIOS. La contrepartie, c'est qu'à chaque fois que le programme à besoin d'accéder aux données de la cartouche en page 0, il a besoin de switcher le slot vers lequel pointe cette page. Il y a des fonctions du BIOS qui font ça automatiquement (function RDSLT) mais très lente car elle switch les pages à chaque octet lu. Sur MRC, ils proposent une ruse sympa mais pas simple à mettre en place en C, c'est d'avoir une fonction de copy de donnée de la cartouche vers la RAM qu'on place dans la cartouche en page 0. En l'appelant via un appel interslot (function CALSLT) cela permet de copy autant d'octet qu'on veut tout en laissant le BIOS se charger du switch de slot.
Si j'étais Ricco, je mettrais juste les 112 niveaux non-compressé dans la page 0 de la cartouche et j'utiliserais la lecture inteslot pour récupérer les 72 octets d'un niveau. Ca sera certainement pas plus lent que de décompresser les données et c'est simple à mettre en place.
Pour l'adresse des tableaux, mes programmes qui génèrent mes .h de donnée ont une option pour calculer automatiquement les adresses des __at.
On est toujours ignorant avant de savoir.
aoineko :
Sur MRC, ils proposent une ruse sympa mais pas simple à mettre en place en C, c'est d'avoir une fonction de copy de donnée de la cartouche vers la RAM qu'on place dans la cartouche en page 0. En l'appelant via un appel interslot (function CALSLT) cela permet de copy autant d'octet qu'on veut tout en laissant le BIOS se charger du switch de slot
C'est clairement une excellente méthode !
Si jamais je dois développer une ROM nécessitant 48K, c'est cette méthode là que je choisirai.
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
Si je devais faire la même chose, je le ferai manuellement.
Oui... j'aime pas utiliser le BIOS et ses fonctions dont je ne maitrise pas exactement le fonctionnement.
Je ferais un truc du genre :
EDIT : Il faut évidemment que la fonction qui copie les données n'utilise pas de fonctions du BIOS vu qu'il n'est plus dans la page 0. Mais bon, y a pas de raisons.
Oui... j'aime pas utiliser le BIOS et ses fonctions dont je ne maitrise pas exactement le fonctionnement.
Je ferais un truc du genre :
Code C :
u8 slot0 = GetPageSlot(0); // Backup Main-ROM slot DisableInterrupt(); SetPageSlot(0, GetPageSlot(1)); // Set slot of page 0 the same than the one in page 1 (the cartridge) /* copy data from page 0 (cartridge) to page 3 (RAM) */ SetPageSlot(0, Slot0); // Restore Main-ROM slot EnableInterrupt();
EDIT : Il faut évidemment que la fonction qui copie les données n'utilise pas de fonctions du BIOS vu qu'il n'est plus dans la page 0. Mais bon, y a pas de raisons.
On est toujours ignorant avant de savoir.
aoineko :
(...)
Si j'étais Ricco, je mettrais juste les 112 niveaux non-compressé dans la page 0 de la cartouche et j'utiliserais la lecture inteslot pour récupérer les 72 octets d'un niveau. Ca sera certainement pas plus lent que de décompresser les données et c'est simple à mettre en place.
(...)
(...)
Si j'étais Ricco, je mettrais juste les 112 niveaux non-compressé dans la page 0 de la cartouche et j'utiliserais la lecture inteslot pour récupérer les 72 octets d'un niveau. Ca sera certainement pas plus lent que de décompresser les données et c'est simple à mettre en place.
(...)
Hello
Ca sous entendrait que toutes mes fonctions soit réécrites pour taper directement dans le HW
Encore du boulot en perspective
Bon dimanche les zamis
aoineko
Membre non connecté
Conseiller Municipal
Je ne suis pas Ricco... et je te conseil de passer par le BIOS.
D'ailleurs, je suis en train de refaire proprement ma librairie de manipulation du BIOS.
Je l'utiliserais probablement pas pour mes jeux (je préfère les accès directs aux HW), mais c'est toujours pratique pour des outils.
D'ailleurs, je suis en train de refaire proprement ma librairie de manipulation du BIOS.
Je l'utiliserais probablement pas pour mes jeux (je préfère les accès directs aux HW), mais c'est toujours pratique pour des outils.
On est toujours ignorant avant de savoir.
J'ai lu ça sur MRC, qui peut m'en dire plus
You'll "hide" the BIOS ROM hence no direct BIOS ROM calls possible. Ofcourse you can use the romcall routines, in page 3 where system stuff is located, to call ROM BIOS routines.
Bon dimanche les zamis
aoineko
Membre non connecté
Conseiller Municipal
La première partie dit que si tu switches le slot vers lequel pointe la page 0 (0000-3FFFh) tu ne peux logiquement plus accéder directement aux fonctions du BIOS qui s'y trouvait (le BIOS est dans le slot 0 ou 0-0).
Par exemple, la fonction BEEP du BIOS (qui joue un son) se trouve à l'adresse 00C0h de la Main-ROM ; Si tu fait un__asm__("call BEEP");
alors que la page 0 ne pointe pas vers le slot de la Main-ROM, ça ne fonctionnera pas (ça va même probablement crasher ).
La deuxième partie de la phrase est plus énigmatique pour moi. Il semble dire qu'en page 3 (qui pointe normalement vers un slot de RAM), il y aurait des fonctions qui permettent d'appeler les fonctions du BIOS même si le slot du BIOS n'est pas sélectionné. Je peux me tromper, mais il ne me semble pas que ce genre de fonctions se trouve en RAM. Quelqu'un pour confirmer ?
Rien ne t'empêche au début de ton programme de copier toi-même des fonctions en RAM pour les utiliser plus tard, mais c'est loin d'être trivial, surtout en C.
Personnellement, ce que je te recommande chaudement c'est :
- Tu créés une cartouche 48K qui occupe les pages 0 à 2 avec un boot au début de la page 1 (4000h).
- Tu places des données auquel tu n'as pas besoin d'accéder tout le temps dans la page 0 de ta cartouche (tes 112 niveaux non-compressés par ex.).
- Au démarrage de ta cartouche tu laisses la page 0 sur la Main-ROM/BIOS, tu mets ta cartouche sur les pages 1 et 2 (comme pour ta cartouche 32K) et tu laisses la RAM en page 3.
- Au moment ou tu as besoin d'accéder aux données de ton niveau, tu fait une lecture interslot (RDSLT) pour récupérer les 72 octets de ton niveau. C'est un peu lent, mais pas plus (voir moins) que l'algorithme de décompression que tu utilisais.
Tu auras déjà gagné 6 KB (tes 112 niveaux) et tu n'auras pas eu besoin de t'occuper des changements de slots.
Après, tu pourras toujours mettre plus de données et/ou optimiser les accès en lecture interslot vers la page 0 de ta cartouche.
Y a plein de solution plus ou moins simples ; On en reparlera à ce moment-là.
Par exemple, la fonction BEEP du BIOS (qui joue un son) se trouve à l'adresse 00C0h de la Main-ROM ; Si tu fait un
La deuxième partie de la phrase est plus énigmatique pour moi. Il semble dire qu'en page 3 (qui pointe normalement vers un slot de RAM), il y aurait des fonctions qui permettent d'appeler les fonctions du BIOS même si le slot du BIOS n'est pas sélectionné. Je peux me tromper, mais il ne me semble pas que ce genre de fonctions se trouve en RAM. Quelqu'un pour confirmer ?
Rien ne t'empêche au début de ton programme de copier toi-même des fonctions en RAM pour les utiliser plus tard, mais c'est loin d'être trivial, surtout en C.
Personnellement, ce que je te recommande chaudement c'est :
- Tu créés une cartouche 48K qui occupe les pages 0 à 2 avec un boot au début de la page 1 (4000h).
- Tu places des données auquel tu n'as pas besoin d'accéder tout le temps dans la page 0 de ta cartouche (tes 112 niveaux non-compressés par ex.).
- Au démarrage de ta cartouche tu laisses la page 0 sur la Main-ROM/BIOS, tu mets ta cartouche sur les pages 1 et 2 (comme pour ta cartouche 32K) et tu laisses la RAM en page 3.
- Au moment ou tu as besoin d'accéder aux données de ton niveau, tu fait une lecture interslot (RDSLT) pour récupérer les 72 octets de ton niveau. C'est un peu lent, mais pas plus (voir moins) que l'algorithme de décompression que tu utilisais.
Tu auras déjà gagné 6 KB (tes 112 niveaux) et tu n'auras pas eu besoin de t'occuper des changements de slots.
Après, tu pourras toujours mettre plus de données et/ou optimiser les accès en lecture interslot vers la page 0 de ta cartouche.
Y a plein de solution plus ou moins simples ; On en reparlera à ce moment-là.
On est toujours ignorant avant de savoir.
Re
- "Tu créés une cartouche de 48ko" > je crois que C good
J'ai ma cartouche de 48ko
de 0x0000 à 0x3fff : datas des niveaux
de 0x4000 à 0xbfff : l'ensemble du jeu
- "Tu places des données auxquelles tu n'as pas (...)
Si ce sont les datas niveaux, c good car fait en dans le 1er point (si j'ai bien saisi)
- "Au démarrage de la cartouche...." > je crois que C good
page 0 > datas niveaux de 0x0000 à 0x3fff
page 1 et 2 > les 32ko du jeu
- "Au moment d'avoir besoin (...)"
C'est lent car lu octet par octet. C'est un début et si ca marche ca serait déjà génial mais j'en suis loin
RDSLT est une fonction du BIOS 0x000c. Comment j'y accède sachant que le BIOS est écrasé ? C'est la même chose pour mes fonctions comme LDIRVM, INIGRP, ENASCR, etc... ou alors un truc m'échappe...
Le cerveau est en mode Ebullition ON
Bonne soirée
- "Tu créés une cartouche de 48ko" > je crois que C good
J'ai ma cartouche de 48ko
de 0x0000 à 0x3fff : datas des niveaux
de 0x4000 à 0xbfff : l'ensemble du jeu
- "Tu places des données auxquelles tu n'as pas (...)
Si ce sont les datas niveaux, c good car fait en dans le 1er point (si j'ai bien saisi)
- "Au démarrage de la cartouche...." > je crois que C good
page 0 > datas niveaux de 0x0000 à 0x3fff
page 1 et 2 > les 32ko du jeu
- "Au moment d'avoir besoin (...)"
C'est lent car lu octet par octet. C'est un début et si ca marche ca serait déjà génial mais j'en suis loin
RDSLT est une fonction du BIOS 0x000c. Comment j'y accède sachant que le BIOS est écrasé ? C'est la même chose pour mes fonctions comme LDIRVM, INIGRP, ENASCR, etc... ou alors un truc m'échappe...
Le cerveau est en mode Ebullition ON
Bonne soirée
aoineko
Membre non connecté
Conseiller Municipal
Ricco59 :
C'est lent car lu octet par octet. C'est un début et si ca marche ca serait déjà génial mais j'en suis loin
RDSLT est une fonction du BIOS 0x000c. Comment j'y accède sachant que le BIOS est écrasé ? C'est la même chose pour mes fonctions comme LDIRVM, INIGRP, ENASCR, etc... ou alors un truc m'échappe...
RDSLT est une fonction du BIOS 0x000c. Comment j'y accède sachant que le BIOS est écrasé ? C'est la même chose pour mes fonctions comme LDIRVM, INIGRP, ENASCR, etc... ou alors un truc m'échappe...
72 octets c'est pas beaucoup. Je pense pas que la vitesse sera un soucis ; surtout que ça va remplacer ton code de décompression lz77 qui doit être assez lourd.
Si tu ne changes pas le slot de la page 0, le BIOS ne va pas être "écrasé".
Tu peux donc utilisé sans soucis les fonctions qui se trouve sur la page 0 de la Main-ROM/BIOS.
A priori, la partie haute de la Main-ROM (celle qui se trouve en page 1) ne concerne que le BASIC et tu n'en as pas besoin pour utiliser les fonctions de base du BIOS, comme la copy interslot.
Je te remets l'image des slots (théoriques) vers lesquels devrait pointer les différentes pages au démarrage de ta ROM :
Voici mes fonctions de lecture interslots :
Code C :
#define R_RDSLT 0x000C // Reads the value of an address in another slot #define M_EXPTBL 0xFCC1 // 4 Bit 7 of these variables is a flag for each primary slot to indicate if the slot is expanded or not. The other bits are reset. The first variable (also called MNROM) indicates the slot ID of the Main-ROM. This implies that the Main-ROM of an MSX is always in primary slot 0, or secondary slot 0-0. // Reads the value of an address in another slot u8 Bios_InterSlotRead(u8 slot, u16 addr) { slot; // IX+4 addr; // IX+6 IX+5 __asm push ix ld ix, #0 add ix, sp ld a, 4(ix) ld l, 5(ix) ld h, 6(ix) call R_RDSLT ld l, a // return value pop ix __endasm; } // InterSlot read to Main-ROM u8 Bios_MainROMRead(u16 addr) __FASTCALL { addr; // HL __asm ld a, (M_EXPTBL) call R_RDSLT ld l, a // return value __endasm; }
Y a plein de moyen d'optimiser, mais essaye déjà comme ça.
On est toujours ignorant avant de savoir.
Merdoum, j'ai rêvé ou ton message a disparu Aoineko
J'ai encore une kouechtionne Trivial Pursuit (et ce n'est pas la dernière)
Mon fichier compilé à l'instant correspond bien à la figure 48ko after crt0. La rom est bien décomposé comme suit
SLOT1 - PAGE0 pour les datas des niveaux
SLOT1 - PAGE1 et PAGE2 pour le jeu
Si je lance la rom avec emulicious ou meisei, le jeu doit se lancer correctement et planter au moment de lire les niveaux ? ici, j'affiche un ecran et c'est tout...
Allez, mode TRACE ON Edité par Ricco59 Le 12/12/2021 à 21h50
J'ai encore une kouechtionne Trivial Pursuit (et ce n'est pas la dernière)
Mon fichier compilé à l'instant correspond bien à la figure 48ko after crt0. La rom est bien décomposé comme suit
SLOT1 - PAGE0 pour les datas des niveaux
SLOT1 - PAGE1 et PAGE2 pour le jeu
Si je lance la rom avec emulicious ou meisei, le jeu doit se lancer correctement et planter au moment de lire les niveaux ? ici, j'affiche un ecran et c'est tout...
Allez, mode TRACE ON Edité par Ricco59 Le 12/12/2021 à 21h50
aoineko
Membre non connecté
Conseiller Municipal
Mon message est là, mais j'ai eu un soucis... j'étais connecté en double sur le site.
Oui, normalement tu ne devrais pas crasher avant d'essayer de lire les données de ta cartouche dans la page 0.
Tu peux vérifier que ta cartouche est bien placé avec OpenMSX dans le menu Memory layout :
Tu peux comparer avec le crt0 que j'utilise pour les cartouches 48K : https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/crt0/crt0_rom48.asm
Ricco59 :
Si je lance la rom avec emulicious ou meisei, le jeu doit se lancer correctement et planter au moment de lire les niveaux ? ici, j'affiche un ecran et c'est tout...
Oui, normalement tu ne devrais pas crasher avant d'essayer de lire les données de ta cartouche dans la page 0.
Tu peux vérifier que ta cartouche est bien placé avec OpenMSX dans le menu Memory layout :
Tu peux comparer avec le crt0 que j'utilise pour les cartouches 48K : https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/crt0/crt0_rom48.asm
On est toujours ignorant avant de savoir.
Comme je le disais, ca plante dès le début. J'ai essayé avec ton crt48ko et la cartouche n'est pas reconnue, le msx passe au BASIC
Voila ce que j'obtiens dans le memory layout
Page adress slot segment
0 $0000 0 r0/1
1 $4000 1 r2/3
2 $8000 1 r4/5
3 $c000 3 -
Edité par Ricco59 Le 12/12/2021 à 23h48
Voila ce que j'obtiens dans le memory layout
Page adress slot segment
0 $0000 0 r0/1
1 $4000 1 r2/3
2 $8000 1 r4/5
3 $c000 3 -
Edité par Ricco59 Le 12/12/2021 à 23h48
aoineko
Membre non connecté
Conseiller Municipal
Met un label juste avant le début du header de ta ROM et check dans le .map s'il est bien en 4000h.
Tu peux aussi check les adresses de tes fonctions qui doivent se trouver entre 4000h et 7FFFh (pages 1 et 2) pour être visible par le Z80.
Check aussi que tes 112 niveaux sont bien dans une adresse entre 0000h et 3FFFh (page 0).
Code ASM :
rom_header:: .db 0x41 ; A .db 0x42 ; B
Tu peux aussi check les adresses de tes fonctions qui doivent se trouver entre 4000h et 7FFFh (pages 1 et 2) pour être visible par le Z80.
Check aussi que tes 112 niveaux sont bien dans une adresse entre 0000h et 3FFFh (page 0).
On est toujours ignorant avant de savoir.
Dans mes souvenirs, datant fin des années 80 sur MSX1 (64ko forcément), écrire et lire dans la RAM en page 0 à partir du basic en ASM était assez galère :
- attention aux interruptions,
- et attention à ne pas perdre le contenu des registres.
A propos du C :
Small-C (si mes souvenirs sont exacts) bascule sur les seconds registres lors d'appel à une fonction MAIS il arrive que ces seconds registres contiennent des valeurs utiles au système. Là aussi, le crash est assuré !
Désolé, si j'enfonce des portes ouvertes...
Il faut bien lire la documentation des fonctions BIOS : lire les pré-requis mais aussi , ce qu'il y a en sortie, en particulier les drapeaux (flags) et registres modifiés.
Dans ton cas, il faut vérifier également que ta cartouche comporte bien les infos nécessaires au bon endroit : caractères 'AB' et adresse de lancement de ton jeu.
Surtout, ASSUME NOTHING (règle d'or d'un gourou de la programmation assembleur)
- attention aux interruptions,
- et attention à ne pas perdre le contenu des registres.
A propos du C :
Small-C (si mes souvenirs sont exacts) bascule sur les seconds registres lors d'appel à une fonction MAIS il arrive que ces seconds registres contiennent des valeurs utiles au système. Là aussi, le crash est assuré !
Désolé, si j'enfonce des portes ouvertes...
Il faut bien lire la documentation des fonctions BIOS : lire les pré-requis mais aussi , ce qu'il y a en sortie, en particulier les drapeaux (flags) et registres modifiés.
Dans ton cas, il faut vérifier également que ta cartouche comporte bien les infos nécessaires au bon endroit : caractères 'AB' et adresse de lancement de ton jeu.
Surtout, ASSUME NOTHING (règle d'or d'un gourou de la programmation assembleur)
Nous sommes en 2010 aps JC, toute la Gaule est envahie. Ah ben non, apparement, un village résiste encore aux envahisseurs Personalcomputerum et autres Consoledessalum. Bienvenue dans l'antre du emessix !
Hello les zamis
Je viens de verifier et tout est au bon endroit
La boulette que j'ai faite était dans la ligne de compilation :
J'ai ecris
--code-loc 0x4010 --data-loc 0x0000
au lieu de ça
--code-loc 0x4010 --data-loc 0xc000
Et comme attendu, tout fonctionne jusqu'au moment d'afficher le niveau
Je continue mes recherches et la prochaine étape devrait être
> Mettre DATA slot1 page0 en slot0 page1 (de 0x4000 à 0x8000)
Tchao les zamigo
Edité par Ricco59 Le 13/12/2021 à 20h41
Je viens de verifier et tout est au bon endroit
La boulette que j'ai faite était dans la ligne de compilation :
J'ai ecris
--code-loc 0x4010 --data-loc 0x0000
au lieu de ça
--code-loc 0x4010 --data-loc 0xc000
Et comme attendu, tout fonctionne jusqu'au moment d'afficher le niveau
Je continue mes recherches et la prochaine étape devrait être
> Mettre DATA slot1 page0 en slot0 page1 (de 0x4000 à 0x8000)
Tchao les zamigo
Edité par Ricco59 Le 13/12/2021 à 20h41
Ricco59 :
Hello les zamis
> Mettre DATA slot1 page0 en slot0 page1 (de 0x4000 à 0x8000)
> Mettre DATA slot1 page0 en slot0 page1 (de 0x4000 à 0x8000)
Là, je ne suis plus... En slot 0 - page 1, ce n'est pas la ROM
Nous sommes en 2010 aps JC, toute la Gaule est envahie. Ah ben non, apparement, un village résiste encore aux envahisseurs Personalcomputerum et autres Consoledessalum. Bienvenue dans l'antre du emessix !
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie