La Place des Développeurs FUSION-C Codez en C pour MSX les doigts dans le nez !
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.
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.
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.
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.
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
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.
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
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.
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
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.
@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.
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.
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.
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
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.
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
