Dr.Vince
11/09/2006, 11h38
Economiser de l'IWRAM sous VHAM
Auteur : Brunni
Bonjour tout le monde!
Voici un petit tuto qui va vous permettre de gagner, très simplement, 5484 octets d'IWRAM avec HAM.
Ceci n'est applicable que si:
Vous n'utilisez pas la librairie HAM
Vous n'utilisez pas le support des interruptions du crt0.s (si vous ne savez pas ce que c'est, c'est que vous ne l'utilisez certainement pas).
L'astuce consiste simplement à désactiver le support des interruptions inclus à HAM. Vous pouvez ensuite en faire un vous-même très simplement.
Voici donc la procédure à suivre:
-> Allez dans le répertoire C:\HAM\system et ouvrez crt0.s.
-> Mettez un @ devant la ligne suivante:
.equ __InterruptSupport, 1
Voilà, c'est tout, il ne vous reste plus qu'à recompiler votre projet. C'était trop compliqué, n'est-ce pas?
--------
Bon, maintenant voici quelques informations, pour bien comprendre ce que cela implique. Presque tout le monde utilise son propre gestionnaire d'interruptions, car c'est plus simple d'en coder un que d'utiliser celui de crt0.s (sisi). Tout d'abord, il faut déclarer le registre REG_INTERRUPT:
#define REG_INTERRUPT *(u32*)0x3007FFC
Ensuite, vous devez y mettre un pointeur vers une fonction, qui fera gestionnaire d'interruption.
REG_IME=0; //Désactiver les interruptions pendant qu'on travaille dessus
REG_IE = INT_TYPE_VBL|INT_TYPE_HBL; //On veut gérer le VBLANK et le HBLANK
REG_DISPSTAT = (1<<3)|(1<<4); //VBL+HBL IRQ
REG_INTERRUPT=(u32*)InterruptHandler; //La fonction
REG_IME=1; //Activer les interruptions
Maintenant le gestionnaire d'interruptions (interrupt handler en anglais):
void InterruptHandler(void)
{
u32 IF;
REG_IME = 0x00;
IF=REG_IF;
if (REG_IF & INT_TYPE_HBL) {
//Code de l'HBL
}
if (REG_IF & INT_TYPE_VBL) {
//Code de la VBL
}
REG_IF = IF;
REG_IME = 0x01;
}
Vous pouvez mettre l'interrupt handler en IWRAM ou non, mais perso je ne le fais pas, car même s'il s'y trouve une pétée de code, la différence est minime (inférieure à 1% de CPU).
Le hic c'est que ce handler ne gère pas les interruptions multiples (ou "nestées"), ce qui signifie qu'une autre interruption ne peut pas arriver pendant que l'une d'entre elles est justement en train d'être gérée.
En général, ça ne pose aucun problème, sauf dans de très rares cas (où la VBL déborderait souvent sur l'affichage par exemple).
Dans ce cas-là, tournez-vous vers une routine toute faite qui gère les IRQ multiples, ou réactivez le support IRQ dans crt0.s.
Mais bon, je pense que si vous arrivez dans ce cas, ce ne sera pas un problème pour vous de coder votre propre routine.
Auteur : Brunni
Bonjour tout le monde!
Voici un petit tuto qui va vous permettre de gagner, très simplement, 5484 octets d'IWRAM avec HAM.
Ceci n'est applicable que si:
Vous n'utilisez pas la librairie HAM
Vous n'utilisez pas le support des interruptions du crt0.s (si vous ne savez pas ce que c'est, c'est que vous ne l'utilisez certainement pas).
L'astuce consiste simplement à désactiver le support des interruptions inclus à HAM. Vous pouvez ensuite en faire un vous-même très simplement.
Voici donc la procédure à suivre:
-> Allez dans le répertoire C:\HAM\system et ouvrez crt0.s.
-> Mettez un @ devant la ligne suivante:
.equ __InterruptSupport, 1
Voilà, c'est tout, il ne vous reste plus qu'à recompiler votre projet. C'était trop compliqué, n'est-ce pas?
--------
Bon, maintenant voici quelques informations, pour bien comprendre ce que cela implique. Presque tout le monde utilise son propre gestionnaire d'interruptions, car c'est plus simple d'en coder un que d'utiliser celui de crt0.s (sisi). Tout d'abord, il faut déclarer le registre REG_INTERRUPT:
#define REG_INTERRUPT *(u32*)0x3007FFC
Ensuite, vous devez y mettre un pointeur vers une fonction, qui fera gestionnaire d'interruption.
REG_IME=0; //Désactiver les interruptions pendant qu'on travaille dessus
REG_IE = INT_TYPE_VBL|INT_TYPE_HBL; //On veut gérer le VBLANK et le HBLANK
REG_DISPSTAT = (1<<3)|(1<<4); //VBL+HBL IRQ
REG_INTERRUPT=(u32*)InterruptHandler; //La fonction
REG_IME=1; //Activer les interruptions
Maintenant le gestionnaire d'interruptions (interrupt handler en anglais):
void InterruptHandler(void)
{
u32 IF;
REG_IME = 0x00;
IF=REG_IF;
if (REG_IF & INT_TYPE_HBL) {
//Code de l'HBL
}
if (REG_IF & INT_TYPE_VBL) {
//Code de la VBL
}
REG_IF = IF;
REG_IME = 0x01;
}
Vous pouvez mettre l'interrupt handler en IWRAM ou non, mais perso je ne le fais pas, car même s'il s'y trouve une pétée de code, la différence est minime (inférieure à 1% de CPU).
Le hic c'est que ce handler ne gère pas les interruptions multiples (ou "nestées"), ce qui signifie qu'une autre interruption ne peut pas arriver pendant que l'une d'entre elles est justement en train d'être gérée.
En général, ça ne pose aucun problème, sauf dans de très rares cas (où la VBL déborderait souvent sur l'affichage par exemple).
Dans ce cas-là, tournez-vous vers une routine toute faite qui gère les IRQ multiples, ou réactivez le support IRQ dans crt0.s.
Mais bon, je pense que si vous arrivez dans ce cas, ce ne sera pas un problème pour vous de coder votre propre routine.