Les applications PedroM seront des fichiers kernels (extension '68kP') dont avec un header kernel avec quelques contraintes. En plus d'avoir le flag ReadOnly mis, la fonction '_exit' est detourne :
Good:
+ Possibilite d'utiliser les romcalls / ramcalls / bss / libraries comme en kernel.
+ Possibilite d'importer des libraries en RAM ou en APPS ! C'est transparent.
+ La section BSS pour les vars globales est autorisé.
+ Le bloc BSS possedera un numero d'handle FIXE. Lorsque l'application ne s'en sert pas, cet handle est de taille 2 octets. Sinon, il est de la taille de la section BSS.
Bad:
+ Limite a 64K comme les programmes kernels !
+ Consomme un secteur entier quelque soit la taille utilisé.
+ Les vars globales avec le code sont interdites (forcement...), donc la librarie statique Tigcc ne marchera pas pour produire des applications (y'a des vars globales partout !).
+ Pas de self modifying code (donc genlib ne marchera pas en APPS...)
FUNCTION EVENT :
long event(short id asm("d0"), long data asm("d1"));
Switch (id) :
+ Idle: Le systeme glande...
+ Boot: Le systeme boote.
+ Clean: Commande 'clean' appellée.
+ CrashExit: L'application a declenche une operation illegale..
+ StartProgram: Un programme va etre lance (data = HANDLE)
+ EndProgram: Fin d'un programme
+ Shell KeyPress
+ Shell ClrScr
+ Get Unkown RomCall Ptr.
+ Get Unkown RamCall Ptr.
+ Get Unkown Library Ptr.
+ Install
+ Uninstall.
+ ngetchx Key
+ Calc On / Off
+ ViewFile (HANDLE , WINDOW *)
+ NoticeInstall ?
TO IMPROVE.
MAIN Function :
int _main(int argc, char *argc[])
Les programmes kernels peuvent bien sur importer les fonctions exportees des applications !
Tout comme le contraire :)
Internal Functions :
AppInit
Recherche des applications installées et reservation des handles.
Appelle apres FlashCheck.
AppInstall(HANDLE h, char *name)
Installe l'application h qui est en RAM.
Appelle automatiquement par la procedure de link si elle reconnait une application.
1. Check taille fichier (< 65536-20).
2. Check signature (_exit.w, et _exit +6.ll).
3. Recherche d'un secteur libre ($FFFF).
4. TailleBss = ReadBssSize(h). WriteBssSize(h) = 2
5. Rellocation du handle h avec comme destination le secteur trouvé. (Modifie legerement PreOS).
6. Remet la vrai taille du segment BSS et fixe le counter de reloc a 3.
7. Write Extra Header (Statut = 0FFFE). Folder : apps.
8. Write handle h.
AppUninstall(void *addr)
Desinstalle l'application.
1. Get sector base.
2. Check Extra Header
3. Verifie que le reloc count de l'application est a 3.
Oui: 3' : Met ce reloc count a 0.
3'': Appel function event(Uninstall).
4. Free BSS Handle.
5. FlashErase(Sector)
AppRun(void *addr, int argc, char *argv[])
Execute l'application (appelle la fonction _main).
1. Get sector base.
2. Check Apps
3. Saut a main.
AppOpenRessource(void)
Ouvre le fichier de ressources si necessaire.
Si le fichier est realloue, il est remplis a 0 !
1. Pop PC, get sector base.
2. Get BSS Handle, Check size
3. Size == 2
4. Realloc a sa taille normale.
5. Locke it.
6. Clean it.
7. Realloc des libraries (find_librarie, reloc).
8. Copie les adresses des fonctions dans la section BSS.
9. Retourne Ptr or NULL.
Sinon ne fait qu'un HLock dessus.
AppCloseRessource(void)
Ferme le fichier de ressource.
1. Pop PC, get sector base.
2. Get BSS Handle, Check size
3. Size != 2
4. UnRealloc des libraries (unreloc).
5. UnLocke it.
6. Realloc a 2.
8. Retourne Ptr or NULL.
Example:
#define RESSOURCE "res.h"
#include <pedrom.h>
long event(short id asm("d0"), long data asm("d1"), long extra asm("d2"))
{
return 0;
}
int main(int argc, char *argv[])
{
g = ropen();
printf( "Hello world from Application !\n"
"Counter: %d", g->counter);
g->counter++;
//rclose(); // We don't close the ressource file to keep the globals.
}
QUESTION:
* Un evenement est-il reentrant ?
IDEE :
Au lieu du point d'entree _exit, utilise _main et ceci :
rts
dc.l 'Pedr'
dc.w 'oM'
etc
Suivi d'un format type 'Commentaire _nostub' ?
Dans ce cas, on reserverait comme truc :
* Table d'import de libraries
* Point d'entree. (main)
* Evenement (event)
* Flags (Tableau de bit des evenements supportes)
* Dialogue ?
* Noms des extensions de la Console, suivi des points d'entree. ???
* Nom complet.
* Numero de version.
* Auteur.
* Icone 24x24.
* Touche APPS ? Faire fusionner les dialogues ?
Fonctions:
typedef void *AppId;
_globals_struct *ropen(void);
Ouverture des ressources de l'application.
ie. reallocation de l'handle de la section BSS et importation des libraries.
Doit etre appelle a l'interieur de l'application.
Si les ressources sont deja ouvertes, ne fait juste que redeference le pointeur vers ces ressources.
void rclose(void);
Fermeture des ressources de l'application.
AppId GetAppId(const char *internal_name asm("a0"));
Retourne l'AppId d'apres le nom interne (exemple: 'xwin').
Si on passe NULL, retourne l'AppId de soi meme.
EventId GetBaseEvent(AppId id asm("a0"));
Possibilite d'envoyer des events perso (>$8000)
Reservation automatique de 256 evenements pour chaque app :
La partie haute (127) = AppId / 65536 | $80.
La partie basse est laissee libre a l'app.
Pb : les evenements sont determines dynamiquements...
void *GetFirstAttribut(AppId id asm("a0"), ATTRIBUT attribut asm("d0"));
Reservation de carac intrinseque Type > $8000.
Retourne un pointeur vers la premiere donnee interne de l'application
correspondant au type desire.
void *GetNextAttribut(AppId id asm("a0"), ATTRIBUT attribut asm("d0") ,void *previous asm("a1"));
Retourne un pointeur vers les donnees internes de l'application.
Saute le pointeur precedent (recherche d'abord ce ptr puis passe au sauivant).
Fait n'importe quoi si on l'appelle en changeant AppId ou attribut par
rapport au premier appel a GetFirstAttribut.
AppId GetFirstApp(void)
Retourne la premiere application installe ou APP_NULL
AppId GetNextApp(AppId id asm("a0"))
Application suivante ou APP_NULL.
void SendEvent(EventId id asm("d0"), long num asm("d1"), long num2 asm("d2"));
Envoie un evenement aux applications installees.
void SendEventToApp(EventId id asm("d0"), long num asm("d1"), long num2 asm("d2"), AppId id asm("a0"));
Envoie un evenement a l'application selectionnee.
BOOL GrayOn(void);
void GrayOff();
void *GrayGetPlane(short plane asm("d0"));
Looks Tigcc docs.
Comment faire un systeme fenetre pour PedroM ?
Faire une application principale : le gestionnaire de fenetre.
Exemple : Nom de l'appli 'xwin'.
(Si c'est trop grand, faire deux applications).
L'appli boote par le script 'start' (Ne pas utiliser l'evenement boot).
Elle doit donc exporter une commande console : 'start xwin' par exemple.
Ca demarre le systeme et lance un systeme de gestion de fenetre.
Au demarrage :
+ Recherche des applications avec un numero d'attribut fixe a l'avance.
=> Ce sont les applications qui nous interressent.
for(AppId id = GetFirstApp() ; id != APP_NULL ; id = GetNextApp(id))
if (GetFirstAttribut(id, 0x8001) != NULL)
AddApp(id);
Ces applications exportent des attributs :
#define RESSOURCE xapp2
#include <pedrom.h>
#include <xwin.h>
ATTRIBUTS
ATTR_IMPORT_TABLE
ATTR_EVENT_FUNCTION
ATTR_XMAIN
ATTR_END
Elles accedent aux donnees du serveur graphique par un acces a la librarie (xwin).
Fichier: xapp2.res :
LIBRARY(xwin,4)
IMPORT(void , (void), EventLoop, 0)
IMPORT(XWINDOW * , (int, int, int, int), NewWindow, 1)
...
GLOBAL(AppId, Counter)
Puis le code :
void xmain(void)
{
g = ropen();
...
XWinAppId = GetAppId("xwin");
BaseEvent = GetBaseEvent(XWinAppId);
SendEventToApp(BaseEvent+XW_READY, 0, 0, XWinAppId);
SendEventToApp(BaseEvent+XW_IDLE, 0, 0, XWinAppId);
}
Note: Le ptr des ressources n'est pas valide lors d'une entree de lib (Utiliser ropen).
Note: GKeyIn peut installer des applications...
Note: On ne peut pas exporter des variables mais seulement des fonctions !
ATTR_XMAIN est definie comme suit :
#define ATTR_XMAIN DEF_ATTRIBUT(0x8001, xmain)
Comment faire un systeme multi-tache pour PedroM ?
C'est complique... Impossible proprement actuellement.
Je vais essayer d'arranger cela, mais c'est pas gagne.
TODO: Ameliorer le vocabulaire.
Vous en pensez quoi ?