La Place des Développeurs FUSION-C Codez en C pour MSX les doigts dans le nez !
aoineko
Membre non connecté
Conseiller Municipal
Reprise du message précédent
Pour set un hook sur H.TIMI il suffit d'écrire :Code C :
void MyCallbcak() { // my super intersting code... } Bios_SetHookCallback(H_TIMI, MyCallbcak);
Je connais pas exactement les contraintes (c'était le sujet d'un de mes posts récemment mais j'ai pas eu bcp plus d'infos).
J'ai juste expérimenté des comportements étrange quand mon hook appelait certaines routines du Bios (comme le Beep) à cause de la concurrence (le code du hook peut être redéclencher avant qu'il ait fin de s'exécuter).
Pour limiter les risques, j'ai ajouté des fonctions Mutex pour protéger des zones sensibles de mes hooks.
Voici :
Code C :
//----------------------------------------------------------------------------- // █▀▀ █▀▄▀█ █▀ ▀▄▀ // █▄▄ █ ▀ █ ▄█ █ █ v0.2 //----------------------------------------------------------------------------- #pragma once extern u8 g_Mutex; // Must be declared somewhere in the application code // Initialize mutex inline void MutexInit() { g_Mutex = 0; } // Lock the given mutex (0-7) inline void MutexLock(u8 mutex) { g_Mutex |= (1 << mutex); } // Release the given mutex (0-7) inline void MutexRelease(u8 mutex) { g_Mutex &= ~(1 << mutex); } // Wait for mutex release (0-7) inline void MutexWait(u8 mutex) { while((g_Mutex & (1 << mutex)) != 0); } // Gate for mutex (0-7) inline BOOL MutexGate(u8 mutex) { return ((g_Mutex & (1 << mutex)) == 0); }
Pour l'utiliser dans un hook
Code C :
void MyCallbcak() { if(MutexGate(1)) { MutexLock(1); // codes qui ne peut pas être interrompu... MutexRelease(1); } }
Pour les sections du code assembleur, je maitrise pas trop, mais je vais renseigner.
Ce que j'ai compris, c'est que ça sert à ordonner les différents éléments du programme au moment du link.
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
Pour le data-loc, si tu le mets à 0, la section _DATA va être placé juste à la suite de _CODE.
C'est ce que j'utilise dans la version binaire BASIC et program DOS car le program est en RAM.
Pour les ROM, il faut absolument placer la section _DATA à une adresse en RAM sinon tu pourras pas écrire dans tes variables :P
Pour une ROM de 32KB qui commence à 4000h (pour garder la Main-ROM dans la page 0), il faut que _DATA soit placé en C000h, le seul espace de RAM dispo par défaut.
C'est ce que j'utilise dans la version binaire BASIC et program DOS car le program est en RAM.
Pour les ROM, il faut absolument placer la section _DATA à une adresse en RAM sinon tu pourras pas écrire dans tes variables :P
Pour une ROM de 32KB qui commence à 4000h (pour garder la Main-ROM dans la page 0), il faut que _DATA soit placé en C000h, le seul espace de RAM dispo par défaut.
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
Et bah, j'ai cherché 1h sur le net et j'ai toujours pas trouvé la signification des différents segments du linker...
Dans mon fichier MAP généré par SDCC, j'ai trouvé toutes ces sections :
Je comprends pas l'odre... je comprends pas les S et les L... et je comprends pas le sens de la plupart des sections.
Les seuls que je comprends c'est _CODE (le code compilé va s'accumuler dans cette section), _DATA (où seront stockés les variables) et ABS (éléments placés à une adresse fixe).
Y a aussi la section _BBS qui permet normalement de stocker les variables static et/ou non-initialisé mais il semble pas être utilisé par SDCC.
Si quelqu'un a plus d'infos, je suis preneur !
Dans mon fichier MAP généré par SDCC, j'ai trouvé toutes ces sections :
Code TEXT :
.__.ABS. l__CABS l__DABS l__HEADER l__HEAP l__HOME l__INITIALIZED l__INITIALIZER s__CABS s__DABS s__HEADER s__HEADER0 l__GSFINAL l__DATA l__GSINIT l__HEADER0 s__CODE l__CODE s__DATA s__GSINIT s__GSFINAL s__HEAP s__HOME s__INITIALIZED s__INITIALIZER
Je comprends pas l'odre... je comprends pas les S et les L... et je comprends pas le sens de la plupart des sections.
Les seuls que je comprends c'est _CODE (le code compilé va s'accumuler dans cette section), _DATA (où seront stockés les variables) et ABS (éléments placés à une adresse fixe).
Y a aussi la section _BBS qui permet normalement de stocker les variables static et/ou non-initialisé mais il semble pas être utilisé par SDCC.
Si quelqu'un a plus d'infos, je suis preneur !
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
Bon, ça commence à être un peu plus clair dans ma tête
Les s_ sont les adresses de débuts de segments et les _l sont les longueurs de ces segments.
Ce qui me perturbait, c'est que dans le fichier map ils ont listé les langueurs comme si c'était des adresses alors que ça à rien à voir.
Bref, si on regarde que les s_ et les différents éléments de notre programme on peut vérifier que tout est bien en place.
Du coup, j'ai pu corriger mon crt0 pour cartouche 48K (page 0 à 2 avec page 1&2 sélectionnées au démarrage).
Si tu veux, envoi-moi les ASM / MAP / LST générés par les crt0 qui te posent problème, j'y jetterai un coup d'œil.
Les s_ sont les adresses de débuts de segments et les _l sont les longueurs de ces segments.
Ce qui me perturbait, c'est que dans le fichier map ils ont listé les langueurs comme si c'était des adresses alors que ça à rien à voir.
Bref, si on regarde que les s_ et les différents éléments de notre programme on peut vérifier que tout est bien en place.
Du coup, j'ai pu corriger mon crt0 pour cartouche 48K (page 0 à 2 avec page 1&2 sélectionnées au démarrage).
Si tu veux, envoi-moi les ASM / MAP / LST générés par les crt0 qui te posent problème, j'y jetterai un coup d'œil.
On est toujours ignorant avant de savoir.
ericb59
Membre non connecté
Conseiller Municipal
Citation :
Si tu veux, envoi-moi les ASM / MAP / LST générés par les crt0 qui te posent problème, j'y jetterai un coup d'œil.
Ben j'ai pas ces fichiers quand je compile un crt0, vu que c'est de l'asm, je fais juste un
sdasz80 -o crt0_MSX32k_ROM4000.s
et j'obtient un .rel
c'est tout.
Sinon mes crt0 sont dans WorkungFolder/fusion-c/source/
je tests juste avec crt0_MSX32k_ROM4000
Edité par ericb59 Le 25/11/2020 à 19h55
aoineko
Membre non connecté
Conseiller Municipal
Ajoute les paramètres -l (.lst) et -s (.sym) à sdasz80.
Le .map est généré lors du link avec SDCC.
EDIT : Si tu as le même problème avec mon crt0, c'est que le problème vient pas des crt0.
Les fichiers de linkage permettront de voir si y a des datas ou du code qui se trouve dans des sections ou il devrait pas.
Par contre, ce qu'on pourra difficilement voir, c'est s'il y a des accès en écriture à des endroits situés dans la ROM (qui fonctionne quand le programme est en mémoire).
Le .map est généré lors du link avec SDCC.
EDIT : Si tu as le même problème avec mon crt0, c'est que le problème vient pas des crt0.
Les fichiers de linkage permettront de voir si y a des datas ou du code qui se trouve dans des sections ou il devrait pas.
Par contre, ce qu'on pourra difficilement voir, c'est s'il y a des accès en écriture à des endroits situés dans la ROM (qui fonctionne quand le programme est en mémoire).
On est toujours ignorant avant de savoir.
ericb59
Membre non connecté
Conseiller Municipal
voici un exemple de . map qui pose problème (Enfin qui pose problème je ne sais pas trop) le programme final fonctionne, mais hex2bin génère une erreur
Comme tu le vois, il y a des éléments qui vont au dessus de C000 qui ne sont pas des variables.
Je ne sais pas pourquoi.
Les erreurs relevées par Hex2bin sont les suivantes :
Data record skipped at C0DE
Data record skipped at C0DF
Cela ne le fait pas non plus sur toutes les programmes que je test. Edité par ericb59 Le 26/11/2020 à 10h47
Code TEXT :
ASxxxx Linker V03.00 + NoICE + sdld, page 1. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ . .ABS. 00000000 00000000 = 0. bytes (ABS,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ 00000000 .__.ABS. 00000000 l__CABS 00000000 l__DABS 00000000 l__GSFINAL 00000000 l__GSINIT 00000000 l__HEADER 00000000 l__HOME 00000000 s__CABS 00000000 s__DABS 00000000 s__HEADER 00000000 s__HEADER0 00000005 l__INITIALIZED 00000005 l__INITIALIZER 00000020 l__XDATA 0000004B l__HEADER0 000000D9 l__DATA 00002231 l__CODE 00004050 s__CODE 0000C000 s__DATA 0000C0D9 s__INITIALIZED 0000C0DE s__GSFINAL 0000C0DE s__GSINIT 0000C0DE s__HOME 0000C0DE s__INITIALIZER 0000C0E3 s__XDATA ASxxxx Linker V03.00 + NoICE + sdld, page 2. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _CODE 00004050 00002231 = 8753. bytes (REL,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ 00004067 _FT_RandomNumber GCHASEb 000040C4 _TxtTitle GCHASEb 000040D4 _TxtPressKey GCHASEb 000040EC _TxtScore GCHASEb 000040F5 _TxtTime GCHASEb 000040FB _TxtYourScore GCHASEb 00004107 _TxtSub GCHASEb 00004127 _rotdir GCHASEb 00004131 _DirectionX GCHASEb 0000413A _DirectionY GCHASEb 0000451C _PrintScore GCHASEb 0000455B _FT_Wait GCHASEb 00004570 _EnemyDirection GCHASEb 00004642 _LittleDirection GCHASEb 000046B0 _CheckApproach GCHASEb 000047BC _CheckCollision GCHASEb 00004970 _MoveEnemy GCHASEb 00004AEE _MoveLittle GCHASEb 00004C35 _SpriteOnScreen GCHASEb 00004C5A _Timer GCHASEb 00004CB1 _WaitSpaceKey GCHASEb 00004CEE _EndScreen GCHASEb 00004D7E _StartScreen GCHASEb 00004F94 _routing GCHASEb 00004FAF _main GCHASEb 00005279 _Sprite32Bytes 000052AB _rand rand 0000536A _srand rand 00005387 _Pattern16RotationRam PatternTransform 00005508 _shift PatternTransform 00005518 _Pattern16RotationVram PatternTransform 000055CF _Pattern8RotationVram PatternTransform 0000564C _Pattern8RotationRam PatternTransform 0000570A _Pattern8FlipRam PatternTransform 00005761 _Pattern16FlipRam PatternTransform 0000580D _Pattern16FlipVram PatternTransform 000058D7 _Pattern8FlipVram PatternTransform 00005950 _PatternRotation patternrotation 000059A2 _BoxFill boxfill 00005A16 _PatternHFlip patternhflip 00005A7A _InitFX 00005A7A _StopFX 00005ABD _UpdateFX 00005BCC _PlayFX 00005C49 __mulsuchar 00005C53 __muluschar 00005C5D __mulschar 00005C6F _abs 00005C92 _HMMV hmmv 00005CE0 _MemCopy ASxxxx Linker V03.00 + NoICE + sdld, page 3. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _CODE 00004050 00002231 = 8753. bytes (REL,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ 00005D02 _SpriteReset 00005D1E _LMMV lmmv 00005D71 _InitPSG 00005D76 _PatternVFlip patternvflip 00005D99 _Inkey 00005DA9 _SetSpritePattern setspritepattern 00005DD9 _SetSpriteColors setspritepattern 00005E0B _InitVDPInterruptHandler 00005E47 _EndVDPInterruptHandler 00005E5E _JoystickRead 00005E67 _TriggerRead 00005E70 _Itoa itoa 00005F52 _VDP60Hz 00005F66 __mulint 00005F6C __mul16 00005F80 _CopyVramToRam copyvramtoram 00005FE3 _CopyRamToVram copyramtovram 00006045 _StrReverse strreverse 000060AC _fPutSprite fputsprite 000060F8 _StrLen 00006113 ___sdcc_enter_ix 0000611D _Exit 0000611E __modschar 0000612B __modsint 00006137 _Sprite16 0000614B _PutText 00006183 _SetColors 000061A4 __divsint 000061AD __divschar 000061B4 __div8 000061B8 __div_signexte 000061BC __div16 000061E2 __get_remainder 000061EC _Screen 00006201 _SetVDPread 00006209 _SetVDPwrite 00006240 __divuint 00006248 __divuchar 0000624F __divu8 00006252 __divu16 ASxxxx Linker V03.00 + NoICE + sdld, page 4. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _DATA 0000C000 000000D9 = 217. bytes (REL,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ 0000C000 _MyTimer GCHASEb 0000C002 _sdirX GCHASEb 0000C003 _sdirY GCHASEb 0000C004 _GameOn GCHASEb 0000C005 _score GCHASEb 0000C006 _mj GCHASEb 0000C007 _slittle GCHASEb 0000C008 _RunStep GCHASEb 0000C097 _TempBuffer PatternTransform 0000C0B7 _DoBuffer PatternTransform 0000C0D7 _rot PatternTransform 0000C0D8 _i PatternTransform ASxxxx Linker V03.00 + NoICE + sdld, page 5. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _INITIALIZED 0000C0D9 00000005 = 5. bytes (REL,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ 0000C0D9 _PatternStep GCHASEb ASxxxx Linker V03.00 + NoICE + sdld, page 6. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _INITIALIZER 0000C0DE 00000005 = 5. bytes (REL,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ ASxxxx Linker V03.00 + NoICE + sdld, page 7. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _HEADER0 00000000 0000004B = 75. bytes (ABS,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ 0000401D find_rom_page_2 ASxxxx Linker V03.00 + NoICE + sdld, page 8. Hexadecimal [32-Bits] Area Addr Size Decimal Bytes (Attributes) -------------------------------- ---- ---- ------- ----- ------------ _XDATA 0000C0E3 00000020 = 32. bytes (REL,CON) Value Global Global Defined In Module ----- -------------------------------- ------------------------ ASxxxx Linker V03.00 + NoICE + sdld, page 9. Files Linked [ module(s) ] GCHASEb.rel [ GCHASEb ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/include/crt0_MSX32k_ROM4000.rel [ ] Libraries Linked [ object file ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ sprite32bytes.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ rand.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ PatternTransform.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ patternrotation.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ boxfill.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ patternhflip.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ ayfxDriver.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ mulchar.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ abs.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ hmmv.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ memcopy.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ spritereset.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ lmmv.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ initpsg.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ patternvflip.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ inkey.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ setspritepattern.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ interrupt_vdp.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ joystickbios.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ itoa.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ vdp60.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ mul.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ copyvramtoram.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ copyramtovram.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ strreverse.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ fputsprite.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ strlen.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ crtenter.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ exit.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ modsigned.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ sprite16.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ puttext.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ setcolors.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ divsigned.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ screen.rel ] /Users/ericboez/Desktop/WorkingFolder/fusion-c/lib/fusion-ROM.lib [ setvdp.rel ] /usr/local/bin/../share/sdcc/lib/z80/z80.lib [ divunsigned.rel ] ASxxxx Linker V03.00 + NoICE + sdld, page 10. User Base Address Definitions _CODE = 0x4050 _DATA = 0xc000
Comme tu le vois, il y a des éléments qui vont au dessus de C000 qui ne sont pas des variables.
Je ne sais pas pourquoi.
Les erreurs relevées par Hex2bin sont les suivantes :
Data record skipped at C0DE
Data record skipped at C0DF
Cela ne le fait pas non plus sur toutes les programmes que je test. Edité par ericb59 Le 26/11/2020 à 10h47
aoineko
Membre non connecté
Conseiller Municipal
Y a 5 bytes dans le segment _INITIALIZER qui semble poser problème, mais ça ne dit pas ce qu'il contient.
Je sais que Konamiman manipule ce segment dans le crt0 des binaires BASIC que j'ai récupéré, mais je ne sais pas pourquoi.
Je vais creuser la question...
Je sais que Konamiman manipule ce segment dans le crt0 des binaires BASIC que j'ai récupéré, mais je ne sais pas pourquoi.
Je vais creuser la question...
On est toujours ignorant avant de savoir.
ericb59
Membre non connecté
Conseiller Municipal
J'ai retrouvé des posts de Sylvain sur MSX.ORG qui me sont très utiles ...
Pendant que moi j'étais encore sur le DOS, lui avait déjà commencé à travailler les ROMS...
Je dois dire que Sylvain m'a beaucoup beaucoup aidé pour avancer vers Fusionc-c 1.3, et je le remercie énormément.
Reviens nous Sylvain ! Tu es le meilleurs d'entre nous !
Bref c'est ici :
https://www.msx.org/forum/msx-talk/development/sdcc-crt0s-for-floppy-bload?page=0
Suis les posts de Akumajo.
Sa méthode et son CRT0, m'ont permis de créer une première ROM qui marche bien !! (en tout cas mieux que les autres)
PS : Bon, je n'arrive plus à reproduire cet essai qui fonctionnait bien Edité par ericb59 Le 27/11/2020 à 17h01
Pendant que moi j'étais encore sur le DOS, lui avait déjà commencé à travailler les ROMS...
Je dois dire que Sylvain m'a beaucoup beaucoup aidé pour avancer vers Fusionc-c 1.3, et je le remercie énormément.
Reviens nous Sylvain ! Tu es le meilleurs d'entre nous !
Bref c'est ici :
https://www.msx.org/forum/msx-talk/development/sdcc-crt0s-for-floppy-bload?page=0
Suis les posts de Akumajo.
Sa méthode et son CRT0, m'ont permis de créer une première ROM qui marche bien !! (en tout cas mieux que les autres)
PS : Bon, je n'arrive plus à reproduire cet essai qui fonctionnait bien Edité par ericb59 Le 27/11/2020 à 17h01
aoineko
Membre non connecté
Conseiller Municipal
Akumajo, un nom qui revient souvent sur les discussions intéressantes de msx.org
J'avais déjà lu ce post, mais je pense pas qu'il aide beaucoup dans le cas actuel.
Je peux me tromper, mais j'ai vraiment pas l'impression que ton problème vienne du crt0 ; celui des ROM est simpliste (entête, éventuel switch de page si ROM > 16KB, puis saut au _main).
Il faut juste s'assurer que tout ce qui doit être en RAM est bien dans une page de la RAM.
Pour info, j'ai trouvé dans le code hex2bin l'endroit ou il produit l'erreur « Data record skipped at ... »
MEMORY_SIZE est de 4 Mo. C'est bizarre que tu dépasses cette taille pour une cartouche de 32KB.
J'ai jamais eu ce bug par contre, j'ai déjà eu des fichiers binaires de plusieurs centaines de méga généré par hex2bin ; dans mon souvenir, ça arrivait quand j'avais des datas initialisés avant le main().
J'avais déjà lu ce post, mais je pense pas qu'il aide beaucoup dans le cas actuel.
Je peux me tromper, mais j'ai vraiment pas l'impression que ton problème vienne du crt0 ; celui des ROM est simpliste (entête, éventuel switch de page si ROM > 16KB, puis saut au _main).
Il faut juste s'assurer que tout ce qui doit être en RAM est bien dans une page de la RAM.
Pour info, j'ai trouvé dans le code hex2bin l'endroit ou il produit l'erreur « Data record skipped at ... »
Code C :
/* Check that the physical address stays in the buffer's range. */ if ((Phys_Addr + Nb_Bytes) > MEMORY_SIZE)
MEMORY_SIZE est de 4 Mo. C'est bizarre que tu dépasses cette taille pour une cartouche de 32KB.
J'ai jamais eu ce bug par contre, j'ai déjà eu des fichiers binaires de plusieurs centaines de méga généré par hex2bin ; dans mon souvenir, ça arrivait quand j'avais des datas initialisés avant le main().
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
@Eric, j'ai p'être trouvé ton problème (en corrigeant ce problème dans ma lib ).
Si tu as des variables non-const initialisées dans le scope global, ça va poser des problèmes car, par défaut SDCC va essayer de placer la zone d'initialisation dans la RAM (après l'adresse que tu passes en --data-loc ).
Du coup, hex2bin va générer un binaire qui va de ton adresse de début de code jusqu'après cette zone d'initialisation.
Ca va faire un ROM buggé ayant une partie qui devrait se trouver en RAM (mais comme cette page ne sera pas sélectionné, tu vas te retrouver avec des variables initialisées avec des donnés random... et des comportement hiératiques qui vont avec).
Heureusement, il y a une solution via le crt0 car on peut manipuler l'emplacement des zones _INITIALIZER qui contient le code d'initialisation et _INITIALIZED qui contient les données finales.
Deux étapes :
1) Placer la zone _INITIALIZER dans la ROM et _INITIALIZED dans la RAM. Il suffit de placer la première juste après _CODE et la deuxième juste après _DATA.
2) Au run-time (dans le code du crt0 avant l'appel au main() ), il faut recopier le contenu de _INITIALIZER (en ROM) vers _INITIALIZED (en RAM).
Il suffit d'exécuter ce code :
Au cas ou tu vois pas ce que sont les variables non-const initialisées, c'est des trucs du genre :
static int myTab[] = { 0, 1, 2, 3 };
L'alternative serait de les rendre "const". Dans ce cas, elles sont stocké dans la ROM et ça pose pas de problème.
Sachant que si tu as besoin de les garder en "non-const", il faudra payer le cout d'une double occupation mémoire (1 fois dans la ROM et 1 fois dans la RAM).
J'espère que ça t'aidera.
Si tu as des variables non-const initialisées dans le scope global, ça va poser des problèmes car, par défaut SDCC va essayer de placer la zone d'initialisation dans la RAM (après l'adresse que tu passes en --data-loc ).
Du coup, hex2bin va générer un binaire qui va de ton adresse de début de code jusqu'après cette zone d'initialisation.
Ca va faire un ROM buggé ayant une partie qui devrait se trouver en RAM (mais comme cette page ne sera pas sélectionné, tu vas te retrouver avec des variables initialisées avec des donnés random... et des comportement hiératiques qui vont avec).
Heureusement, il y a une solution via le crt0 car on peut manipuler l'emplacement des zones _INITIALIZER qui contient le code d'initialisation et _INITIALIZED qui contient les données finales.
Deux étapes :
1) Placer la zone _INITIALIZER dans la ROM et _INITIALIZED dans la RAM. Il suffit de placer la première juste après _CODE et la deuxième juste après _DATA.
2) Au run-time (dans le code du crt0 avant l'appel au main() ), il faut recopier le contenu de _INITIALIZER (en ROM) vers _INITIALIZED (en RAM).
Il suffit d'exécuter ce code :
Code ASM :
ld bc, #l__INITIALIZER ld a, b or a, c jp z,start ld de, #s__INITIALIZED ld hl, #s__INITIALIZER ldir start: call _main ; start main() function
Au cas ou tu vois pas ce que sont les variables non-const initialisées, c'est des trucs du genre :
static int myTab[] = { 0, 1, 2, 3 };
L'alternative serait de les rendre "const". Dans ce cas, elles sont stocké dans la ROM et ça pose pas de problème.
Sachant que si tu as besoin de les garder en "non-const", il faudra payer le cout d'une double occupation mémoire (1 fois dans la ROM et 1 fois dans la RAM).
J'espère que ça t'aidera.
On est toujours ignorant avant de savoir.
ericb59
Membre non connecté
Conseiller Municipal
Par variables non-const, tu veux parler de variables globale ?
Initialisée hors du main ? C'est bien ça ?
Si c'est le cas, ca me parait assez étrange. Il est plus rapide et moins couteux en RAM pour SDCC d'utiliser des variables globales que locale.
Initialisée hors du main ? C'est bien ça ?
Si c'est le cas, ca me parait assez étrange. Il est plus rapide et moins couteux en RAM pour SDCC d'utiliser des variables globales que locale.
aoineko
Membre non connecté
Conseiller Municipal
ericb59 :
Par variables non-const, tu veux parler de variables globale ?
Initialisée hors du main ? C'est bien ça ?
Si c'est le cas, ca me parait assez étrange. Il est plus rapide et moins couteux en RAM pour SDCC d'utiliser des variables globales que locale.
Initialisée hors du main ? C'est bien ça ?
Si c'est le cas, ca me parait assez étrange. Il est plus rapide et moins couteux en RAM pour SDCC d'utiliser des variables globales que locale.
Les données const sont stockés dans la ROM et ne sont accessibles qu'en lecture donc ça pose aucun problème.
Je parle de données non-const déclarées et initialisées dans le scope global.
C'est quelque chose d'assez standard (surtout chez les adaptes de la programmation Data driven).
C'est évitable, mais ça m'étonnerait pas que tu puisses en avoir qq unes qui trainent dans ta lib.
Et si c'est le cas, ça va poser des problèmes quand tu build une ROM avec la config de base de SDCC.
D'où ma théorie que tes problèmes viennent de là.
Et pour info, les données non-const déclarées et initialisées dans un scope local ont le même cout en mémoire (l'initialisation sera stocké dans la ROM et un espace équivalant sera alloué en RAM).
La différence c'est qu'elles sont alloués dans la stack et non pas dans la heap.
Et elles n'ont évidemment pas la même durée de vie (puisse qu'elles peuvent être dépilées).
Pour prendre un exemple :
Code C :
const char tab1[] = { 1, 2, 3 }; // donnée const avec initialisation char tab2[] = { 1, 2, 3 }; // donnée non-const avec initialisation char tab3[3]; // donnée non-const sans initialisation void main() { char c1 = tab1[0]; // vaut '1' (pointe vers les données en ROM) char c2 = tab2[0]; // ne vaut pas '1' si tu n'as pas fait la manip décrite dans mon précédent post }
On est toujours ignorant avant de savoir.
ericb59
Membre non connecté
Conseiller Municipal
Alors tes variables non-Const chez moi ça s’appel une variable globale. En tout cas c’est comme ça que j’ai appris
Bref... oui... les CONST font parties des données, dans le cas d’un programme DOS, et se retrouvent en ROM dans le cas d’une ROM jusque là tout va bien, on est d’accord.
Les Variables qui sont déclarées en globale, mais non initialisées DOIVENT être initialisées à zéro au début et se retrouvent en Ram, et c’est le boulot d’une routine ASM du crt0_msxdos.s
Les variables qui sont déclarées et initialisées en globale, doivent se trouver en RAM aussi, avec leur valeur.
Que ça soit pour un programme Dos ou ROM, c’est censé être identique. Mais, ça ne marche pas des masses, la faute au crt0 pour faire les Roms ? Et le linker qui mets pas les blocs dans le bon sens d’après Sylvain.
Par contre en aucun cas, la variable ne devrait prendre de la place en Rom et en Ram, ce n’est pas un comportement normal... on est d’accord ?
De tout ce que j’ai lu sur la programmation des 8bits avec SDCC il est fortement conseillé d’utiliser au maximum des variables globales.
Essaie de faire un essai sur un petit bout de code.
Tu déclares une variable en globale, tu compiles, puis tu changes ta variable de place et tu la déclares dans le main à la place du globale, tu compiles ... compare la taille des 2 binaires à la fin, sur 1 seule variable tu as 1 ou 2 octets de plus quand tu déclare en locale.
Le problème que j’ai est dépendant du crt0 , mais je dois aussi avoir des routines asm qui ne sont pas adaptées à la rom... faut que je fasse le point... mais. A m’enerve un peu car j’ai l’impression de tourner en rond...
Compliqué tout ça Edité par ericb59 Le 30/11/2020 à 18h45
Bref... oui... les CONST font parties des données, dans le cas d’un programme DOS, et se retrouvent en ROM dans le cas d’une ROM jusque là tout va bien, on est d’accord.
Les Variables qui sont déclarées en globale, mais non initialisées DOIVENT être initialisées à zéro au début et se retrouvent en Ram, et c’est le boulot d’une routine ASM du crt0_msxdos.s
Les variables qui sont déclarées et initialisées en globale, doivent se trouver en RAM aussi, avec leur valeur.
Que ça soit pour un programme Dos ou ROM, c’est censé être identique. Mais, ça ne marche pas des masses, la faute au crt0 pour faire les Roms ? Et le linker qui mets pas les blocs dans le bon sens d’après Sylvain.
Par contre en aucun cas, la variable ne devrait prendre de la place en Rom et en Ram, ce n’est pas un comportement normal... on est d’accord ?
De tout ce que j’ai lu sur la programmation des 8bits avec SDCC il est fortement conseillé d’utiliser au maximum des variables globales.
Essaie de faire un essai sur un petit bout de code.
Tu déclares une variable en globale, tu compiles, puis tu changes ta variable de place et tu la déclares dans le main à la place du globale, tu compiles ... compare la taille des 2 binaires à la fin, sur 1 seule variable tu as 1 ou 2 octets de plus quand tu déclare en locale.
Le problème que j’ai est dépendant du crt0 , mais je dois aussi avoir des routines asm qui ne sont pas adaptées à la rom... faut que je fasse le point... mais. A m’enerve un peu car j’ai l’impression de tourner en rond...
Compliqué tout ça Edité par ericb59 Le 30/11/2020 à 18h45
aoineko
Membre non connecté
Conseiller Municipal
Une variable initialisé non-const va forcement se retrouver en double dans le cas d'un programme sur ROM.
Dans mon exemple, pour char tab2[] = { 1, 2, 3 }; , tu vas avoir :
A l'initialisation de ton programme, la partie en ROM est censé être copié en RAM, sinon le tableau aura pas ses bonnes valeurs.
Je pense que notre problème c'est que comme on utilise pas le crt0 de SDCC (via l'option --no-std-crt0 ) il nous manque une partie des opérations qui sont géré de base (comme celle-là).
D'ailleurs, Konamiman fait aussi la copie de la partie _INITIALIZER vers _INITIALIZED dans son crt0 pour programme Binary sous Basic.
Dans ce cas (comme pour le DOS), y a p'être moyen de faire en sorte que les zones soient confondues pour qu'on ait pas besoin d'allouer d'espace supplémentaire en RAM.
J'ai pas vu comment faire ça avec SDCC ; je sais pas si Konamiman a cherché mais y a p'être pas de solution sans modifier le linker.
Ca peut paraitre fou d'avoir les données "en double" mais en fait, si tu fais l'initialisation de tes variables en code, ça prendra en fait encore plus de place.
tab[0] = 1; tab[1] = 2; tab[2] = 3; prends plus de bytes une fois convertis en code binaire que son équivalent en initialisation de variable.
Bon courage !
PS : Pour info je bosse sur une gestionnaire d'input (clavier/joystick) sans accès bios et avec un système de callback pour détecter certain évènements (appuis court, appuis long, double-click, etc.). Si ça t'intéresse, ça devrait pas être compliqué de le convertir pour Fusion-C une fois fini.
Dans mon exemple, pour char tab2[] = { 1, 2, 3 }; , tu vas avoir :
Code ASM :
.area _INITIALIZER __xinit__tab2: .db 1 2 3 ; qui se trouve dans la ROM (après la section _CODE) pour stocker les valeurs par défaut de la zone mémoire .area _INITIALIZED _tab2: .ds 3 ; qui se trouve dans la RAM (après la section _DATA) pour réserver la zone mémoire en RAM (mais sans valeurs associées)
A l'initialisation de ton programme, la partie en ROM est censé être copié en RAM, sinon le tableau aura pas ses bonnes valeurs.
Je pense que notre problème c'est que comme on utilise pas le crt0 de SDCC (via l'option --no-std-crt0 ) il nous manque une partie des opérations qui sont géré de base (comme celle-là).
D'ailleurs, Konamiman fait aussi la copie de la partie _INITIALIZER vers _INITIALIZED dans son crt0 pour programme Binary sous Basic.
Dans ce cas (comme pour le DOS), y a p'être moyen de faire en sorte que les zones soient confondues pour qu'on ait pas besoin d'allouer d'espace supplémentaire en RAM.
J'ai pas vu comment faire ça avec SDCC ; je sais pas si Konamiman a cherché mais y a p'être pas de solution sans modifier le linker.
Ca peut paraitre fou d'avoir les données "en double" mais en fait, si tu fais l'initialisation de tes variables en code, ça prendra en fait encore plus de place.
tab[0] = 1; tab[1] = 2; tab[2] = 3; prends plus de bytes une fois convertis en code binaire que son équivalent en initialisation de variable.
Bon courage !
PS : Pour info je bosse sur une gestionnaire d'input (clavier/joystick) sans accès bios et avec un système de callback pour détecter certain évènements (appuis court, appuis long, double-click, etc.). Si ça t'intéresse, ça devrait pas être compliqué de le convertir pour Fusion-C une fois fini.
On est toujours ignorant avant de savoir.
aoineko
Membre non connecté
Conseiller Municipal
Ah... une dernière chose !
J'ai pas vérifié si c'était bien le cas avec SDCC, mais la norme C99 demande qu'une variable static soit initialisé automatiquement à 0.
Du coup, si dans ton programme tu as un " static char a; " par ex., le compilo/linker va le traiter comme une variable initialisé donc si tu fais pas la copie de _INITIALIZER vers _INITIALIZED , tu vas avoir une variable avec une valeur indéterminée (alors qu'avec la version du crt0 de Konamiman que tu utilises pour les binaires Basic, cette variable sera bien initialisée à 0).
J'ai pas vérifié si c'était bien le cas avec SDCC, mais la norme C99 demande qu'une variable static soit initialisé automatiquement à 0.
Du coup, si dans ton programme tu as un " static char a; " par ex., le compilo/linker va le traiter comme une variable initialisé donc si tu fais pas la copie de _INITIALIZER vers _INITIALIZED , tu vas avoir une variable avec une valeur indéterminée (alors qu'avec la version du crt0 de Konamiman que tu utilises pour les binaires Basic, cette variable sera bien initialisée à 0).
On est toujours ignorant avant de savoir.
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie