Attention, code TRES moche (et non re-testé), représentant d'une époque où on définissait encore les directives pour la compilation de TIGCCLIB dans le source (au lieu de les définir globalement dans le TPR, si on utilise un TPR). C'est une libre modification de l'exemple "Progress Bar" de TIGCC, qui a commencé comme test ("tiens, qu'est-ce que ça fait si on remplit la structure à la main pour mettre une progress bar super grande ?"), et montre à quel point AMS sux pour la vitesse...
Je précise aussi que j'ai fait exprès d'aller, quand j'ai fait cette optimisation, de l'autre côté de la limite des normes de lisibilité et de propreté. Ceci dit, un programmeur ASM comme toi devrait tout de suite comprendre la copie manuelle de structure WIN_RECT
// Progress bar example for TIGCC
// Optimized version, the old version is left commented after this one.
// Compilation options: -O3 -Wall -W -Wwrite-strings -Wa,-l
// (-Os generates bigger code !)
//
// We could even replace the calls to the system timer functions by
// waiting loops in plain assembly. That would reduce the size, while
// not being a problem, since we don't need accuracy here...
#define USE_TI89 // Compile for TI-89
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define MIN_AMS 200 // Compile for AMS 2.00 or higher
#define NO_CALC_DETECT
#define NO_EXIT_SUPPORT
#define OPTIMIZE_ROM_CALLS
#include <tigcclib.h> // Include All Header Files
ST_PROGRESS_BAR spb = {NULL, {0, 0, 0, 0}, 0, 0, 100, 100, 0};
// Using that trick, we can reduce size.
register ST_PROGRESS_BAR * spbptr asm("%a2");
// Main Function
void _main(void)
{
short j;
spbptr = &spb; // Initialize the global register variable.
WINDOW w;
WINDOW * wptr = &w;
// WIN_RECT is 8 bytes...
WIN_RECT * winrect = ScrToWin (ScrRect);
*(unsigned long *)((unsigned char *)spbptr+OFFSETOF(ST_PROGRESS_BAR,rect)) =
*(unsigned long *)winrect;
*(unsigned long *)((unsigned char *)spbptr+OFFSETOF(ST_PROGRESS_BAR,rect)+4) =
*(unsigned long *)((unsigned char *)winrect+4);
spbptr->physwidth = spbptr->rect.x1 - spbptr->rect.x0 + 1;
WinOpen (wptr, (WIN_RECT*)((unsigned char *)spbptr+OFFSETOF(ST_PROGRESS_BAR,rect)), WF_SAVE_SCR | WF_NOBORDER);
spbptr->w = wptr;
spbptr->value = 0;
for (j = 0; j < 20; j++)
{
// The function is so slow if the progress bar is huge, that no waiting loop
// is necessary !
OSFreeTimer (USER_TIMER);
OSRegisterTimer (USER_TIMER, 2);
while (!OSTimerExpired (USER_TIMER)); // Wait a little...
ST_progressIncrement (spbptr, 1); // Increment the progress bar by 1/100.
}
ST_progressUpdate (spbptr, 50); // Increment the progress bar up to 50/100.
OSFreeTimer (USER_TIMER);
OSRegisterTimer (USER_TIMER, 20);
while (!OSTimerExpired (USER_TIMER)); // Wait for about 1 second...
OSFreeTimer (USER_TIMER);
ST_progressUpdate (spbptr, 100); // Fill the progress bar entirely.
GKeyIn (NULL, 0);
// ST_progressDismiss does nothing if the progress bar is in a window.
ST_progressDismiss (spbptr); // Remove the progress bar, redraw status line.
WinClose (wptr);
}