% Merci a Yannick Chevallier pour la version mathjax-enabled
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{amsmath,amsfonts,amssymb}
\usepackage{listings}
\usepackage[francais]{babel}
\usepackage{times}
\usepackage{xspace}
\usepackage{makeidx}
\usepackage{ifpdf}
\ifpdf
 \usepackage[colorlinks,pdftex]{hyperref}
\else
 \usepackage[ps2pdf,breaklinks=true,colorlinks=true,linkcolor=red,citecolor=green]{hyperref}
\fi
\newcommand{\bs}{\symbol{92}}
\newtheorem{thm}{Th\'eor\`eme}
\newtheorem{prop}[thm]{Proposition}
\newtheorem{defn}[thm]{D\'efinition}
\makeindex

% \renewcommand{\cuttingunit}{subsection} (add HEVEA after % for hacha)
\input{giacfr.tex}
\ifhevea
\(
\newcommand{\R}{{\mathbb{R}}}
\newcommand{\C}{{\mathbb{C}}}
\newcommand{\Z}{{\mathbb{Z}}}
\newcommand{\N}{{\mathbb{N}}}
\newcommand{\Q}{{\mathbb{Q}}}
\newcommand{\tr}{\mbox{tr\,}}
\)
\else
\newcommand{\R}{{\mathbb{R}}}
\newcommand{\C}{{\mathbb{C}}}
\newcommand{\Z}{{\mathbb{Z}}}
\newcommand{\N}{{\mathbb{N}}}
\newcommand{\Q}{{\mathbb{Q}}}
\newcommand{\tr}{\mbox{tr\,}}
\fi

\giacmathjax
%HEVEA\renewcommand{\footertext}{}

\begin{document}
\title{$\chi$CAS pour Numworks N0110, N0115, N0120}
\author{Bernard.Parisse@univ-grenoble-alpes.fr}
\date{Novembre 2022, mai 2026}

\begin{giacjshere}

\maketitle

\ahref{khicasnwen.html}{English version}


\tableofcontents

\section{Préambule~: du calcul formel en examen pour tous!}
Le calcul formel est autorisé aux examens en France.
Un élève équipé d'une calculatrice haut de gamme (TI Nspire CX2 CAS,
HP Prime, Casio Classpad) peut s'en servir par exemple au bac, mais
un élève équipé d'une Numworks récente ne peut utiliser $\chi$CAS qu'en dehors
des examens, sauf s'il ouvre sa calculatrice 
pour la déverrouiller (cf. la section \ref{sec:unlock}) 
car à ce jour, Numworks refuse d'authentifier $\chi$CAS.
En mai 2025,
$\chi$CAS a été rendu compatible avec le mode examen des calculatrices graphiques
milieu de gamme concurrentes TI83 et Casio Graph (90e et 35eii) 
pour rendre accessible les mêmes fonctionnalités aux
élèves modestes qu'à ceux plus fortunés
qui peuvent se payer une calculatrice haut de gamme.
Mais la libre concurrence ne s'applique pas sur le marché des calculatrices,
l'élève acheteur n'a en général pas le choix du modèle qui est 
imposé par les enseignants de leur lycée. Enesignant qui travaillent
dans des conditions difficiles et dont le choix se fait
souvent d'abord sur la facilité d'utilisation en classe de seconde 
générale avec une partie du public qui ne fera pas (ou peu) de maths, 
plutôt que sur les fonctionnalités
qui seront utiles aux élèves qui souhaitent poursuivre des études
scientifiques.

Les constructeurs de calculatrices empêchent l'exécution de $\chi$CAS
en mode examen 
pour diverses raisons~: soit parce que cela fait concurrence à leur
modèle haut de gamme qui rapporte plus, soit parce qu'ils craignent (ou
prétextent craindre) être interdits aux examens dans certains pays. 
Techniquement, Numworks pourrait
très facilement authentifier $\chi$CAS et le laisser accessible 
en mode examen en France, bien plus facilement que nous l'avons
fait sur les Casio ou TI. J'ai contacté à plusieurs reprises Numworks
à ce sujet mais sans effet pour l'instant.\\
{\bf Est-il légitime de laisser une entreprise privée décider,
en fonction de ses intérêts économiques à l'étranger, des outils
autorisés ou non dans des examens publics de l'Education Nationale}~?
L'égalité est un principe constitutionnel, il devrait avoir
priorité sur d'autres considérations.\\
 Chers lecteurs, vous êtes nombreux
à consulter ce document (environ 15 000 consultations en 2025), alors si vous 
vous mobilisez pour que cela change, nous pouvons faire évoluer les choses. 
Déverrouillez votre calculatrice et celles de vos camarades
comme expliqué à la section \ref{sec:unlock}. Contactez
Numworks et demandez-leur de rendre $\chi$CAS utilisable en mode examen
en France. Ou contactez le ministère de l'Education Nationale
et demandez l'abolition du 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/irem/exammode.html}{mode examen inégalitaire}.

%% Pour \'echanger des fichiers, vous pouvez utiliser
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{ce
%% kit de connexion Numworks} ou
%%  une version \`a jour de 
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/install_fr.html}{Xcas}
%% (1.7.0-31 au moins) qui permet dor\'enavant d'\'echanger des programmes
%% entre la calculatrice et votre ordinateur.

%% Si vous trouvez cette \'evolution d\'esastreuse,
%% je vous invite \`a contacter Numworks et leur faire part de votre opinion.
%% Diffusez l'information aux personnes susceptibles de faire une
%% mise \`a jour, par exemple \`a vos camarades de lyc\'ee ou \`a vos
%% \'el\`eves si vous \^etes profs.
%% Prenez garde si vous vous connectez sur le workshop
%% de Numworks, le site vous propose cette mise \`a jour 
%% sans vous avertir que cela bloque $\chi$CAS .

%\printindex

\section{Introduction}
Ce document explique comment prendre en main et utiliser efficacement
le syst\`eme de calcul formel $\chi$CAS, une version adapt\'ee
du \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/giac_fr.html}{logiciel Xcas} pour les calculatrices Numworks N0110, N0115 ou N0120.\\
{\em N.B.~:
Ce document est interactif, vous pouvez modifier les commandes
et voir le r\'esultat de l'ex\'ecution des commandes
propos\'ees en exemple en cliquant sur le bouton \framebox{exe}.
%(ou en validant avec la touche Entr\'ee).
}

\subsection{$\chi$CAS, qu'est-ce que c'est~?}
$\chi$CAS permet de transformer votre calculatrice graphique
en calculatrice graphique formelle (CAS) pour faire du
calcul litt\'eral (d\'evelopper, factoriser, calculer
une limite, une d\'eriv\'ee, une primitive, r\'esoudre
des \'equations, faire du calcul
matriciel exact ou approch\'e, ...) et de la géométrie
analytique dans le plan et l'espace (exclusivité $\chi$CAS), fort utile
pour vérifier ses calculs en spécialité maths en terminale, cf. les sections
\ref{sec:why} et \ref{sec:bac}. 
$\chi$CAS ajoute
aussi des fonctionnalit\'es
pour les \'el\`eves qui envisagent une poursuite d'\'etudes
en sciences ou en maths~: 
grande vari\'et\'e de
repr\'esentations graphiques (champ de tangentes et solution
d'une \'equation diff\'erentielle, lignes de niveau, graphes 3d
cf. la section \ref{sec:geo3d}),
g\'eom\'etrie analytique (2d et 3d), arithm\'etique et cryptographie
(corps finis premiers et extensions, polyn\^omes, etc.), alg\`ebre,
alg\`ebre lin\'eaire, analyse num\'erique, calcul flottant
multi-pr\'ecision et certifi\'e (arithm\'etique d'intervalle), etc.

$\chi$CAS propose aussi une application tableur et une 
application de g\'eom\'etrie interactive (2d/3d), qui permet
de combler l'absence de ces fonctionnalit\'es dans le syst\`eme
Epsilon fourni par Numworks. Enfin, un interpr\'eteur MicroPython
est maintenant inclus dans $\chi$CAS pour les programmes qui n\'ecessitent
une compatibilit\'e stricte avec Python que le mode de compatibilit\'e
de Xcas n'apporte pas. Ce MicroPython est plus
complet que celui de Numworks, il comprend 
un module permettant de faire du calcul formel,
un module d'arithm\'etique (test de primalit\'e, PGCD, identit\'e de
B\'ezout),
deux modules pour faire du calcul vectoriel et matriciel
et trouver des racines de polynome et un module graphique
plus complet (polygones, cercles, formes remplies).

Toutes les fonctionnalit\'es de $\chi$CAS sont
int\'egr\'ees, on peut repr\'esenter sur un m\^eme graphique
un histogramme et un graphe de fonction et une droite, on peut \'ecrire
un programme pour faire une simulation et repr\'esenter
les r\'esultats graphiquement, ou utiliser les fonctions
math\'ematiques dans un programme en syntaxe Python ou utiliser
un programme en syntaxe Python dans le tableur.

La philosophie de $\chi$CAS est tr\`es \'eloign\'ee de celle
du syst\`eme Epsilon de la Numworks qui a des applications
cibl\'ees, conçues pour être faciles \`a utiliser en début de lycée
mais au risque de favoriser la paresse intellectuelle 
(``pas besoin de lire un manuel'' disait le fondateur de Numworks),
et le désintérêt des élèves curieux, 
les limites des fonctionnalit\'es math\'ematiques 
étant très vite atteintes.
Avec $\chi$CAS, programmé par un passionné de mathématiques 
assistées par ordinateur,
les élèves devraient avoir largement de quoi susciter 
leur curiosité intellectuelle.
Bien sur, cela suppose de faire un effort pour apprendre
comment utiliser le shell et les outils d'\'edition pour
ensuite les faire travailler harmonieusement ensemble, sans autres
limites que la m\'emoire (malheureusement trop vite remplie, et ce par choix
délibéré de bridage de Numworks sur les modèles les plus récents!, 
cf. la section \ref{sec:why}) et la vitesse
de la Numworks (tout \`a fait raisonnable pour une calculatrice).
\\
Il est donc fortement recommand\'e de conserver ce manuel dans vos signets
et de s'y référer pour une
utilisation optimale de $\chi$cas pour faire des mathématiques, 
\`a l'exception
des sections \ref{sec:dev} et \ref{sec:indep} qui
s'adressent aux programmeurs
qui souhaitent programmer leur calculatrice en C ou C++.

\subsection{Remarques importantes avant d'installer} \label{sec:install}
{\bf Le calcul formel est autorisé dans les examens
organisés par l'éducation nationale en France, par
exemple au bac. Mais, à l'étranger ou pour certains  
concours ou examens spécifiques (par exemple l'IB),
l'utilisation de calculatrices formelles est interdite en examen. 
Il est de la responsabilit\'e de l'utilisateur
de v\'erifier que les calculatrices formelles sont autoris\'ees
avant d'utiliser $\chi$CAS dans un examen ou concours. Les auteurs
ne sauraient \^etre tenus pour responsables en cas d'utilisation
non autoris\'ee.}

L'installation optimale de $\chi$CAS
dépend de votre modèle précis de calculatrice
et du numéro de version d'Epsilon que vous utilisez.
Le numéro de votre modèle de calculatrice Numworks
est inscrit à l'arrière
de votre calculatrice et le numéro de version d'Epsilon
se lit dans l'applications Paramètre, A propos. 

Afin de satisfaire certaines réglementations d'examens
à l'étranger, depuis 2021, Numworks a d\'ecid\'e 
de verrouiller ses calculatrices, ce qui rend
les applications développées par des auteurs indépendants de Numworks
nettement moins intéressantes sur ces calculatrices~:
elles sont plus difficiles à installer, doivent être
réinstallées ou réactivées après un crash ou/et un RESET et
elles ne sont pas utilisables en mode examen, même lorsque
c'est légitime (plus de détails en section \ref{sec:why}).\\
Une Numworks verrouillée peut être déverrouillée par une ou deux
méthodes~:
\begin{itemize}
\item Logicielle pour les possesseurs de certaines Numworks N0110\\
Vérifiez votre
version d'Epsilon dans Paramètres, à propos.
Si elle est
inférieure à 16, 
surtout ne faites pas de mise \`a jour votre calculatrice depuis le site de
Numworks! Installez
\ahref{https://getupsilon.web.app/}{Upsilon} 
qui ajoute une protection contre le verrouillage non intentionnel
et permet de lancer les versions récentes d'Epsilon.\\
Si votre calculatrice N0110 est
en version 16 ou plus, une faille logicielle trouv\'ee par la
communaut\'e permet dans certains cas de
\ahref{https://tiplanet.org/forum/viewtopic.php?f=113&t=25784}
{d\'everrouiller votre calculatrice} sans l'ouvrir.\\
Astuce~: si vous achetez une calculatrice Numworks d'occasion, 
demandez au vendeur s'il s'agit d'une N0110 et si le num\'ero
de version du logiciel est au plus 15.5 ou Omega/Upsilon/Khi. 
\item Matérielle (pour tous les modèles)\\
il faut disposer d'un peu de matériel (compter 20 euros, mais
cette somme est mutualisable, le matériel acquis permet de
déverrouiller un nombre non limité de calculatrices) et 
il faut ouvrir la calculatrice, mais c'est vraiment recommandé
pour utiliser $\chi$CAS, cf. la section \ref{sec:unlock},
afin de rétablir l'interopérabilité de KhiCAS en mode examen
comme c'était le cas jusqu'en 2021.
\end{itemize}
Si votre calculatrice est déverrouillée (par exemple
en suivant le mode d'emploi de la section \ref{sec:unlock}), 
passez à la section \ref{sec:unlocked16}.
Si vous ne souhaitez pas ouvrir votre calculatrice pour la déverrouiller,
passez à la section \ref{sec:n120}.
 
%% Il reste quelques N0110 d'avant 2021 et qui n'ont pas été mises à jour (avec
%% Epsilon 15.5 au plus, Omega, Upsilon ou Khi), elles
%% sont dites non verrouillées (ou déverrouillées). Les autres
%% Numworks (presque toutes) 
%% sont vendues verrouill\'ees ou ont été verrouillées
%% lors d'une mise à jour sur le site de Numworks,
%% sans avertissement préalable dans les messages
%% envoyés par Numworks incitant à faire cette mise à jour. 

\section{Déverrouillage et installation sur Numworks déverrouillée.}
\subsection{Le déverrouillage pour tous~: comment transformer votre ``Numlocked'' en ``CASworks''!} \label{sec:unlock}
{\em Le titre de cette section est un petit jeu de mot 
sur le nom de la calculatrice Numworks, 
ici l'abréviations Numlocked désigne une calculatrice {\bf num}érique 
verrouillée ({\bf locked}),
et CASworks une calculatrice {\bf CAS}, assistant portable pour 
vos travaux en mathématiques.\\ $\chi$CAS est aussi un petit jeu 
de mot, d'écriture proche de Xcas, avec une prononciation
proche de kick ass, qui signifie ``d'enfer'' ou ``qui déchire'', 
et littéralement ``botter le cul''}

{\bf Avertissement~: le déverrouillage est une opération
qui doit être menée minutieusement} pour éviter
de rendre votre calculatrice inutilisable
(temporairement en principe), faites-le uniquement lorsque
vous êtes bien réveillé! (On peut
toujours débloquer une Numworks avec un STLink, sauf
si un hasard astronomiquement improbable vous a fait passer
en mode RDP2 ce qui verrouille irréversiblement le CPU).\\
{\bf Faites bien les étapes
de vérification indiquées avant de passer à l'étape suivante}
et revenez en arrière si nécessaire.
Une fois votre calculatrice déverrouillée, je vous déconseille
de vous connecter sur le site de Numworks lorsque votre calculatrice
est connectée.

Si vous êtes impatients, passez tout de suite 
à la section \ref{sec:fast} 
puis aux sections \ref{sec:opencalc} et \ref{sec:unlockcalc}.
\\
La section \ref{sec:why} explique pourquoi c'est
important de déverrouiller sa calculatrice pour utiliser $\chi$CAS,
la section \ref{sec:materiel} liste le matériel nécessaire.
Les sections \ref{sec:patchboot} et \ref{sec:patchkernel} expliquent
comment générer les firmwares patchés \verb|bootloader_patched.bin| 
pour la flash interne et \verb|epsilonkernel_patched.bin| 
pour la flash externe de la
calculatrice. Si vous les avez obtenu par un autre moyen vous pouvez
sauter directement aux sections \ref{sec:opencalc} et \ref{sec:unlockcalc}.

{\bf Aspect juridique~:} \\
Les informations données ici pour réaliser
le déverrouillage matériel d'une calculatrice Numworks sont nécessaires
pour permettre l'interopérabilité de $\chi$CAS en mode examen,
elles sont diffusées conformément à l'article 
\ahref{https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000044365559}{L.122-6-1}
du code de la 
propriété intellectuelle
et en accord avec l'article L111-1 du code de l'éducation~:
``Le service public de l'éducation est conçu et organisé en fonction des élèves et des étudiants. Il contribue à l'égalité des chances et à lutter contre les inégalités sociales et territoriales en matière de réussite scolaire et éducative''.
\\
Les manipulations ci-dessous ont été testées plusieurs
fois sur des calculatrices différentes, mais je ne peux pas garantir 
l'exactitude pour toutes les calculatrices, en particulier
{\bf je n'ai pas de N0115 donc je n'ai pas pu tester sur N0115}, en conséquence
{\bf l'auteur décline toute responsabilité}.

{\bf N.B.~:}\\
Le code de patch du bootloader a été créé par Ayabusa. 
C'est le premier a avoir indiqué et expliqué comment effectuer le
déverrouillage matériel d'une N0120.


\subsubsection{Préparation, version abrégée pour les impatients.} \label{sec:fast}
{\bf Matériel}~: 
il faut un PC sous Linux, un ST-Link ou un Raspberry Pi, 
3 (ou parfois 4) fils Dupont male-femelle,
un tournevis torx, un trombone, une enveloppe,
cf. la section \ref{sec:materiel} pour plus de détails.\\
{\bf Logiciel}~:
il faut récupérer les fichiers à installer et éventuellement
les modifier selon votre modèle de calculatrice comme
indiqué ci-dessous (pour les personnes voulant connaitre
les détails techniques, se référer aux sections
\ref{sec:patchboot} et \ref{sec:patchkernel}).
\begin{enumerate}
\item Récupérez l'archive
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/unlock.zip}{unlock.zip}, décompressez l'archive, cela crée 3 répertoires
\verb|boot|, \verb|kernel| et \verb|unlock|.
\item Installez les logiciels nécessaires (openocd, dfu-util, hexedit, 
bsdiff, crc32)
sur le PC, sur Debian ou Ubuntu avec le script\\
\verb|boot/install_tools.sh|\\
adaptez selon votre distribution (N.B. le nom du package pour crc32
n'est pas intuitif sur Debian/Ubuntu, c'est libarchive-zip-perl...).
Optionnel, compilez le programme \verb|boot/nwcrc.cc|\\
\verb|g++ boot/nwcrc.cc -o nwcrc|
\item Sauvegardez votre flash interne et externe, par exemple depuis le
\ahref{https://ti-planet.github.io/webdfu_numworks/}{webDFU de tiplanet}
(dump internal et dump slot A).
\item Pour les N0110 et peut-être pour le N0115, récupérer le
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/n0110/bootloader_patched.bin}{bootloader d'Upsilon} et passez
à la section \ref{sec:opencalc}. \\
N0120/N0115~: si vous possédez
par ailleurs des images binaires du bootloader patché et
pour les N0120 du kernel patché, vous pouvez aussi passer
à la section \ref{sec:opencalc}.
\item N0120/N0115 1ère méthode, allez sur la page qui permet de
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/patch.html}{patcher} votre bootloader (N0120/N0115) et votre noyau (N0120),
compatible avec Epsilon 20 à 25.
\item N0120/N0115 2ème méthode (sous réserve que Numworks ne la rende pas incompatible)\\
Connectez-vous sur le site de Numworks,
récupérez l'archive
\ahref{https://my.numworks.com/firmwares/n0120/stable.dfu}
{n0120}
(ou \ahref{https://my.numworks.com/firmwares/n0115/stable.dfu}
{n0115} si l'item précédent ne fonctionne pas),
sauvegardez sous le nom \verb|n0120.dfu| (ou \verb|n0115.dfu|)
dans le répertoire \verb|boot|.
Ouvrez un terminal. Pour patcher le fichier de la flash interne,
allez dans le répertoire \verb|boot|\\
\verb|cd boot|\\
exécutez le script correspondant à votre calculatrice~:\\
\verb|./extract120.sh|\\
\verb|./extract115.sh|\\
Appliquez le patch qui permet de transformer le bootloader 25.2 en 24.10, sur n0120\\
\verb|bspatch epsiloninternal.bin boot120_2410 patchboot120_25.2to24.10|\\
sur n0115\\
\verb|bspatch epsiloninternal.bin boot115_2410 patchboot115_25.2to24.10|\\
Vérifiez sur n0120 avec \verb|crc32 boot120_2410|, vous devez trouver 60e48692, sur n0115\verb|crc32 boot115_2410| doit renvoyer 00864807.\\
Sur n0120 lancez \\
\verb|bspatch boot120_2410 bootloader_patched.bin patchboot120_24.10toyes|\\
Sur n0120, il faut encore patcher le noyau\\
\verb|bspatch kernel kernel2410 patchkernel120_25.2to24.10|\\
\verb|bspatch kernel2410 epsilonkernel_patched.bin patchkernel120_24.10took|\\
Sur n0115, on patche le bootloader uniquement avec\\
\verb|bspatch boot115_2410 bootloader_patched.bin patchboot115_24.10toyes|\\
Vous pouvez passer à la section \ref{sec:opencalc}.
\item N0120/N0115,
si aucune des deux méthodes précédentes ne s'applique, il faut consulter
la section \ref{sec:patchboot}  et les suivantes.
\end{enumerate}
Si tout s'est bien passé, vous pouvez maintenant passer
à la section \ref{sec:opencalc}.

\subsubsection{Pourquoi déverrouiller, le DPE calculatrice.} \label{sec:why}
Pour pouvoir utiliser réellement $\chi$CAS, il est
vivement conseill\'e de d\'everrouiller sa calculatrice. C'est
en particulier n\'ecessaire pour utilisation en examen lorsque
le mode examen est mis en oeuvre. Mais m\^eme sans mode examen,
le moindre appui sur reset  n\'ecessite 
une r\'einstallation partielle de $\chi$CAS sur une calculatrice
verrouill\'ee, car, depuis la version 20,
Numworks sabote au lancement d'Epsilon le secteur de lancement de toutes
les applications externes donc de $\chi$CAS (et c'est également le cas
lors d'un crash sur les versions 20 à 24).
De plus sur les N0120, vous pourrez doubler 
la quantité de mémoire vive disponible! (presque 300K disponible
pour $\chi$CAS au lieu de 120K, 128K de tas Python au lieu de 64K)
et récupérer vos données en cas de crash.
\\
Comme la
garantie constructeur est de 2 ans, si vous avez achet\'e en d\'ebut
de lyc\'ee, je vous conseille de d\'everrouiller en 
d\'ebut d'ann\'ee de terminale, au moment où cesse votre garantie
et où $\chi$CAS apporte de plus en plus de fonctionnalités absentes
de la Numworks (calcul formel bien sûr, y compris
l'arithmétique et le calcul matriciel exact, mais aussi géométrie
analytique et dans l'espace).

{\bf Le DPE, Diagnostic Perfomance Examen}\\
Voici les performances de quelques calculatrices
en fonction des sujets de bac de spé maths terminale de 2025.
Un + désigne une fonctionnalité présente, un - présente mais peu confortable.
\begin{center}
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|} \hline 
Calculatrice   &{\bf Graph 90}& Graph Math+&{\bf Graph 35eii}& Graph Light & FX92 & {\bf Numworks unlocked} & Numworks locked & TI83CE &TI82AEP& {\bf TI36XPRO} \\ 
observation    & $\chi$CAS   &             & $\chi$CAS      &             &      & déverrouillée, $\chi$CAS &verrouillée       & $\chi$CAS & \\
prix rentrée   & occas ($\approx$60?) & 70-90    & {\bf 50}          &   35        & 15-20 & occas ou {\bf 83}+0..20  &  83            &  80-90  & 60  & {\bf 20} \\
DPE            &  {\bf A+}  &  C          &  {\bf B}        &   D         & E    & {\bf A}            &    C             & B      &  C   &  D \\
proba-stats    & +        & +           &  +          &  +          &  +   & +            &    +             &  +     & +    &   + \\ 
binomial\_cdf  & +        & -           &  +          &   +         &  +   &  +           &    +             &  +     & +    &   + \\ 
graphe suite   &  +       & +           &  +          &             &     &   +          &     +            &   +    &  +   &    \\ 
premiers termes&  +       & +           &  +          &   -         &  -   & +            &    +             &  +     & +    &   - \\ 
rsolve         &   +      &             &   +         &             &      &  +           &                  &        &      &    \\ 
limit          &   +      &             &   +         &             &      &  +           &                  &  +     &      &    \\ 
solve          & +        &             &  +          &             &      &  +           &                  &  +     &      &    \\ 
fsolve         &  +       &  +          &  +          &   +         &      &  +           &    +             &  +     &  +   &   + \\ 
analytique 3D &   +       &             &             &             &      &  +           &                  &        &      &    \\ 
tests 3D      &   +       &             &             &             &      &  +           &                  &        &     &    \\ 
géométrie 3D  &   +       &             &             &             &      &  +           &                  &        &     &    \\ 
linsolve      &   +       &  +          & +           &  +          &   -  &  +           &   +              &  +     &   +  &   + \\ 
graphe fct    &   +       &  +          &  +          &   +         &      &  +           &   +              &  +     &   +  &    \\ 
dérivée       &   +       &             &   +         &             &      &  +           &                  &  +     &      &    \\ 
primitive     &   +       &             &   +         &             &      &  +           &                  &  +     &      &    \\ 
aire/courbe   &   +      &  +           &  +          &   +         &      &  +           &   +              &  +     &      &    + \\ 
tableau var.  &  +        &             &   +         &             &      &  +           &                  &  +     &      &    \\ 
mémoire RAM   &  8M      & 8M         & 512K        &  24K          &24K   & 256K ou 560K (N0120)        &  256K           & 256K    & 256K & N.A. \\
stockage flash&  13M/32  & 4.7M/32    & 1M/8        &  0/512K       &0/512K& 2M/8        & 5M/8             & 192K/4M & /4M  & 0/128K \\
\end{tabular}
\end{center}
Voir aussi \ahref{https://tiplanet.org/forum/compare.php}{le QCC de tiplanet}
qui établit une comparaison beaucoup plus complète, celui-ci
est adapté au programme de spé maths de terminale. Pour les prix
de calculatrices neuves, cf. 
\ahref{https://tiplanet.org/prix/}{le comparateur de tiplanet}.

{\bf Remarques~:}
\begin{itemize}
\item {\bf Actuellement (2025/26), l'utilisation de $\chi$CAS
est conforme \`a la r\'eglementation des examens nationaux
en France, ailleurs il revient \`a l'utilisateur 
de s'assurer de la conformit\'e
avant d'utiliser $\chi$CAS en examen.}
\item Les deux calculatrices classées A sont 
à acheter d'occasion pour les Casio ou à déverrouiller matériellement
pour les Numworks  (d'où un surcoût variable
entre 0 et une vingtaine d'euros selon le nombre de calculatrices
déverrouillée par un même matériel de déverrouillage). 
La Graph 90 est le meilleur choix à mon avis, 
le clavier a plus de touches,
il y a beaucoup plus de mémoire RAM disponible (peu de risque
que $\chi$CAS doive interrompre un calcul par manque de mémoire), il
y a beaucoup plus d'espace de stockage disponible, et il est très facile
d'y accéder (la calculatrice se comporte comme une clef USB).
La Numworks a pour elle un processeur plus rapide.\\
Chez TI, on peut installer une version de $\chi$CAS compatible
mode examen sur la 83, mais par manque
de place, c'est une version incomplète (pas de géométrie). De plus
le processeur est très lent par rapport aux Casio et Numworks.
\item Chez Casio la Graph Math+ ressemble beaucoup à la Graph 90, 
et pourrait passer
de C à A si on rend $\chi$CAS compatible en mode examen. De même pour les
Numworks N0115/N0120 si Numworks acceptait d'authentifier $\chi$CAS.
\item Si on se tourne vers une calculatrice scientifique 
pour des raisons économiques, la fx92 collège,
qui est le modèle le plus populaire au collège en France, 
me parait quand même trop limitée,<
sauf si Casio décidait d'y ajouter les fonctionnalités qu'on retrouve
dans les calculatrices scientifiques non destinées aux scolaires. La Graph
Light est vendue bien trop chère, alors que son coût de fabrication
matériel est certainement très proche de la fx92, on devrait 
la trouver vers les 25 euros, et pas 35!\\
 Pour
un prix essentiellement équivalent à la fx92 (soit 20 euros), je conseillerais
plutôt la TI36XPRO, qui est moins profilée scolaire, mais permet
de traiter 40\% d'un sujet de bac de terminale spé maths (et dispose
en plus d'un peu de calcul matriciel pour maths expertes), 
on est très proche (le confort d'utilisation en moins) de ce que
permet une Numworks verrouillée, pour 4 fois moins cher
(et même 5 fois si on l'achète dès le collège!).
\end{itemize}

La longueur de la documentation ci-dessous ne doit
pas vous faire peur, c'est précisément parce que j'étais
moi-même effrayé par l'idée d'ouvrir ma calculatrice, que j'ai
bien détaillé les étapes. Si j'y suis arrivé alors que je ne suis
pas du tout bricoleur, vous pourrez certainement y arriver! Si certaines
étapes ne vous paraissent pas claires, vous pouvez demander
des renseignements sur tiplanet.

\subsubsection{Matériel nécessaire} \label{sec:materiel}
Pour d\'everrouiller une Numworks, voici ci-dessous le mat\'eriel
que j'utilise.
Un m\^eme mat\'eriel peut bien sur servir pour d\'everrouiller plusieurs
calculatrices, par exemple tous ceux des \'el\`eves int\'eress\'es
d'une m\^eme classe. Un enseignant ou un lyc\'ee
peut ainsi en acheter un ou deux exemplaires, ramenant le cout du
d\'everrouillage \`a moins de 1 euro par calculatrice. Il faut donc~:
\begin{itemize}
\item 3 (ou parfois 4) cables de connexion Dupont male-femelle. Si vous n'en
avez pas, il suffit d'acheter un ST-Link qui en fournit. Si vos
cables sont femelle-femelle, il est possible de transformer une
extr\'emit\'e en cable male, en enfon\c{c}ant un trombone dans
l'embout, puis en retirant le trombone avec le cable. Un quatrième
cable peut être nécessaire (pour les premières N0120)\\
\includegraphics[width=10cm]{unlock1.png}
\item un tournevis torx avec la pointe adapt\'ee, pour des N0120, il
  s'agit de T6. On trouve des kits tournevis torx \`a environ 10
  euros comme celui-ci\\
\includegraphics[width=10cm]{unlock2.png}
\item un ST-Link. On trouve des clones \`a environ 10 euros.
D'autres mat\'eriels permettent d'effectuer la même opération 
par exemple un Raspberry Pi 3,
cf. \ahref{https://tiplanet.org/forum/viewtopic.php?f=113&t=25191}{ce post de tiplanet}, 
mais comme je n'en possède pas, je donnerai moins de détails.\\
\includegraphics[width=10cm]{unlock3.png}
\item un trombone
\item une enveloppe (pour ne pas perdre les vis)
\item un PC Linux o\`u on installe \ahref{https://openocd.org/}{openocd}
et \ahref{https://dfu-util.sourceforge.net/}{dfu-utils} qui sont
des packages standards des distributions Linux, par exemple sur Debian
et dérivés (Ubuntu), tapez dans un terminal la commande\\
\verb|sudo apt install hexedit bsdiff openocd dfu-util|\\ 
openocd et dfu-utils sont aussi disponible sur
Mac (installation avec brew), et sous Windows 
(on peut installer WSL pour avoir un Linux sous Windows,
je n'ai pas testé, il faudra 
probablement installer Zadig pour les drivers USB,
ou 
installer une machine virtuelle sous Linux avec par exemple
VirtualBox, ce qui est probablement plus simple).
\item Pour utiliser dfu-utils sur Linux sans faire sudo à chaque commande,
copiez le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/50-numworks-calculator.rules}{\tt 50-numworks-calculator.rules} dans  \verb|/etc/udev/rules.d|\\
\verb|sudo cp 50-numworks-calculator.rules /etc/udev/rules.d|\\
\verb|sudo udevadm control --reload-rules && sudo udevadm trigger|
\item
Si votre Linux est ancien, la version d'openocd disponible risque de ne
pas avoir de support pour le stm32h725 (le CPU de la N0120),
il est alors nécessaire de compiler openocd.
Pour cela il faut installer git et les autotools, sur Debian 
à partir de la version 11 ou Ubuntu
à partir de la version 16.04
\begin{verbatim}
sudo apt-get update
sudo apt-get install git make libtool pkg-config autoconf automake texinfo libusb-1.0-0-dev libftdi-dev libhidapi-dev libjim-dev|
\end{verbatim}
Puis
\begin{verbatim}
git clone https://github.com/openocd-org/openocd.git
cd openocd
./bootstrap
./configure --enable-stlink
make
sudo make install
\end{verbatim}
\item Récupérez l'archive
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/unlock.zip}{unlock.zip} qui contient
l'ensemble des fichiers nécessaires 
pour déverrouiller depuis le PC Linux avec openocd.
\end{itemize}

\subsubsection{Sauvegarde et patch (version courte)} \label{sec:savecalc}
Commencez par sauvegarder la flash de votre calculatrice.
Depuis votre navigateur, vous pouvez le faire sur le 
\ahref{https://ti-planet.github.io/webdfu_numworks/}{webDFU de tiplanet}
en deux actions (Dump internal et Dump slot A).
Ensuite, pour séparer le noyau de l'userland, faire sur N0120
\begin{verbatim}
dd if=flash_externe.bin of=epsilonkernel.bin bs=65536 count=1
dd if=flash_externe.bin of=epsilonuserland.bin bs=65536 skip=2
\end{verbatim}
sur N0110/N0115, remplacer \verb|skip=2| par \verb|skip=1|.
En ligne de commande avec dfu-utils (Mac/Linux), faire pour N0120
\begin{verbatim}
/bin/rm -f epsilonkernel.bin
dfu-util -i 0 -a 0 -s 0x90000000:0x10000:force -U epsilonkernel.bin
/bin/rm -f epsilonuserland.bin
dfu-util -i 0 -a 0 -s 0x90020000:0x200000:force -U epsilonuserland.bin
/bin/rm -f epsiloninternal.bin
dfu-util -i 0 -a 0 -s 0x8000000:0x80000:force -U epsiloninternal.bin
\end{verbatim}
Sur N0110/N0115 les commandes ci-dessus doivent être remplacées par
\begin{verbatim}
/bin/rm -f epsilonkernel.bin
dfu-util -i 0 -a 0 -s 0x90000000:0x10000:force -U epsilonkernel.bin
/bin/rm -f epsilonuserland.bin
dfu-util -i 0 -a 0 -s 0x90010000:0x200000:force -U epsilonuserland.bin
/bin/rm -f epsiloninternal.bin
dfu-util -i 0 -a 0 -s 0x200000:0x10000:force -U epsiloninternal.bin
\end{verbatim}

Ensuite 
\begin{itemize}
\item
Si vous avez une N0110, téléchargez le
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/n0110/bootloader_patched.bin}{bootloader d'Upsilon}, conservez le noyau installé
sur votre calculatrice.
\item
Si vous avez une N0115 et Epsilon entre 20 et 25.2, il faut 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/patch.html}{patcher le bootloader}, conservez le noyau installé
sur votre calculatrice.
\item
Si vous avez une N0120 et Epsilon entre 20 et 25, il faut 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/patch.html}{patcher le bootloader et le kernel}.
Renvoyez le noyau patché sur votre calculatrice dès maintenant 
depuis le mode récupération (Reset+6)
\end{itemize}
Si tout s'est bien passé, passez à la section
\ref{sec:opencalc}, sinon lisez la suite.

\subsubsection{Patcher un bootloader (version longue)} \label{sec:patchboot}
%{\em Section à commenter si Numworks donne l'autorisation de publier un binaire patché?}\\
Cette étape n'est pas nécessaire pour les N0110
(et peut-être pour les N0115), vous pouvez utiliser le
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/n0110/bootloader_patched.bin}{bootloader d'Upsilon} et le noyau installé
sur votre calculatrice et passer à la section
\ref{sec:opencalc}.

Sur N0120, si vous avez déjà un bootloader patché
en votre possession, passez à l'étape patcher le noyau
section \ref{sec:patchkernel}.

Si vous lisez ceci, c'est que la version courte de patch n'a pas fonctionné
ou que vous voulez en savoir plus.
Pour identifier un bootloader, on ne peut pas se fier à la version d'Epsilon
installée, car celle-ci change lors des mises à jour, alors
que le bootloader ne change pas. On pourrait utiliser la commande crc32
mais il faut prendre garde au fait que le numéro de PCB et le niveau
de sécurité sont inscrits dans la flash interne et vont donc modifier
le crc du fichier récupéré sur la calculatrice. Il vaut mieux reconstituer
le crc que Numworks affiche dans Paramètre, à propos, version du logiciel
(appuyer sur OK 4 fois). Le programme suivant permet de le faire
sur l'image firmware que vous avez récupérée~:
\begin{verbatim}
#include <stdio.h>

void swap(unsigned char &a,unsigned char &b){
  unsigned char c=a;
  a=b;
  b=c;
}

int main(int argc,char ** argv){
  if (argc<2){
    printf("Syntaxe %s filename\n",argv[0]);
    return 0;
  }
  FILE * f=fopen(argv[1],"rb");
  if (!f){
    printf("Fichier non trouvé\n");
    return 0;
  }
  const int s=0x7fa00;
  unsigned char buf[s];
  int sreal=fread(buf,1,s,f);
  if (sreal!=s){
    printf("Fichier trop court\n");
    return 0;
  }
  fclose(f);
  const unsigned p= 0x4C11DB7; // polynome utilisé par Ethernet
  unsigned res=0xffffffff; // crc32 init
  for (int i=0;i<s;i+=4){
    unsigned c= * (unsigned *) &buf[i];
    res ^= c;
    for (int j=0;j<32;j++){
      // on multiplie par x et on regarde s'il faut diviser par le polynome
      if (res&0x80000000)
        res = ((res<<1) ^ p);
      else
        res = (res<<1);
    }
  }
  printf("crc 0x%x\n",res);
  if (res==0xbd422db0 || res==0x8b36995b || res==0xaba59e0d)
    printf("!!! crc32 -> update !!!");
}
\end{verbatim}
Voici une liste de NWCRC sur des firmwares récupérés sur le site de Numworks
\begin{itemize}
\item n120 Epsilon 19.5.0: 0xf0df039a
\item n120 Epsilon 20.1.0: 0xc03b00ae
\item n120 Epsilon 20.2, 20.3 0x23cdd43d
\item n120 Epsilon 20.4: 0xf60e99be
\item n120 Epsilon 21.0 0xe3cdb333
\item n120 Epsilon 21.1, 21.2, 21.3: 0x4aa0d5e8
\item n120 Epsilon 22.1.0: 0x8b3f7585
\item n120 Epsilon 22.2.1, 23.0.0: 0x61457977
\item n120 Epsilon 23.1.0, 23.2.0: 0x47ee5196
\item n120 Epsilon 23.2.2, 3: 0x79e62089
\item n120 Epsilon 23.2.4, 5, 6: 0x2c9709fd
\item n120 Epsilon 24.1.0: 0x44aaac2c
\item n120 Epsilon 24.8, 10, 11: 0xfd4cd4ad
\item n120 Epsilon 25.2: 0xbff7994c
\end{itemize}
Si vous avez une N0120 et si la commande\\
\verb|nwcrc epsiloninternal.bin|\\
renvoie 0xfd4cd4ad, vous pouvez exécuter\\
\verb|bspatch epsiloninternal.bin bootloader_patched.bin patchboot120_24.10toyes|\\
%% le script \verb|boot/patch.sh| de l'archive 
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/unlock.zip}{unlock.zip} 
et sauter directement à la vérification. De même sur une N0115 
avec crc32 et 0x00864807\\
\verb|bspatch epsiloninternal.bin bootloader_patched.bin patchboot115_24.10toyes|\\

{\bf Procédure simplifiée pour se ramener au cas précédent}~: 
attention cela ne fonctionne peut-être plus si Numworks
l'a rendu incompatible. Connectez-vous sur le site de Numworks,
récupérez l'archive
\ahref{https://my.numworks.com/firmwares/n0120/stable.dfu}
{n0120}
ou 
\ahref{https://my.numworks.com/firmwares/n0115/stable.dfu}
{n0115},
sauvegardez sous le nom \verb|n0120.dfu| ou \verb|n0115.dfu|
dans le répertoire \verb|boot|.
Ouvrez un terminal. Pour patcher le fichier de la flash interne,
allez dans le répertoire \verb|boot|\\
\verb|cd boot|\\
exécutez l'un des deux scripts \\
\verb|./extract120.sh|\\
\verb|./extract115.sh|\\
Appliquez le patch qui permet de transformer le bootloader 25.2 en 24.10\\
\verb|bspatch epsiloninternal.bin boot120_2410 patchboot120_25.2to24.10|\\
\verb|bspatch epsiloninternal.bin boot115_2410 patchboot115_25.2to24.10|\\
Vérifiez avec \verb|nwcrc boot1?0_2410|, si vous trouvez bien 0xfd4cd4ad
sur n0120 ou 00864807 sur n0115, lancez \\
\verb|bspatch boot120_2410 bootloader_patched.bin patchboot120_24.10toyes|\\
\verb|bspatch boot115_2410 bootloader_patched.bin patchboot115_24.10toyes|

Si la procédure simplifiée échoue, commencez par copier le bootloader vers un fichier qu'on va patcher\\
\verb|cp epsiloninternal.bin bootloader_patched.bin|\\
Créez un fichier \verb|nop.bin| de 2 octets contenant le code
assembleur de l'instruction nop\\
\verb|truncate -s 2 nop.bin && hexedit nop.bin|\\
et taper les 2 octets 00 BF, puis Ctrl-X et confirmez la sauvegarde.\\
{\bf Dans la suite, on suppose que le bootloader pour N0120/N0115 
est celui récupéré sur le site de Numworks en décembre 2025. Attention
celui récupéré depuis ce printemps 2026 est différent (voir plus bas
l'analyse ghidra du bootloader 25.2 et les commandes à effectuer sur N0120). 
Pour le vérifier, taper}\\
\verb|nwcrc epsiloninternal.bin |\\
La réponse attendue est 0xfd4cd4ad pour les n0120,
Pour les n0115 la commande \verb|crc32 epsiloninternal.bin|
doit renvoyer 00864807.. Si ce n'est pas le cas, on fait
une recherche de l'offset du 1er verrouillage du bootloader\\
\verb?hexdump -v -e '/1 "%02X "' epsiloninternal.bin | grep -b -o "30 62 00 21 F2 6B 07 20"?\\
Vous devez voir une sortie analogue à\\
\verb|115770:30 62 00 21|\\
Il suffit alors de diviser par 3 l'entier avant le : pour avoir l'offset
du premier octet à modifier. Ici 115770/3=38590
en décimal, ssoit 0x96be en hexa.
Si la commande ci-dessus ne renvoie rien ou renvoie plusieurs valeurs, il faudra
faire une analyse du bootloader avec 
\ahref{https://ghidralite.com/}{ghidra}, 
de manière analogue à
ce qui est détaillé ci-dessous pour patcher un noyau.
Quelques valeurs de ce premier offset qui remplace 38590 (0x96be) ci-dessous
\begin{itemize}
\item Epsilon 21: 61482/3=20494 (0x500E)
\item Epsilon 22-2-1 à 23.2.6: 60366/3=20122 (0x4e9a)
\item Epsilon 24-1-0: 60378/3=20126 (0x4e9e)
\item Epsilon 24-5 à 24-10: 115770/3=38590 (0x96be)
\item Epsilon 25-2: 115686/3=38562 (0x96a2)
\end{itemize}
Rajouter 12 pour le 2ème offset.
Epsilon 19.5 et 20 (nwcrc 0xf60e99be) n'utilisent pas le même régistre, 
il faut donc adapter\\
\verb?hexdump -v -e '/1 "%02X "' epsiloninternal.bin | grep -b -o "20 62 00 21 E2 6B 07 20"?\\
et on trouve 60048/3=20016 (0x4E30) pour Epsilon 20 et 62070/3=20690 (0x50D2)
pour Epsilon 19.5.

Sur n0120, on désactive le verrouillage aux offset 0x96BE et 0x96CA 
(offsets
déterminés en cherchant un accès aux régistres 0x52002020 et 0x5200203c) par~:
\begin{verbatim}
echo N0120 Bootloader Disable RDP lock and internal flash protection
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=38590 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=38602 conv=notrunc
\end{verbatim}
% n115: 0x7806 2 nop, 0x7818 patchs de 4 octets (au lieu de 2) donc 2 nop

Sur n0115, il faut désactiver l'écriture sur le régistre 0x40023c14 aux offset
0x7806 et 0x7818 en version 24.10
(il y a 4 octets à patcher, donc 2 écritures de nop pour
un offset)~:
\begin{verbatim}
echo N0115 24.10 Bootloader Disable RDP lock and internal flash protection
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30726 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30728 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30744 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30746 conv=notrunc
\end{verbatim}
Sur d'autres versions du bootloader n0115, on peut chercher avec 
le script suivant
\begin{verbatim}
#! /bin/bash
hexdump -v -e '/1 "%02X "' $1 | grep -b -o "C5 F8 14 0C 10 21 D5 F8"
\end{verbatim}
Quelques valeurs~:
\begin{itemize}
\item Epsilon 21.1: 93078/3=31026 (0x7932) 
\item Epsilon 23.2.3: 93102/3=31034 (0x793A)
\item Epsilon 24.10: 30726 (0x7806)
\item Epsilon 25.2: 91758/3=30586 (0x777A)
\end{itemize}


Pour vérifier rapidement sans lancer ghidra, vous pouvez utiliser le script
\verb|disasm| suivant
\begin{verbatim}
#!/bin/bash

# On s'assure que l'adresse a bien été fournie
if [ -z "$1" ]; then
    echo "Usage: $0 <adresse_hexa> fichier (exemple d'adresse: $0 a000)"
    exit 1
fi

# On ajoute le préfixe 0x à l'adresse fournie (ex: a000 -> 0xa000)
start_hex="0x$1"

# On calcule l'adresse de fin (+4 octets) en disant à Bash de calculer en hexa
# $(( ... )) gère l'hexa nativement si la variable commence par 0x
stop_hex=$(printf "0x%x" $(($start_hex + 100)))

# Exécution de la commande
arm-none-eabi-objdump -b binary -D -m arm -M force-thumb \
    --start-address="$start_hex" \
    --stop-address="$stop_hex" \
    $2
\end{verbatim}
Ainsi \verb|disasm 7806 bootloader_patched.bin| renvoie avant patch
\begin{verbatim}
00007806 <.data+0x7806>:
    7806:	f8c5 0c14 	str.w	r0, [r5, #3092]	; 0xc14
    780a:	2110      	movs	r1, #16
    780c:	f8d5 2c14 	ldr.w	r2, [r5, #3092]	; 0xc14
    7810:	2017      	movs	r0, #23
    7812:	f7f8 fcec 	bl	0x1ee
    7816:	2300      	movs	r3, #0
    7818:	f8c5 0c14 	str.w	r0, [r5, #3092]	; 0xc14
    781c:	2007      	movs	r0, #7
    781e:	f8d5 2c1c 	ldr.w	r2, [r5, #3100]	; 0xc1c
    7822:	4619      	mov	r1, r3
    7824:	f7f8 fce3 	bl	0x1ee
    7828:	f8c5 0c1c 	str.w	r0, [r5, #3100]	; 0xc1c
\end{verbatim}
on voit bien l'écriture avec str (store) à l'offset 0xc14 (3092 en décimal) 
au-delà du régistre r5. Une fois le patch fait les écritures 
sont remplacées par des nop.

% devrait aussi fonctionner sur n0110, mais il faut regarder aussi BOOT1, régistre 0x40023c18
On pourrait ensuite se contenter de 
désactiver le controle de signature un peu plus loin.
Ayabusa nous propose une solution plus complète, qui permet
également de booter sur le bootloader ST, ce qui permettra
de mettre à jour ultérieurement le bootloader
lui-même sans avoir besoin d'ouvrir à nouveau la calculatrice.
Pour cela, après le test de reset+6 effectué par le code de Numworks
pour pouvoir flasher la flash externe,
on teste si la touche 1 est pressée pendant le reset.
Si oui, on lance le bootloader ST, sinon on lance le slot A en 0x90000000.
Voici le \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/main.bin}{le code compilé pour n0120}
(\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/main.s}{code source assembleur n0120 correspondant}),
 le \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/main115.bin}{le code compilé pour n0115}
(\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/main115.s}{code source assembleur n0115 correspondant})
et deux ressources graphiques
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/image.bin}{image.bin} et
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/about.bin}{about.bin}
prêts à être patché aux offsets 0xbc00, 0xC0C0, 0xC730~\\
\verb|dd if=image.bin of=bootloader_patched.bin bs=1 seek=49344 conv=notrunc|\\
\verb|dd if=about.bin of=bootloader_patched.bin bs=1 seek=50992 conv=notrunc|\\
Puis sur n0120 faire\\
\verb|dd if=main.bin of=bootloader_patched.bin bs=1 seek=48128 conv=notrunc|\\
et ssur n0115\\
\verb|dd if=main115.bin of=bootloader_patched.bin bs=1 seek=48128 conv=notrunc|\\

Il faut maintenant que ce code assembleur soit lancé depuis le code 
du bootloader.
Sur les n0120 internal 24.10, on crée un fichier de jump par\\
\verb|truncate -s 4 jump_new.bin && hexedit jump_new.bin|\\
on écrit les octets \verb|03 F0 89 FB|, puis Ctrl-X et on confirme
la sauvegarde. On détourne alors un saut à l'offset 0x84EA sur 
les n0120 internal 24.10
(l'appel initial effectuait un affichage par pushrectuniform) par\\
\verb|dd if=jump_new.bin of=bootloader_patched.bin bs=1 seek=34026 conv=notrunc|\\
Sur les n115 en internal 24.10 ou 24.11: le saut équivalent est à
l'offset 0x79b6, saut à faire vers offset bc00, code assembleur
\verb|04 F0 23 F9| à placer dans\\
\verb|truncate -s 4 jump_115.bin && hexedit jump_115.bin|\\
Détournement du saut~:\\
\verb|dd if=jump_115.bin of=bootloader_patched.bin bs=1 seek=31158 conv=notrunc|\\
Passez alors à la vérification en section \ref{sec:verifboot}.\\
Pour une autre version de bootloader, vous pouvez localiser l'offset
à détourner avec la commande\\
\verb?hexdump -v -e '/1 "%02X "' $1 | grep -b -o "6B 46 10 68 51 68"?\\
par exemple sur n0120 en 25.2, on obtient 101928,
on divise l'offset par 3: 101928/3=33976 (0x84B8) et on ajoute 12 (0xc), 
16 (0x10) ou 20 (0x14) ou 22 (0x16)
ce qui donne 33988 (0x84c4) ou ... ou 33998 (0x84CE), 
c'est là. On vérifie au désasssembleur
\begin{verbatim}
./disasm 84b8 boot120_25.2
000084b8 <.data+0x84b8>:
    84b8:	466b      	mov	r3, sp
    84ba:	6810      	ldr	r0, [r2, #0]
    84bc:	6851      	ldr	r1, [r2, #4]
    84be:	c303      	stmia	r3!, {r0, r1}
    84c0:	4b5b      	ldr	r3, [pc, #364]	; (0x8630)
    84c2:	881a      	ldrh	r2, [r3, #0]
    84c4:	f7f7 ff64 	bl	0x390
    84c8:	f7fe fae4 	bl	0x6a94
    84cc:	2f00      	cmp	r7, #0
    84ce:	f000 809c 	beq.w	0x860a
\end{verbatim}
Reste à calculer le saut vers 0xbc00, le plus simple est d'utiliser 
l'assembleur et objdump.
\begin{verbatim}
@ Fichier source pour ARM32 Thumb-2, compilation avec arm-none-eabi-as -mthumb -o jump.o jump.s, ensuite faire arm-none-eabi-objdump -D jump.o
.syntax unified
.cpu cortex-m4        @ Ou un autre processeur supportant le Thumb-2
.thumb

.section .text
.org 0x0000          @ On commence à l'offset 0 du fichier

@ On remplit le fichier jusqu'à l'offset 0x84EA
@ pour simuler le positionnement dans votre binaire
@ .space 0x84ea
.space 0x84ce
	
.global _start
_start:
    bl target_address @ L'assembleur calculera 03 f0 89 fb

@ On remplit l'espace entre le saut et la cible
.org 0xbc00
target_address:
	nop               @ Destination du saut
\end{verbatim}


Si votre bootloader n'est pas celui listé et qu'il faut le rendre
inoffensif avec \ahref{https://ghidralite.com/}{ghidra}, 
voici des pistes pour l'analyser.
Importer (I) epsiloninternal.bin, en choisissant comme langage 
cortex dans filtre puis little endian,
cliquer sur options, 
adresse de début 0x200000 pour N0110/N0115 et 0x8000000 pour N0120,
lancer le fichier, puis valider pour l'analyser par ghidra.
Rajouter depuis le menu Window/Memory avec le bouton vert +
une plage d'adresses pour
les régistres début 40000000 (hexa), longueur 0x40000000,
sauvegardez et fermez.
Recherchez (touche G) 
les références vers 52002020 et 5200203c sur N0120,
40023c14 sur N0110/N0115 pour éviter le verrouillage en RDP1
et laisser la flash interne accessible en écriture.
Sur n0120 Epsilon 25.2, l'offset de début de setoptionbytes est 0x9678
au lieu de 0x9694 en 24.8, donc il faut décaler de 28 (0x1c) octets, 
le patch nop.bin s'écrit en 38590-28=38562 (0x96a2=0x96be-0x1c) et en 
38602-28=38574 (0x96ae=0x96ca-0x1c).

Eventuellement chercher aussi 40023c18 pour les modifications
des adresses de boot sur N0110/N0115 ou 52002044 sur N0120
(utilisé par une fonction appelée deux fois avec paramètre 0 et 1
pour gérer les adresses de boot0 et boot1), pas vraiment utile
sauf si on veut tester le bootloader d'une N0115 sur une N0110
en conservant l'adresse de boot1 pour reset+6 en remplaçant 
l'appel de cette fonction par des nop.

On peut alors simplement annuler les vérifications signatures
en cherchant depuis la fonction main du bootloader (aller en offset
4 du firmware avec G 200004 sur n0110/n0115 ou G 8000004 sur n0120, 
taper P puis double-cliquer sur l'adresse). La fonction
main du bootloader commence par configurer la mémoire (MPU, écritures
en 0xe000eda0...), puis d'autres périphériques,
puis la flash externe (écritures en 52004000 sur
n0120, a0000000 sur n0110), puis le LCD (60000000).
Les vérification
de signature sont dans un appel de fonction situé presque à la fin de cette
fonction main, fonction
que l'on pourrait nommer chkslots\_run. Pour la repérer, partez
de la fin de la fonction, cherchez dans la fenêtre de décompilation
à droite l'instruction setMainStackPointer en rouge. L'instruction
suivante (hors du test) est normalement un appel à la fonction aléatoire,
puis un appel de l'instruction de copie mémoire du bootloader,
puis c'est l'appel à la fonction chkslots\_run qui appelle
une fonction setboot0boot1 qui modifie
les adresses de boot (il y a 2 appels consécutifs 
de cette fonction pour boot0 et boot1), 
assez au début, et peut donc aussi se repérer
parce qu'il référence 52002044 sur n0120 ou 40023c18 sur n110/115~: taper
G puis 52002044 ou 40023c18, cliquer sur la fonction qui référence
ce régistre, remonter au début de cette fonction, cliquer sur la 
fonction appelante, c'est chkslots\_run.
\\
Si on veut un bootloader permettant de lancer le bootloader ST
comme c'est fait dans main.s ou main115.s,
il faut ensuite analyser un peu le code du bootloader Numworks pour
rajouter les appels vers l'activation de l'écran. Les deux
régistres permettant de communiquer avec le LCD sont 60000000
et 60020000, cela permet de localiser où détourner le code
pour aller à la fonction 
de boot/main.s (n0120) ou boot/main115.s (n0115). \\
Reste à trouver un endroit où détourner un saut vers l'offset 0xbc00,
juste avant la vérification des signatures.
La fonction chkslots est à l'offset 0x82fc sur 25.2 (n0120) et 0x8318 sur 
24.8 et 24.10,
avec le même décalage de 0x1c octets, et l'offset 0x84ea 
(qui effectue un beq.w sur 24.8)
correspond à l'offset 0x84ce sur 25.2, donc jumpnew.bin doit être légèrement
modifié (saut de 28 octets de plus) en \verb|03 f0 97 fb| et écrit en 
offset 33998=34026-28=0x84ce\\
Sur Epsilon 20.4 (nwcrc 0xf0df039a), l'adresse équivalente pour le détournement 
est 0x08007F6E.
\\
Si vous avez réussi, conservez le bsdiff du bootloader initial
et bootloader patché, pour pouvoir le communiquer à d'autres personnes
ayant le même bootloader que le votre\\
\verb|bsdiff epsiloninternal.bin bootloader_patched.bin boot.bsdiff|

Donc, {\bf les commandes pour le bootloader 25.2 sur n0120}\\
\begin{verbatim}
echo N0120 Bootloader Disable RDP lock and internal flash protection
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=38562 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=38574 conv=notrunc
echo add code to bc00
dd if=main.bin of=bootloader_patched.bin bs=1 seek=48128 conv=notrunc
dd if=image.bin of=bootloader_patched.bin bs=1 seek=49344 conv=notrunc
dd if=about.bin of=bootloader_patched.bin bs=1 seek=50992 conv=notrunc
echo Jump to bc00
truncate -s 4 jump_new.bin && hexedit jump_new.bin
\end{verbatim}
écrire les 4 octets 03 f0 97 fb, Ctrl-X, confirmer la sauvegarde, puis
\begin{verbatim}
dd if=jump_new.bin of=bootloader_patched.bin bs=1 seek=33998 conv=notrunc
\end{verbatim}
On vérifie avec ghidra ou avec un désassembleur\\
\verb|arm-none-eabi-objdump -b binary -D -m arm -M force-thumb --start-address=38562 --stop-address=38564 bootloader_patched.bin|\\
\verb|arm-none-eabi-objdump -b binary -D -m arm -M force-thumb --start-address=38574 --stop-address=38576 bootloader_patched.bin|\\
\verb|arm-none-eabi-objdump -b binary -D -m arm -M force-thumb --start-address=33998 --stop-address=34002 bootloader_patched.bin|\\
avant les commandes dd de patch on a deux commande de stockage (str)
et un branchement conditionnel beq.w, 
après on a deux instructions nop et un saut inconditionnel bl en 0xbc00.

{\bf Pour N0115, Epsilon 25.2, il y a un décalage de 140 octets (recul)}
\begin{verbatim}
echo N0115 25.2 Bootloader Disable RDP lock and internal flash protection, 0x777a, 0x777c, 0x778c, 0x778e
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30586 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30588 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30604 conv=notrunc
dd if=nop.bin of=bootloader_patched.bin bs=1 seek=30606 conv=notrunc
\end{verbatim}
Les ajouts\\
\verb|dd if=main115.bin of=bootloader_patched.bin bs=1 seek=48128 conv=notrunc|\\
\verb|dd if=image.bin of=bootloader_patched.bin bs=1 seek=49344 conv=notrunc|\\
\verb|dd if=about.bin of=bootloader_patched.bin bs=1 seek=50992 conv=notrunc|\\
Enfin, le saut à détourner est à l'offset 0x792a. Le fichier de saut
se crée avec\\
\verb|truncate -s 4 jump_new.bin && hexedit jump_new.bin|\\
où l'on met les 4 octets 04 f0 69 f9,
puis
\begin{verbatim}
dd if=jump_new.bin of=bootloader_patched.bin bs=1 seek=31018 conv=notrunc
\end{verbatim}
On vérifie avec\\
\verb|arm-none-eabi-objdump -b binary -D -m arm -M force-thumb --start-address=31018 --stop-address=31022 bootloader_patched.bin|\\
le saut conditionnel devient un branchement bl vers 0xbc00.



\subsubsection{Vérification du bootloader patché} \label{sec:verifboot}
Pour vérifier, exécutez la commande \verb|hexedit bootloader_patched.bin|, 
tapez la touche entrée suivie des offsets à vérifier.\\
Sur les n0120 en version 24.10, vérifiez les offsets  84ea, 96be, 96ca, bc00
\begin{verbatim}
000084E0   F7 F7 56 FF  FE F7 62 F9  00 2F 03 F0  89 FB 58 4C  ..V...b../....XL
...
000096B0   2B 46 08 21  32 6A 0F 20  FC F7 2A F9  23 46 00 BF  +F.!2j. ..*.#F..
000096C0   00 21 F2 6B  07 20 FC F7  23 F9 00 BF  BD E8 70 40  .!.k. ..#.....p@
...
0000BC00   FF B5 00 27  79 4C A0 47  4F F0 00 00  78 49 41 F2  ...'yL.GO...xIA.
...
\end{verbatim}
Si tout va bien, passez à la section suivante \ref{sec:patchkernel}

Sur les n0115, vérifiez en  7806, 7818,  79b6, bc00
\begin{verbatim}
00007800   F8 F7 F5 FC  00 23 00 BF  00 BF 10 21  D5 F8 14 2C  .....#.....!...,
00007810   17 20 F8 F7  EC FC 00 23  00 BF 00 BF  07 20 D5 F8  . .....#..... ..
...
000079B0   F8 F7 84 FE  00 2F 04 F0  23 B9 56 4C  1E 21 01 23  ...../..#.VL.!.#
...
0000BC00   FF B5 00 27  76 4C A0 47  4F F0 00 00  75 49 41 F2  ...'vL.GO...uIA.
\end{verbatim}
Si tout va bien, passez à la section \ref{sec:opencalc}


\subsubsection{Patcher le noyau (version longue)} \label{sec:patchkernel}
Cette étape n'est pas nécessaire si vous avez un noyau patché
ou sur N0110/N0115,
dans ce cas passez à l'étape Ouverture de la calculatrice,
section \ref{sec:opencalc}. 

Pour connaitre le numéro de version de votre noyau, vous pouvez
regarder dans l'application Paramètres ou taper\\
\verb|hexedit epsilonkernel.bin|\\
et regarder à partir de l'offset 0xc (si hexedit n'est pas installé,
il s'installe comme tous les paquets standards de votre distribution
Linux, par exemple sur Debian ou Ubuntu avec \verb|sudo apt install hexedit|).

{\bf Procédure simplifiée pour noyau 24.10 (sur N0120)}\\
\verb|bsdiff epsilonkernel.bin epsilonkernel_patched.bin patchkernel120_24.10took|\\
Pour Epsilon 25.2 (récupéré avec le bootloader précédemment), on convertit le bootloader en 24.10 puis on le patche comme ci-dessus\\
\verb|bspatch epsiloninternal.bin kernel2410 patchkernel120_25.2to24.10|\\
\verb|bspatch kernel2410 epsilonkernel_patched.bin patchkernel120_24.10took|\\
Vérifiez.

{\bf Patcher un noyau 24.10 ou 24.11 pour N0120, version courte}\\
Si vous avez le noyau 24.10 ou 24.11 de Numworks (ils sont identiques
sauf pour le numéro et identifiant de version), vous pouvez le patcher
 à l'aide du script \verb|kernel/patch_2410.sh|. Avec un noyau
24.8, exécutez \verb|kernel/patch_2408.sh|.\\
{\bf Vérifiez sur 24.10/11 avec \verb|hexedit epsilonkernel_patched.bin|~}:
\begin{verbatim}
00000000   00 00 00 00  98 44 16 00  F0 0D C0 DE  32 34 2E 31  .....D......24.1
00000010   30 2E 30 00  63 63 37 39  36 62 37 00  F0 0D C0 DE  0.0.cc796b7.....
...
00001D80   11 46 FE F7  97 FB 00 28  36 D1 00 BF  33 46 08 21  .F.....(6...3F.!
00001D90   0F 20 FE F7  63 FB 2B 46  20 62 00 21  00 BF 07 20  . ..c.+F b.!...
...
00004920   00 60 05 F1  00 65 00 BF  00 BF 3F 48  32 46 38 49  .`...e....?H2F8I
...
00004D00   D4 F8 98 2D  FB F7 AA FB  C4 F8 98 0D  4F F0 00 50  ...-........O..P
00004D10   FD F7 1A F8  D4 F8 A0 2D  1C 23 01 21  05 20 FB F7  .......-.#.!. ..
\end{verbatim}
Votre noyau est prêt, avec une protection anti-crash
(voir explications en fin de cette section),
vous pouvez passer à 
la section suivante \ref{sec:opencalc} Ouvrir la calculatrice,

%% Le script pour 24.10 utilise le fichier
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/kernel/kernel2410.bsdiff}{kernel2410.bsdiff}
%% en tapant la commande\\
%% \verb|bspatch epsilonkernel.bin epsilonkernel_patched.bin kernel2410.bsdiff|\\
%% (il faut avoir installé le package \verb|bsdiff|).\\


Si vous lisez ceci, vous être sur une n0120 et vous n'avez
pas un noyau 24.10/11 ou vous voulez des détails. On souhaite donc
rendre le noyau inoffensif et on va également autoriser
l'accès \`a presque toute la RAM de votre calculatrice (on
passe de 256 à 500K de RAM).
Sur les n0110/n0115, les noyaux sont
en principe inoffensifs, et il n'y a (essentiellement) pas
de RAM supplémentaire utilisable. 
L'étape qui suit est donc inutile sur n0110/n0115 ou
si vous disposez déjà d'une manière
ou d'une autre d'un noyau inoffensif pour n0120,
dans ce cas sautez directement à Ouverture de la calculatrice. 
La rediffusion publique
d'un noyau inoffensif est très probablement couverte par 
l'article L122-6-1 du code
de la propriété intellectuelle sur l'interopérabilité, mais
ne souhaitant pas être importuné, je préfère donner les informations
qui permettent de rendre un noyau inoffensif.

Astuce~: pour s'assurer de ne pas reflasher un bootloader qui
verrouille la calculatrice sur n0120, vous pouvez ajouter une
copie de votre bootloader patché après votre noyau patché\\
\verb|cp epsilonkernel.bin kernel && cat kernel bootloader_patched.bin > epsilonkernel.bin|\\
ainsi si votre patch du noyau a manqué un code de reflashage du bootloader,
c'est votre bootloader libre qui s'exécutera.


{\bf Rendre inoffensif un noyau 24.8 pour N0120}\\
On crée d'abord un fichier nop.bin pour patcher le noyau\\
\verb|truncate -s 2 nop.bin && hexedit nop.bin|\\
on met les 2 octets \verb|00 BF|, puis Ctrl-X, confirmer.
Puis un deuxième fichier\\
\verb|truncate -s 1 mpusize.bin && hexedit mpusize.bin|\\
on met l'octet \verb|1C|, puis Ctrl-X, confirmer. 
\begin{verbatim}
echo Patching kernel...
cp epsilonkernel.bin epsilonkernel_patched.bin
echo Kernel 24.8 disable RDP lock and internal flash protection
# 0x1ddc 0x1de8 -> nop
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=7644 conv=notrunc
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=7656 conv=notrunc
echo Kernel 24.8 Do not rewrite extra bytes to internal flash
# 0x491a 0x491c -> nop
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=18714 conv=notrunc
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=18716 conv=notrunc
echo
# 0x4d02 00 instead of 0x10, MPU start at 0x20000000 instead of 0x24000000
# 0x4d0c 0x1c instead of 0x11, MPU ram region increase size to 0x20000000
truncate -s 1 zero.bin
dd if=zero.bin of=epsilonkernel_patched.bin bs=1 seek=19714 conv=notrunc
dd if=mpusize.bin of=epsilonkernel_patched.bin bs=1 seek=19724 conv=notrunc
\end{verbatim}
Vérifiez avec \verb|hexedit epsilonkernel_patched.bin| le numéro
de version et les changements 
aux offsets 1ddc, 1de8, 491a, 491c, 4d02, 4d0c.
\begin{verbatim}
00000000   00 00 00 00  68 3E 16 00  F0 0D C0 DE  32 34 2E 38  ....h>......24.8
00000010   2E 30 00 00  62 65 61 34  38 38 36 00  F0 0D C0 DE  .0..bea4886.....
...
00001DD0   33 46 08 21  0F 20 FE F7  41 FB 2B 46  00 BF 00 21  3F.!. ..A.+F...!
00001DE0   E2 6B 07 20  FE F7 3A FB  00 BF BF F3  4F 8F 01 23  .k. ..:.....O..#
...
00004910   3D 49 4F F0  00 60 05 F1  00 65 00 BF  00 BF 3F 48  =IO..`...e....?H
...
00004D00   4F F0 00 50  FD F7 42 F8  D4 F8 A0 2D  1C 23 01 21  O..P..B....-.#.!
\end{verbatim}
Si vous voulez utiliser ce noyau avec des versions de userland dont
le numéro de version diffère, vous pouvez le changer (offsets 0xc à 0x13).

{\bf Rendre inoffensif un noyau 24.10/11 sur N0120}\\
On utilise la même procédure que précédemment avec des adresses 
qui diffèrent un peu~:
\begin{verbatim}
echo Patching kernel...
cp epsilonkernel.bin epsilonkernel_patched.bin
echo Kernel 24.10 disable RDP lock and internal flash protection
# 0x1d8a 0x1d9c -> nop
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=7562 conv=notrunc
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=7580 conv=notrunc
echo Kernel 24.10 Do not rewrite extra bytes to internal flash
# 0x4926 0x4928 -> nop
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=18726 conv=notrunc
dd if=nop.bin of=epsilonkernel_patched.bin bs=1 seek=18728 conv=notrunc
# 0x4d0e 00 instead of 0x10, MPU start at 0x20000000 instead of 0x24000000
# 0x4d18 0x1c instead of 0x11, MPU ram region increase size to 0x20000000
truncate -s 1 zero.bin
dd if=zero.bin of=epsilonkernel_patched.bin bs=1 seek=19726 conv=notrunc
dd if=mpusize.bin of=epsilonkernel_patched.bin bs=1 seek=19736 conv=notrunc
\end{verbatim}
Vérifiez (voir ci-dessus le hexedit pour 24.10/11).

{\bf Rendre inoffensif un autre noyau N0120}\\
Méthode 1~: sans ghidra.\\ 
On commence par désactiver le verrouillage avec\\
\verb|./findboot120offset1 epsilonkernel.bin|\\
qui exécute la commande\\
\verb?hexdump -v -e '/1 "%02X "' $1 | grep -b -o "20 62 00 21 E2 6B 07 20"?\\
La commande semble fonctionner depuis Epsilon 20,
elle affiche un entier, à diviser par 3 pour avoir le premier offset 
où le noyau écrit les options bytes. Par exemple avec Epsilon 24.10 sur n0120
on obtient\\
\verb|22932:20 62 00 21 E2 6B 07 20|\\
il faut donc écrire 00 BF à l'offset 7644 (0x1ddc) et aussi
12 (0xc) octets plus loin en 7656 (0x1de8). 
On confirme avec\\
\verb|disasm 1ddc epsilonkernel.bin|
\begin{verbatim}
    1ddc:	6220      	str	r0, [r4, #32]
    1dde:	2100      	movs	r1, #0
    1de0:	6be2      	ldr	r2, [r4, #60]	; 0x3c
    1de2:	2007      	movs	r0, #7
    1de4:	f7fe fb3a 	bl	0x45c
    1de8:	63e0      	str	r0, [r4, #60]	; 0x3c
    1dea:	f3bf 8f4f 	dsb	sy
    1dee:	2301      	movs	r3, #1
\end{verbatim}
Pour annuler la réécriture de la flash interne, on utilise\\
\verb?hexdump -v -e '/1 "%02X "' $1 | grep -b -o "4F F0 00 60 05 F1 00 65"?\\
l'offset à neutraliser se situe 8 octets plus loin. Par exemple
avec un kernel 20.2, on obtient 32136/3 soit 0x29d8, on ajoute 8, on
trouve 0x29e0. Et au désassemblage on a\\
\verb|./disasm 29d8 kernel120_20.2|
\begin{verbatim}
000029d8 <.data+0x29d8>:
    29d8:	f04f 6000 	mov.w	r0, #134217728	; 0x8000000
    29dc:	f105 6500 	add.w	r5, r5, #134217728	; 0x8000000
    29e0:	f7fe fa94 	bl	0xf0c
\end{verbatim}
on écrit donc 00 BF 00 BF à l'offset 0x29e0.\\
Pour augmenter la RAM disponible,  on part de la fonction
main du kernel, qu'on lit à l'offset 0x24, apr exemple 0x90004bd8
pour le kernel 24.10 (en fait on lit d9 4b 00 90 car le processeur
est little endian et ajoute 1 pour indiquer le mode thumb). On ajoute
0x100, et on déssassemble\\
\verb|disasm 4cd8 epsilonkernel.bin|\\
jusqu'à trouver\\
\verb|... f04f 5010 	mov.w	r0, #603979776	; 0x2400000|\\
il faut modifier l'octet 10 et mettre 0 à la place.
Localissation par script\\
\verb?hexdump -v -e '/1 "%02X "' $1 | grep -b -o "C4 F8 98 0D 4F F0 10 50"?\\
remplacer le 10 à l'offset (entier avant : divisé par 3 plus 6) par 0.


Méthode 2; avec \ahref{https://ghidralite.com/}{ghidra}.
\begin{itemize}
\item Faisons d'abord une copie du noyau que l'on va modifier\\
\verb|cp epsilonkernel.bin epsilonkernel_patched.bin|
\item  Téléchargez \ahref{https://ghidralite.com/}{ghidra} 
s'il n'est pas installé sur votre ordinateur,
puis lancez-le, puis Import File, chargez le fichier 
à analyser \verb|epsilonkernel.bin|. Le
``language'' à utiliser est Cortex ARM32 little endian
(mettre cortex dans Filter pour le faire apparaitre puis double-cliquer), 
cliquer ensuite sur le bouton options 
et mettre pour l'adresse 90000000. 
\item Puis double-cliquez sur \verb|epsilonkernel.bin|. Vous pouvez faire 
OK pour lancer l'analyse.
Il faudra refaire une analyse une fois la zone mémoire des régistres créée.
\item Ouvrir
maintenant dans le menu Windows, Memory map, cliquez sur le bouton +, donnez
comme nom de zone registers, adresse de base 40000000, longueur 0x20000000.
\item 
Ensuite menu Analyse, auto-analyse, cocher Decompiler Parameter ID et lancez
l'analyse.
\item  Une fois
l'analyse faite, vérifiez que la fonction main du kernel est 
bien désassemblée. L'adresse de cette fonction se lit à l'offset 0x24
du kernel, tapez G puis 90000024, puis la touche P puis
double cliquez sur l'adresse. S'il n'y a pas de code désassemblé, tapez
sur la touche D. Puis sur la touche F pour forcer une fonction,
vous pouvez lui donner un nom, par exemple main en tapant L.
\item Allez en 52002020 (touche G), puis regardez où le régistre
est référencé, il devrait l'être une fois en lecture (R) et une fois en
écriture (W). S'il ne l'est pas, alors il faut forcer le désassemblage
en tapant D dans la zone qui référence un des régistres voisins 
(en cherchant de part et d'autre de 52002020 une référence).
Cliquez sur l'adresse en écriture,
 il va falloir remplacer l'adresse d'écriture de ce régistre 
par une instruction
nop à l'adresse correspondante. On lit par exemple pour le noyau 24.8\\
\verb|        90001ddc 20  62           str        param_1 ,[r4 ,#0x20 ]=> DAT_52002020                = ??|\\
ou pour le noyau 24.10/11\\
\verb|        90001d98 20  62           str        param_1 ,[r4 ,#0x20 ]=> DAT_52002020                = ??|\\
Pour modifier, faire\\
\verb|hexedit epsilonkernel_patched.bin|\\
validez. Dans hexedit, taper enter puis l'offset \verb|1ddc| (kernel 24.8) 
ou \verb|1d98| (kernel 24.10/11) ou \verb|1da4| (25.2), 
vérifier qu'on y lit bien \verb|20 62| et remplacer par \verb|00 bf| 
(instruction assembleur nop), et sauvegarder (ctrl-X confirmer).
\item Faire de même pour le régistre 5200203c. En 24.8\\
\verb|90001de8 e0  63           str        r0 ,[r4 ,#0x3c ]=> DAT_5200203c|\\
En 24.10/11\\
\verb|90001da4 e0  63           str        r0 ,[r4 ,#0x3c ]=> DAT_5200203c|\\
En 25.2, c'est à l'offset \verb|1db0| (si vous voyez param1 au lieu de r0,
pas de panique, param1 est un synonyme de r0)
\item 
Précaution supplémentaire pour éviter une réécriture du bootloader par le noyau.
Il faut désactiver le code correspondant, qui se localise de la manière
suivante~: depuis le code qu'on vient de modifier,
remonter jusqu'en début de fonction dans le listing C, cliquer,
dans le listing assembleur à gauche
cliquer sur la fonction appelante, plus précisément sur le premier appel.
Si vous ne voyez pas de fonction appelante, partez de la fonction main
et descendez jusqu'à la dernière paire de DataSynchronizationBarrier
InstructionSynchronizationBarrier et cliquez sur la fonction qui suit,
cherchez à nouveau la même paire, sautez l'instruction suivante.
Vous devez alors être à la ligne \verb|FUN 9000xxxx(0xaa,0xff)|.
Juste au-dessus vous devez voir 
InstructionSynchronizationBarrier, et un peu plus bas
en-dessous dans le code assembleur le chargement d'un régistre
avec 0x8000000 (l'adresse mémoire du début de la flash interne), 
par exemple pour le noyau 24.8\\
\verb|90004912 4f  f0  00  60     mov.w      r0 => DAT_08000000 ,#0x8000000 |\\
ou pour le noyau 24.10/11\\
\verb|90004922 05  f1  00  65      add.w      r5 ,r5 ,#0x8000000|\\
(ou à l'adresse 90004932 avec le noyau 25.2).
Juste après il y a un appel de sous-programme (24.8) \\
\verb|9000491a fc  f7  b9  f8     bl        FUN9000xxxx|\\
ou (24.10/11)\\
\verb|90004926 fc  f7  b3  f8     bl         FUN_90000a90| \\
ou en 90004936 en 25.2.
c'est cette instruction qu'il faut désactiver en remplaçant à cette adresse
les 4 octets par 2 instructions nop, par exemple ici avec \\
\verb|hexedit epsilonkernel_patched.bin| 
valider. Taper enter puis l'offset 491a pour le noyau 24.8 ou
4926 pour le noyau 24.10/11 ou 4936 pour le noyau 25.2 (ou remplacer
par l'offset de votre noyau), puis taper
\verb|00 bf 00 bf| et sauvegarder (Ctrl-X confirmer).
\item étape {\em nwagra} (N0120 uniquement)~:\\
on va maintenant augmenter la mémoire disponible, 
Numworks nous prive en effet de 244K de RAM sur les 500K de la puce
(128K en 0x20000000, 64K en 0x20400000, 
3 blocs de 16K dans la plage 0x30000000, un bloc de 64K en 0x0).
A l'offset 0x24 du kernel (taper G puis 90000024 dans ghidra)
on lit l'adresse de la fonction de démarrage du code
du noyau. Taper P si le mot clef addr n'apparait pas. 
Double cliquez ensuite sur l'adresse, puis tapez F
pour transformer en fonction cette zone (vous pouvez aussi
taper L puis mettre \verb|kernel_main| 
comme nom de fonction), et chercher ensuite
DataMemoryBarrier dans le listing C de la fonction. 
Juste après vous devez voir un appel
à une fonction avec comme paramètre 0x24000000
(\verb|FUN9000xxxx(0x24000000)|). Cet appel de fonction 
\verb|MPU_setaddr| configure le MPU (memory protection unit).
On va effectuer 2 modifications, 
\begin{itemize}
\item remplacer 0x24000000 par 0x20000000, repérez le code
assembleur correspondant, en noyau 24.8 c'est \\
\verb|90004d00 4f  f0  10  50     mov.w      r0 ,#0x24000000|\\
en noyau 24.10/11, c'est\\
\verb|90004d0c 4f  f0  10  50     mov.w      r0 ,#0x24000000|\\
en 25.2 c'est à l'offset 4d60.
Il faut remplacer le 10 par 00 avec hexedit (ici ce serait en offset 4d02 
ou 4d0e selon le noyau 24.8 ou 24.10/11).
\item modifier juste après \verb|11| par \verb|1c| qui code la taille
de la zone configurée dans l'instruction~\\
\verb|_DAT_e000eda0 = FUN9000xxxx(5,1,_DAT_e000eda0,0x11);|\\
Repérez l'adresse de 11 dans le code assembleur, remplacez 11 par 1c avec
hexedit à cette adresse (ici en offset 4d0c en noyau 24.8 ou 4d18 en 
noyau 24.10/11 et 4d6c en noyau 25.10).
\end{itemize}
\item Optionnel mais conseillé, ouvrir \verb|epsilonkernel_patched.bin|
avec ghidra et vérifier que les modifications ont bien été effectuées
aux adresses modifiées.
\item Si vous voulez explorer plus le code binaire du noyau,
un bon point de départ est de partir de l'appel 0x11 de la VTOR du noyau,
à l'offset 0x4c du kernel, c'est le gestionnaire SVC~:
taper P pour faire apparaitre le mot clef addr puis cliquez
sur l'adresse, par exemple 90005350+1 sur Epsilon 25.2. Ce gestionnaire
appelle une fonction qui renvoie vers une routine selon le numéro
SVC demandé, routine dont l'adresse est lue dans une table de pointeurs.
Cette table de pointeurs permet de déterminer ce que fait
une fraction significative des fonctions du noyau en comparant
avec la table des appels SVC du source d'Epsilon, et de
compléter ensuite (éventuellement avec le source du noyau d'Epsilon 18
qui contient le source du kernel de l'époque).
\end{itemize}

{\bf Patch optionnel pour la gestion de crashes sur N0120}\\
La table VTOR contient à l'offset \verb|0x2c| du noyau
(offset \verb|0xc| depuis le début de la table VTOR) le pointeur appelé
en cas de hard fault. Sur les noyaux Numworks, c'est un reset
avec perte de toutes les données.
On peut arranger cela en changeant cette adresse par exemple
en \verb|0x9000a000| vers un gestionnaire qui sauvegarde
le scriptstore en cas de crash
pour ne pas perdre de données (c'est souvent possible,
il faut juste que le scriptstore
ne soit pas corrompu). 
Entrer avec hexedit les octets \verb|01 0A 00 90| à l'offset 0x2c
(le décalage de 1 signale au CPU qu'on est en mode Thumb).
Ma routine de gestion de crash 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/kernel/fault2410.bin}{fault2410.bin} est créée à partir du source
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/kernel/fault2410.c}{fault2410.c} compilé avec
\begin{verbatim}
arm-none-eabi-gcc -c -mcpu=cortex-m7 -mthumb fault2410.c -o fault2410.o
arm-none-eabi-objcopy -O binary --only-section=.text fault2410.o fault2410.bin
\end{verbatim}
se patche sur le kernel avec la commande\\
\verb|dd if=fault2410.bin of=epsilonkernel_patched.bin bs=1 seek=40960 conv=notrunc|\\
Elle utilise la zone mémoire 
de 64K en \verb|0x24040000| pour faire une copie du scriptstore.
La table des pointeurs SVC est à l'offset 0x892c sur noyau
25.2, 0x8948 sur le noyau 24.10/11,
0x893c sur le noyau 24.8, le pointeur SVC 40 à l'offset 0x89cc sur noyau 25.2,
0x89e8 sur
le noyau 24.10/11, 0x89dc sur le noyau 24.8, on doit voir 00 00 00 00
à cette adresse et à la suivante. Il faut remplacer par 01 A0 00 90.
pour gérer la copie du scriptstore depuis un userland en ajoutant dans
la table des appels SVC à la position 40 actuellement inutilisée
la même adresse \verb|0x9000a000| (codée par \verb|01 0A 00 90|
en little endian), en ajoutant un code d'appel
de la fonction SVC 40.
Vérifiez avec \verb|hexedit epsilonkernel_patched.bin|, en version 24.10/11 on doit voir~:
\begin{verbatim}
00000020   F8 F3 03 24  D9 4B 00 90  00 00 00 00  01 A0 00 90  ...$.K..........
...
000089E0   81 2B 00 90  89 06 00 90  01 A0 00 90  00 00 00 00  .+..............
...
0000A000   80 B5 A2 B0  00 AF 78 60  00 23 BB 64  EF F3 03 83  ......x`.#.d....
0000A010   BB 64 BB 6C  C3 F3 08 03  BB 64 BB 6C  0B 2B 02 D0  .d.l.....d.l.+..
...
\end{verbatim}
Il reste à modifier la fonction handleEvent 
du fichier du source d'Epsilon 24 \verb|apps/home/controler.cpp|
de la manière suivante~:
\begin{verbatim}
#define SVC_ATTRIBUTES __attribute__((noinline, externally_visible))

#define SVC_RETURNING_VOID(code)				\
  asm volatile("svc %[immediate]" : : [immediate] "I"(code));
#define SVC_RETURNING_SINGLE_REGISTER(code, returnType, instruction) \
  returnType returnValue;                                            \
  asm volatile(instruction                                           \
               : [returnValue] "=r"(returnValue)                     \
               : [immediate] "I"(code)                               \
               : "r0", "r1", "r2", "r3");                            \
  return returnValue;

#define SVC_RETURNING_R0(code, returnType)        \
  SVC_RETURNING_SINGLE_REGISTER(code, returnType, \
                                "svc %[immediate] ; mov %[returnValue], r0")

#define SVC_BACKUP_RESET 40 // not used anymore by kernels
#define SVC_TEST 41 // not used anymore by kernels
unsigned SVC_ATTRIBUTES svc_backup_reset(unsigned r) {
  SVC_RETURNING_R0(SVC_BACKUP_RESET,unsigned)
}

// insure r is stored in R0
unsigned backup_reset(unsigned arg){
asm volatile (
    "mov r0, %[input]"      // Copie la valeur dans R0
    :                       // Pas de sorties
    : [input] "r" (arg) // Entrée : n'importe quel registre "r"
    : "r0"                  // Liste de "clobber" : prévient que R0 est modifié
);
 svc_backup_reset(arg);
}

  void watch(unsigned r){
#if 0 // enabled : display the result of SVC 40
      char buf[3]={0};
      buf[0]='0'+r/10; buf[1]='0'+r%10;
      extapp_drawTextSmall(buf,100,120,65535,0,false);
      Ion::Timing::msleep(500);
#endif
  }

// ...

bool Controller::handleEvent(Ion::Events::Event event) {
  if (event == Ion::Events::OK || event == Ion::Events::EXE) {
    switchToSelectedApp();
    return true;
  }
  if (event == Ion::Events::Power || event == Ion::Events::Var) { // dbg, calls code at 9000A000 (using svc 40)
    unsigned tmp=0;
    unsigned * stack = &tmp;
    if ( //(unsigned) stack>>24 == 0x24 &&
	 confirm("OK: Save backup")){ // N0120 only
      unsigned r=0;
      r=backup_reset(r);
      watch(r);
      //m_view.selectableTableView()->selectCellAtLocation(r%3, r/3);
    }
    m_view.reload();
    return true;
    //test(0xff,0,0xff);
  }
  if (event == Ion::Events::Toolbox){ // Paste
    unsigned tmp=0;
    unsigned * stack = &tmp;
    if ( //(unsigned) stack>>24 == 0x24 &&
	 confirm("OK: Backup -> scriptstore")){ // N0120 only
      unsigned r=1;
      r=backup_reset(r);
      watch(r);
    }
    m_view.reload();
    return true;
  }
  if (event == Ion::Events::XNT){
    // Cut: erase crash backup
    unsigned tmp=0;
    unsigned * stack = &tmp;
    if ( // (unsigned) stack>>24 == 0x24 &&
	 confirm("OK: erase backup")){ // N0120 only
      unsigned r=2;
      r=backup_reset(r);
      watch(r);
    }
    m_view.reload();
    return true;
  }
  if (event == Ion::Events::Backspace ){
    // erase crash backup
    unsigned tmp=0;
    unsigned * stack = &tmp;
    if ( //(unsigned) stack>>24 == 0x24 &&
	 confirm("OK: erase backup + reset")){ // N0120 only
      unsigned r=3;
      r=backup_reset(r);
      watch(r);
    }
    m_view.reload();
    return true;
  }
  if ( event == Ion::Events::Plus) { // 1st external app
    m_view.selectableTableView()->selectCellAtLocation(12%3, 12/3);
    return true;
  }
  if (event == Ion::Events::Home || event == Ion::Events::Back){
    m_view.selectableTableView()->selectCellAtLocation(0, 0);
    return true;
  }
  ...
\end{verbatim}
Depuis Home, la touche Power permet alors de sauvegarder le scriptstore courant
(j'ai choisi cette touche parce qu'en shift il y a $\rightarrow$
la touche de stockage), La touche Toolbox (paste) permet de remplacer
le scriptstore actuel par la sauvegarde (attention, cela
efface les données courantes). La touche x,n,t (cut) permet d'effacer
le backup. La touche del permet d'effacer et de faire suivre par un reset.
La touche + permet d'accéder à la première application externe.


% kernel 24.8 offset 0x4d02 00 au lieu de 10, 4d0c 1b au lieu de 11
% config probable TCM_AXI_SHARED 00
% ITCM size = 64K 0:0x0ffff, AXI size=320K 0x24000000
%  FLASH_OPTSR2_PRG
% zones memoires 64K: 0:0xffff réservé pour du code.
% 128K: 20000000:2001ffff DTCM RAM OK
% 320K au lieu de 256K: 20400000:2044ffff AXI RAM OK sauf zone kernel
% 32K de 0x30000000:0x30007fff: SRAM1 et 2 OK
% 16K 0x38000000:0x38003fff SRAM4 OK
% 4K 38800000:38000fff backup SRAM

\subsubsection{Ouverture de la calculatrice} \label{sec:opencalc}
\begin{enumerate}
\item {\bf Avant d'ouvrir la calculatrice, 
faire reset+6 sur la calculatrice et installez le noyau modifié}
depuis
\ahref{https://ti-planet.github.io/webdfu_numworks/}{le site webdfu de tiplanet} ou avec la commande\\
\verb|dfu-util -i 0 -a 0 -s 0x90000000 -D epsilonkernel_patched.bin|\\
Comme cela au premier boot avec la calculatrice déverrouillée, vous
ne risquez pas de lancer un noyau qui reflashe le
bootloader et reverrouille la calculatrice.
\item Notez que si vous avez une N0120 achetée en 2022, 
le déverrouillage matériel
est potentiellement plus difficile à réaliser (il faut faire
un ``connect under reset''). Pour le savoir, aller
dans Paramètres, A propos, version du logiciel, appuyer 4 fois sur OK,
s'il apparait 67E9399C vous êtes probablement concerné. Profitez de la
manipulation pour prendre note du numéro de PCB, affiché après le
2ème OK, par exemple 4.19 pour pouvoir éventuellement
le reporter dans le bootloader patché.
\item Retourner la calculatrice, enlever les 6 petits patins ronds
  anti-d\'erapant blancs, en vous aidant d'un des petits triangles orange
  OPENER si vous en avez. Les vis doivent devenir apparentes, 
d\'evissez-les avec le tournevis torx t6. Mettez dans l'enveloppe
les patins et les vis pour ne pas les perdre~:\\
\includegraphics[width=10cm]{unlock4.png}
\item Placez un des triangles oranges OPENER au milieu de la partie
gauche de la calculatrice comme ci-dessus pour vous aider
\`a d\'eclipser la calculatrice. Commencez par d\'eclipser
enti\`erement \`a gauche (orientation gauche par rapport au mot 
RESET écrit à l'endroit). 
Puis faites doucement une rotation de la partie 
supérieure gauche de la calculatrice 
(on fait donc tourner la face arrière de la calculatrice en utilisation normale,
par rapport à un axe de rotation situé à droite de la calculatrice ouverte), 
pour vous assurer de ne pas arracher le cable de la
batterie. Lorsque vous avez tourné à angle droit la partie supérieure
de la calculatrice, décalez la légèrement vers la gauche et continuez
jusqu'à ouverture complète.
Sur une de mes N0120, il n'y avait pas de soucis, car la batterie était du 
m\^eme coté que toute l'\'electronique (dans la partie inférieure), 
mais sur toutes les autres
calculatrices que j'ai ouvertes, la batterie était de l'autre c\^ot\'e, il faut
faire attention\\
\includegraphics[width=10cm]{unlock5.png}
\includegraphics[width=10cm]{unlock12.png}\\
Vous pouvez aussi mettre de cot\'e le bouton reset et le morceau noir
qui a la forme d'un petit disque accol\'e \`a un rectangle pour ne pas
les perdre. En les remettant, prenez garde \`a bien les replacer 
(il y a deux petits reliefs blancs pour les maintenir).\\
\includegraphics[width=10cm]{unlock6.png}
\item Optionnel~: notez le numéro du PCB en bas à droite (à droite du 
contenant de la vis inférieure droite, ce numéro est écrit
tourné d'un angle droit). Ce numéro peut servir pour remplir les octets
0x807fa00 et 0x807fa01 de la flash interne, 
par exemple si votre PCB est 4.15, on fait le
calcul suivant avec une calculatrice permettant d'afficher le résultat
en hexadécimal, par exemple dans KhICAS:
\begin{verbatim}
16=>=>
0xffff-415
\end{verbatim}
le résultat est ici \verb|0xfe60|, on édite alors\\
\verb|hexedit bootloader_patched.bin|\\
Entrée puis on tape 7fa00, entrée et on entre 60 fe, on voit alors
\begin{verbatim}
0007FA00   60 FE FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  `...............
---  epsilon120internal       --0x7FA00/0x80000--100 %--------------------------
\end{verbatim}
on tape Ctrl-X pour quitter puis Y pour sauvegarder.
\end{enumerate}

Connexions ST-Link ou Raspberry Pi 3~:
\begin{enumerate}
\item Il faut positionner les 3 cables SWIO SWCLK GND selon le 
sch\'ema de votre ST-Link, chez moi cela donne\\
\includegraphics[width=10cm]{unlock7.png}\\
la terre GND en noir est sur la rang\'ee du haut du STLink
sur la broche compl\`etement 
\`a droite, et sur la terre du "shield" connecteur USB de la calculatrice. 
Au moment du d\'everrouillage, je maintiens le cable sur l'USB avec
l'auriculaire de la main droite.
Les broches SWDIO et SWCLK sont chez moi sur la rang\'ee du bas du stlink
respectivement les broches 4 et 5 en partant de la gauche de la rang\'ee
basse.
\item Le cable (en rouge ici) 
SWDIO se connecte sur le connecteur en haut \`a droite
du cortex debug, le cable (orange ici) SWCLK juste en-dessous
(j'ai choisi les couleurs pour être compatible avec la photo de 
\ahref{https://tiplanet.org/forum/viewtopic.php?f=113&t=25191}{ce post de tiplanet}
 pour les N0110). Sur une
N0110/N0115, c'est assez semblable. 
En général l'orientation du Cortex Debug est
d\'efinie par le petit point blanc au-dessus \`a gauche qui marque la
colonne des broches impaires du Cortex Debug (voir la liste ci-dessous).
\\
\includegraphics[width=10cm]{unlock8.png}
\includegraphics[width=10cm]{unlock9.png}\\
Pour éviter toute erreur, je remets une photo où on voit mieux
le branchement du cable SWCLK (orange)\\
\includegraphics[width=10cm]{unlock11.png}\\
Lors du d\'everrouillage je maintiens le cable rouge entre le pouce et
l'index de la main droite (le cable noir est maintenu sur le shield USB avec
l'auriculaire de la main droite), 
et l'orange avec la main gauche.\\
Si vous \^etes deux, ce sera plus facile de maintenir les contacts!\\
Ci-dessous le schéma de cablage des
broches du Cortex Debug, les numéros impairs sont en-dessous du point
blanc, les pairs sur l'autre colonne
\begin{verbatim}
Broche	Signal	Fonction
1	VTRef	Tension de Référence Cible (Alimentation VCC du microcontrôleur).
2	SWDIO/TMS	Données Bidirectionnelles SWD / Signal JTAG TMS.
3	GND	Masse (Ground) du système.
4	SWCLK/TCK	Horloge SWD / Signal JTAG TCK.
5	GND	Masse.
6	SWO/TDO	Sortie de Traçage (Trace) SWV / Signal JTAG TDO.
7	KEY	Détrompeur (Pas de broche/Pin retirée).
8	NC/TDI	Non Connecté (ou JTAG TDI si JTAG est utilisé).
9	GND	Masse (peut parfois être GND Detect).
10	nRESET	Signal de Réinitialisation du microcontrôleur (actif bas).        
\end{verbatim}
\item Voici des photos et le  
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/unlockpi3.png}{schéma de cablage pour Raspberry Pi 3}
 (crédits~: Yannis)\\
\includegraphics[width=10cm]{unlockpi1.png}
\includegraphics[width=10cm]{unlockpi2.png}\\
\includegraphics[width=18cm]{unlockpi3.png}
\end{enumerate}

\subsubsection{D\'everrouillage} \label{sec:unlockcalc}
Les fichiers ci-dessous se trouvent dans le répertoire
\verb|unlock| de l'archive 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/unlock.zip}{unlock.zip}. Il nous faut
\begin{enumerate}
\item le fichier de configuration openocd
\begin{itemize}
\item \verb|stlinkh.cfg| (N0120 pour STLink) 
\begin{verbatim}
source [find interface/stlink.cfg]
source [find target/stm32h7x.cfg]
reset_config none separate
\end{verbatim}
\item \verb|stlinkf.cfg| (N0110/N0115 pour ST-Link)
\begin{verbatim}
source [find interface/stlink.cfg]
source [find target/stm32f7x.cfg]
reset_config none separate
\end{verbatim}
\end{itemize}
ou le fichier \verb|raspyh.cfg| ou \verb|raspyf.cfg| pour Raspberry
obtenu en remplaçant la ligne interface par\\
\verb|source [find interface/raspberrypi-native.cfg]|\\
\verb|transport select swd|
\item selon le modèle de calculatrice un fichier de commande
\begin{itemize}
\item \verb|unlock120.run| pour N0120
\begin{verbatim}
init
halt
stm32h7x option_write 0 0x44 0x1ff01ff0
stm32h7x option_write 0 0x3C 0xFF
stm32h7x unlock 0
\end{verbatim}
\item \verb|unlock115.run| pour les n0115
\begin{verbatim}
init
mww 0x40023C08 0x08192A3B
mww 0x40023C08 0x4C5D6E7F
mww 0x40023C18 0x00400040
mww 0x40023C14 0xC0FFAAFE
exit
\end{verbatim}
\item \verb|unlock110.run| pour les N0110
\begin{verbatim}
init
mww 0x40023C08 0x08192A3B
mww 0x40023C08 0x4C5D6E7F
mww 0x40023C18 0x00400080
mww 0x40023C14 0xC0FFAAFE
exit
\end{verbatim}
\end{itemize}
Explications N0115/N0110~: on commence par lancer une séquence 
de déverrouillage des ``option bytes'' (ce sont les deux premières
commandes après init ci-dessous), 
puis on modifie l'adresse de boot et le mode RDP
du CPU. La seule différence
entre N0115 et N0110, c'est que sur la 
N0110 on a une connexion physique directe
du bouton 6 pour que combiné avec le bouton reset, on démarre sur
l'adresse BOOT1, que l'on configure alors vers le bootloader ST qui 
permettra de reflasher la flash interne de la calculatrice. Sur
les N0115, il n'y a pas de moyen simple de rebooter sur BOOT1
(matériellement cela peut se faire en reliant la broche 
légéndée BOOT1 près de la fibre reliant la LED au boitier
extérieur avec la tension 3.3V au moment du reset),
on reconfigure donc BOOT0 vers le bootloader ST, il faudra après
reflashage de la flash interne reconfigurer BOOT0 vers la flash interne.
Dans les 3 cas, la dernière commande va faire passer le CPU du mode verrouillé
RDP1 au mode non verrouillé RDP0, ce qui provoquera automatiquement
un effacement de la flash interne (protection matérielle de la flash 
du CPU).\\
{\bf Remarque}~: 
si vous pensez que la connexion avec le ST-Link n'est pas fiable
et risque de verrouiller le CPU en RDP2,
enlevez la ligne correspondante du fichier de commandes openocd
({\tt stm32h7x unlock 0} ou {\tt mww 0x40023C14 0xC0FFAAFE}), ceci
permet de booter sur le bootloader ST, vous pourrez ensuite effectuer
l'opération d'unlock avec le logiciel 
\ahref{https://www.st.com/en/development-tools/stm32cubeprog.html}{STM32 Cube Programmer}
en connexion USB.\\
Le risque d'erreur de transmission est objectivement faible, il faudrait 
qu'un octet 0xAA se transforme en 0xCC, or la distance de Hamming est de 4
sans décalage et reste élevé en cas de décalage de 1 bit 
(5 ou 6 si décalage de 1 à gauche, 4 ou 3 si décalage de 1 à droite).
\item le shell script \verb|unlock120.sh| ou
\verb|unlock115.sh| ou \verb|unlock110.sh| qui permettra
de lancer openocd plusieurs fois sans avoir à manipuler le PC,
dont le contenu est par exemple pour les N0120~: 
\begin{verbatim}
#!/bin/bash
while true; do
	openocd -f ./stlinkh.cfg -f "unlock120.run"
	sleep 0.5
done
\end{verbatim}
{\bf Si vous utilisez un Raspberry Pi, 
éditez le fichier correspondant à votre calculatrice
et remplacez stlinkh.cfg par raspyh.cfg ou 
stlinkf.cfg par raspyf.cfg.}
\item Faire reset sur la calculatrice, pour cela appuyer
  avec un trombone au centre de la partie circulaire dor\'ee qui
serait situ\'ee en face du bouton reset si la calculatrice
était refermée. 
Vous devez voir la led en vert/jaune. Sinon, c'est que vous n'avez
pas reflashé le kernel, faites reset+6 pour forcer
la Numworks en mode reflashage et flashez le kernel avant d'oublier!
\item Brancher sur le PC le stlink (vous devez voir apparaitre une led rouge
sur le STLink) ou le raspberry, 
lancer le shell script correspondant à votre calculatrice~:
\begin{itemize}
\item N0120~: \verb|sudo ./unlock120.sh >& log|
\item N0115~: \verb|sudo ./unlock115.sh >& log|
\item N0110~: \verb|sudo ./unlock110.sh >& log|
\end{itemize}
et maintenez les connexions quelques secondes, vous devez voir la led
du stlink changer de couleur par moments. Faire Ctrl-C sur le PC
pour arr\^eter
le script, si tout s'est bien pass\'e vous devriez voir \`a un endroit
dans le fichier \verb|log| sur le PC
que la flash interne de la calculatrice 
a \'et\'e effac\'ee.
\item Si la led du stlink ne s'est pas brièvement allumée en vert,
réessayez. \\
Ensuite faites reset sur la calculatrice (ou reset+6 sur la N0110), 
la modification des options
  bytes doit faire booter sur le ST Micro bootloader, l'\'ecran doit
\^etre \'eteint et la led doit \^etre
  allum\'ee en rouge. 
Sur le PC linux, la commande\\
 \verb|sudo dmesg|\\
doit faire apparaitre le bootloader ST.
Sinon recommencez l'étape précédente.
\item
Si cela ne fonctionne toujours pas (la méthode semble ne pas
fonctionner pour les premières N0120), il est peut-être
nécessaire de faire un ``connect under reset''. Pour cela, il faut
effectuer une 4ème connexion entre la
petite pastille dorée située immédiatement 
à droite du bas de la colonne de droite
du Cortex Debug de la calculatrice et la broche reset du ST-Link 
(sur mon ST-link c'est la 3ème broche à partir de la droite de la rangée
du bas, donc à droite du fil orange en laissant 2 broches libres
et à gauche du fil noir sur l'autre rangée en laissant 1 colonne libre). 
Il faut alors utiliser le script {\tt unlock120reset.sh}
à la place de {\tt unlock120.sh}. L'opération nécessite 2 personnes
pour tenir chacun 2 fils, et même ainsi c'est assez difficile de maintenir
les connexions correctement. Vérifiez que la led du ST-Link
est passée au vert pendant un court moment au moins et que le reset
de la calculatrice affiche la led en rouge.\\
Vous pouvez consulter le compte-rendu de l'opération dans le fichier 
{\tt log} pour savoir ce qui s'est passé. Branchez le cable USB de la
calculatrice et vérifiez avec \verb|sudo dmesg| que 
le bootloader système ST de la calculatrice apparait.\\
Si le bootloader ST n'est pas visible avec dmesg, vérifiez
avec le logiciel \ahref{https://www.st.com/en/development-tools/stm32cubeprog.html}{STM32 Cube Programmer}
en se connectant en USB (au lieu de UART affiché par défaut en haut à droite)
et en cochant l'option connect under protection comme indiqué par le logiciel. 
Si la connexion USB avec STM32 Cube Programmer échoue alors que
la led rouge est allumée au reset, ne paniquez pas, il est probable
que l'adresse de BOOT0/1 ait été mal transmise par openocd, dans ce cas
refaites un connect under reset. 
\item Vous pouvez maintenant transférer le bootloader modifi\'e 
\verb|bootloader_patched.bin| en flash interne depuis
\ahref{https://ti-planet.github.io/webdfu_numworks/}{le site webdfu de tiplanet}
ou avec la commande\\
\verb|dfu-util -i 0 -a 0 -s 0x80000000 -D bootloader_patched.bin|\\
Attention ne vous trompez pas, utilisez le bootloader modifié, 
pas l'original!!! \\
N.B., pour les N0110 (et peut-être aussi les N0115), 
vous pouvez utiliser le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/n0110/bootloader_patched.bin}{bootloader d'Upsilon}.\\
Si vous observez une erreur à cette étape, cela signifie que les contacts
n'ont pas été stable assez longtemps, les options bytes ont été
modifiés, mais pas la commande de déverrouillage RDP1 vers RDP0,
il faut alors recommencer l'étape 5 ou bien lancer le logiciel
\ahref{https://www.st.com/en/development-tools/stm32cubeprog.html}{STM32 Cube Programmer}, se connecter en USB et enlever la protection.
\item Vous pouvez vérifier la flash interne,
\begin{itemize}
\item sur les N0120, taper
\verb|./getn120internal| ou  \\
\verb|dfu-util -i 0 -a 0 -s 0x8000000:0x80000:force -U epsilon120internal|\\
cela doit être identique à \verb|bootloader_patched.bin|\\
\verb|diff -q epsilon120internal bootloader_patched.bin|
\item
Sur les N0110/N0115, taper \verb|./getn110internal| ou\\
\verb|dfu-util -i 0 -a 0 -s 0x8000000:0x10000:force -U epsilon110internal|\\
\verb|diff -q epsilon110internal bootloader_patched.bin|
\end{itemize}
\item Sur les N0115 et N0120, 
il reste \`a remettre le boot sur la flash interne
(c'est inutile sur N0110 ou reset et reset+6 permettent
de booter sur flash interne ou sur le bootloader ST).\\
Si vous êtes confiants, le plus simple est 
d'utiliser le fait que lancer le 
bootloader de Numworks va remettre le boot sur la 
flash interne, il suffit d'exécuter le script \verb|reboot.sh| qui 
contient la commande\\
\verb|dfu-util -a 0 -s 0x8000000:leave |\\
Si vous préférez tout bien controler avant de booter
\begin{itemize}
\item {\bf Pour les n0120} \\
\verb|./sendoption120normal|\\
Vous pouvez vérifier avec\\
\verb|./getoptionbytes120 && hexedit optionbytes120|\\
à l'offset 0x28 (qui correspond au régistre 0x52002044, il y
a un décalage de 0x1c sur les offsets),
 vous devriez voir \verb|00 08 00 08|.
\item
{\bf Pour les n0115 (testé sur n0110)}, 
tapez simplement depuis le répertoire boot\\
\verb|./sendoption110normal|\\
Vous pouvez vérifier avec\\
\verb|./getoptionbytes110 && hexedit optionbytes110|\\ 
à l'offset 10 on doit voir\\
\verb|00000010   80 00 7F FF  80 00 7F FF  40 00 BF FF  40 00 BF FF|\\
\end{itemize}
%% {\bf Pour les n0120}, l'analogue devrait être possible, pas encore testé.
%% Pour le moment il faut installer le logiciel
%% \ahref{https://www.st.com/en/development-tools/stm32cubeprog.html}{STM32 Cube Programmer}. 
%% On ouvre \verb|STM32CubeProgrammer|, puis on 
%% se connecte via USB (en haut à droite de la fenêtre, à la place
%% de UART), puis à gauche Option Bytes, Boot options, mettre 0x800 pour BOOT0,
%% l'adresse correspondante doit être 0x8000000.
%% Attention, ne vous trompez pas sinon
%% il faudra reprendre la proc\'edure à l'étape 5 de déverrouillage.
%% On peut vérifier la configuration en ligne de commande avec une
%% des deux commandes\\
%% \verb|STM32_Programmer_CLI -c port=USB1 -ob displ|\\
%% \verb|dfu-util -i 0 -a 1 -s 0x5200201C:force:88 -U optionbytes120|\\
%% On devrait pouvoir programmer le changement de boot en ligne de commande sur les N0120 par\\
%% \verb|STM32_Programmer_CLI -c port=USB1 -ob nBOOT0=1 nSWBOOT0=0 BOOT0_ADDR=0x08000000 BOOT1_ADDR=0x1FF00000|\\
%% mais je n'ai pas testé. Il est peut-être possible de modifier
%% les options bytes avec dfu-util, à tester.
%% je vous conseille donc l'interface graphique pour être sur de ne pas faire
%% de fausse manipulation.
%% Il ne semble pas y avoir d'équivalent openocd sur USB,
%% on peut le faire avec le STLink en repositionnant les contacteurs
%% et en changeant la ligne de unlock120.run
%% \\ \verb|stm32h7x option_write 0 0x44 0x1ff01ff0|\\
%% en
%% \\ \verb|stm32h7x option_write 0 0x44 0x1ff00800|\\
%% (les lignes \verb|stm32h7x option_write 0 0x3C 0xFF| et 
%% \verb|stm32h7x unlock 0|
%% ne sont plus utiles)
\item Si tout s'est bien pass\'e, au prochain reset vous red\'emarrez
 sur Epsilon, mais vous pourrez modifier librement le noyau et
l'userland, il n'y a plus
de v\'erification de la signature de Numworks. \\
Sur les N0120 et N0115, il faudra faire reset+6 pour
flasher les slots (comme avant), reset+1 pour ouvrir le bootloader ST
(si vous voulez modifier le bootloader ou les options bytes).
Sur les N0110, le bootloader d'Upsilon affiche un menu permettant
de flasher les slots ou de lancer le bootloader ST.\\
Vous pouvez refermer la calculatrice et \`a
  vous la libert\'e! Vous pouvez installer $\chi$CAS depuis la
\ahref{https://xcas.univ-grenoble-alpes.fr/nw/nws.html}{page Numworks du site de Xcas}.\\
Si on vous demande de justifier que votre calculatrice est 
conforme à la réglementation du mode examen, vous pouvez
vous connecter avec un navigateur webUSB compatible sur
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nws.html#exam}{la page Numworks de Xcas}.
\item Si la calculatrice ne redémarre pas normalement (par
exemple reboote en boucle avec un bref flash écran), ne paniquez
pas, il y a surement un moyen de la débloquer.\\
Essayez de faire reset+1. 
\begin{itemize}
\item Si la led rouge s'allume
avec écran noir et que ST Micro apparait dans les devices USB, 
cela signifie que le bootloader patché est bien installé
mais que le kernel patché/userland ne se lance pas correctement.
Faites reset+6 pour passer en mode rescue et reflashez un kernel
patché et un userland de la même version. Si cela ne fonctionne
toujours pas, je vous conseille de récupérer la version 24.10
d'Epsilon (par exemple en récupérant la 25.2 d'Epsilon
sur le site de Numworks puis en exécutant les patchs pour
redescendre le kernel/bootloader en 24.10 comme expliqué
en 2ème méthode de la section \ref{sec:fast}), exécutez
les patchs sur 24.10 puis reflashez bootloader/kernel 24.10 et un
un userland 24.10 recompilé\\
\verb|git clone https://github.com/parisseb/epsilon/ -b version-24|\\
\verb|make userland.A.allow3rdparty.bin MODEL=n0115|\\
\verb|make userland.A.allow3rdparty.bin MODEL=n0120|
\item Si reset+1 n'a aucun effet, c'est que le bootloader
n'a pas été patché, recommencez l'opération de déverrouillage matériel.
\end{itemize}
\end{enumerate}


\subsubsection{Donner un nom à votre calculatrice}
Il suffit de changer la valeur des premiers octets à l'adresse 0x90003f00.
Par exemple avec dfu-util et hexedit, on récupère le secteur
\begin{verbatim}
/bin/rm sector3f.bin
dfu-util -i 0 -a 0 -s 0x903f0000:force:0x10000 -U sector3f.bin
\end{verbatim}
Puis\\
 \verb|hexedit sector3f.bin|\\
 taper la touche de tabulation 
(normalement à gauche de A sur un clavier français), taper votre nom,
taper à nouveau la touche de tabulation, puis 00, vous devez voir
quelque chose qui ressemble à~:
\begin{verbatim}
00000000   42 65 72 6E  61 72 64 20  50 61 72 69  73 73 65 00  Bernard Parisse.
00000010   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
\end{verbatim}
attention, il faut absolument un 00 à la fin du nom. Taper Ctrl-X
pour quitter puis  confirmer en tapant Y.
Puis\\
\verb|dfu-util -i 0 -a 0 -s 0x903f0000 -D sector3f.bin|

\subsection{Installation/mise à jour de $\chi$CAS sur Numworks non verrouillée avec Delta (Upsilon...)} \label{sec:delta}
Si votre Numworks est déverrouillée (cf. la section \ref{sec:unlock}),
le plus simple est d'installer Khi, Omega, Upsilon ou Delta sur une N0110 ou
Delta sur une N0115/N0120. Ce sont des firmwares dérivés d'Epsilon 15.5, Delta
est une version d'Upsilon modifié pour fonctionner avec un noyau Epsilon
déjà installé (il n'y a actuellement pas d'autre solution pour
fonctionner sur n0120). La version
qui nous intéresse pour une Numworks non verrouillée s'installe immédiatement
après le noyau, en 0x90010000 sur une N0110/N0115 ou en 0x90020000 sur une
N0120. (Crédits image ChatGPT)\\
\includegraphics[width=12cm]{delta.png}
Ci-dessous une archive d'une image flash complète, à l'exception
du noyau~:
\begin{itemize}
\item \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/n110unlocked.zip}{Delta+KhiCAS N0110/N0115 pour kernel >22}.
\item \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/n120unlocked.zip}{Delta+KhiCAS N0120 pour kernel >22}.
\end{itemize}
Si vous préférez installer chaque composant séparément, on
commence par Delta~:
\begin{itemize}
\item \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/epsilon.110.bin}{Delta N0110/N0115 pour kernel >22}
à installer par
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90010000 -D epsilon.110.bin
\end{verbatim}
\item \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/epsilon.120.bin}{Delta N0120 pour kernel >22} à installer par
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90020000 -D epsilon.120.bin
\end{verbatim}
\end{itemize}
On installe ensuite un paquet d'applications externes dont KhiCAS
\begin{itemize}
\item \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/apps110b_rodata.tar}{data N0110/N0115} et
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/apps110b.tar}{apps N0110/N0115}
à installer par
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90300000 -D apps110b_rodata.tar
dfu-util -i 0 -a 0 -s 0x90400000 -D apps110b.tar
\end{verbatim}
\item \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/apps120b_rodata.tar}{data N0120} et
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/apps120b.tar}{apps N0120}
à installer par
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90300000 -D apps120b_rodata.tar
dfu-util -i 0 -a 0 -s 0x90400000 -D apps120b.tar
\end{verbatim}
\end{itemize}
Vous pouvez sauvegarder votre flash externe depuis le 
\ahref{https://ti-planet.github.io/webdfu_numworks/}{webDFU de tiplanet},
ou par
\begin{verbatim}
#! /bin/bash
/bin/rm flash.bin
dfu-util -i 0 -a 0 -s 0x90000000:force:0x800000 -U flash.bin
\end{verbatim}
et cloner votre installation sur d'autres machines identiques
en mode récupération, soit
depuis le site de TI Planet, soit par la commande
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90000000 -D flash.bin
\end{verbatim}

Vous pouvez maintenant passer à la section \ref{sec:firststep}.

\subsection{Installation/mise à jour de $\chi$CAS sur Numworks non verrouillée avec Epsilon en version $\geq$16} \label{sec:unlocked16}
Si votre calculatrice est déverrouillée 
(cf. la section \ref{sec:unlock}), et si vous avez également besoin
des fonctionnalités récentes d'Epsilon, vous pouvez modifier
et recompiler une version d'Epsilon interopérable avec KhiCAS.
(la redistribution de versions modifiées d'Epsilon est 
dans une zone un peu floue des licences d'utilisation de github).
Il vous faudra supprimer le sabotage des applications
externes en cas de reset, dans le fichier
{\tt ion/src/device/userland/drivers/external_apps.cpp},
rechercher la fonction \verb|App::eraseMagicCode() {| et mettre au début
\begin{verbatim}
   return; // do not erase magic code
\end{verbatim}
Il faut ensuite autoriser le lancement de KhiCAS dans
{\tt apps/home/controler.cpp}, dans la fonction 
\verb|void Controller::switchToSelectedApp() {|.

Vous pouvez alors installer ou mettre à jour
$\chi$CAS depuis la
\ahref{https://xcas.univ-grenoble-alpes.fr/nw/nws.html}{page Numworks du site de Xcas}
en utilisant un navigateur webUSB compatible (Chromium, Chrome, Edge...).

Il existe deux sous-versions~: la version courte occupe presque
la moitié de l'espace flash de la calculatrice, la version longue
environ les deux tiers, la différence est que la version courte
ne contient pas l'aide complète en ligne dans plusieurs langues,
mais uniquement l'aide sur les principales commandes en français
et en anglais.
Je vous recommande l'installation complète!
Vous pouvez maintenant passer à la section \ref{sec:firststep}.


\subsection{Numworks N0110 non verrouillée avec Epsilon au plus 15.5} \label{sec:unlocked15}
Cette section est destinée aux rares personnes qui possèdent une
Numworks N0110 achetée avant 2021 et qui n'a pas été mise à jour depuis.
%% Il est donc n\'ecessaire
%% de compiler soi-m\^eme une version modifi\'ee de Epsilon 
%% (le firmware de la Numworks) et de compiler Giac pour produire
%% un firmware (qu'on ne peut pas diffuser publiquement). 
%% Damien Nicolet a automatis\'e la proc\'edure avec le logiciel Docker, on peut
%% l'installer 
%% \begin{itemize}
%% \item sous Linux debian compatible
%% avec la commande \\
%% \verb|sudo apt-get install docker.io|
%% \item sur Mac, installer \ahref{https://brew.sh/}{brew} puis
%% ex\'ecuter la commande\\
%% \verb|brew install docker|
%% \item sous Windows, je ne sais pas si c'est possible,
%%   voir le site de \ahref{https://docs.docker.com/docker-for-windows/install/}{Docker}
%% \end{itemize}
%% Connecter la calculatrice puis ex\'ecuter la commande~:\\
%% \verb|docker run -it --rm --privileged zardam/epsilon-builder https://github.com/zardam/epsilon.git n110-giac|\\
%% pour plus d'informations, voir le fil de
%% \ahref{https://tiplanet.org/forum/viewtopic.php?f=97&t=22980}{TI planet}

%% Une fois la compilation et le transfert termin\'es, d\'ebranchez
%% la calculatrice, elle reboote alors et une nouvelle icone (avec le flocon
%% de Xcas) apparait dans le menu principal. J'ai du enlever
%% l'application r\'egressions, car elle prend trop de place en m\'emoire
%% vive. La section \ref{sec:stat2d} explique comment faire des r\'egressions
%% avec $\chi$CAS.

%% {\bf Remarque~: je suis le premier \`a regretter 
%% devoir imposer cette manipulation compliqu\'ee.} 
%% J'ai pourtant tout fait de mon cot\'e pour que la licence libre de Giac
%% ne soit pas un obstacle \`a une diffusion sous forme de firmware compil\'e.
%% Mais contrairement
%% \`a la licence GPL qui permet de lier du code libre avec un OS propri\'etaire,
%% la licence de l'OS de la Numworks est incompatible avec toute
%% autre licence.
%% Malgr\'e mon insistance, 
%% Numworks n'a pour l'instant pas r\'epondu \`a ma demande d'autorisation
%% de lier du code sous licence GPL avec les fonctions de base de leur OS.
%% Le m\^eme raisonnement s'applique \`a tout logiciel libre, on peut donc
%% dire que
%% {\bf contrairement aux d\'eclarations d'ouverture de la soci\'et\'e, 
%% la Numworks est encore un syst\`eme ferm\'e, 
%% plus que Casio par exemple.}

Avant d'installer ou mettre \`a jour $\chi$CAS, pensez \`a sauvegarder
vos donn\'ees, car elles pourraient \^etre effac\'ees. 
{\em Si vous faites une mise \`a jour, il pourra \^etre n\'ecessaire de faire
reset+4 sur votre calculatrice pour acc\'eder \`a la flash
(i.e. appuyer sur la touche 4, puis enfoncer une pointe \`a
l'arri\`ere sur reset, relacher la touche 4).}
Puis choisir une des m\'ethodes~:
\begin{enumerate}
\item {\bf Via Internet avec un navigateur compatible avec webUSB}\\
Cliquez sur \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{ce lien}
en utilisant un navigateur supportant web USB tel que Chromium ou Edge ou Google Chrome.
Connectez la calculatrice et cliquez sur le bouton Installer
ou mettre \`a jour $\chi$CAS.
\item {\bf Depuis Xcas} (Windows et Linux)\\
C'est une m\'ethode d'installation locale (une fois Xcas install\'e)
N.B.~:sous Linux,
v\'erifiez que
\ahref{http://dfu-util.sourceforge.net/}{dfu-util} 
est bien install\'e et que le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/50-numworks-calculator.rules}{\tt
  50-numworks-calculator.rules} a \'et\'e copi\'e dans  \verb|/etc/udev/rules.d|.\\
Connecter la calculatrice, ouvrez Xcas, puis dans le menu Fich,
sous-menu Numworks, s\'electionner \verb|Installer $\chi$CAS sur la calculatrice|. Lorsqu'on vous demande de faire un reset de la
calculatrice, appuyez sur le bouton
\verb|RESET| \`a l'arri\`ere de la calculatrice.
\item Depuis le site d'\ahref{https://getupsilon.web.app/}{Upsilon}
  ou d'\ahref{https://getomega.dev/}{Omega},
  suivre les instructions
  de ces sites et installer $\chi$CAS comme application externe. Notez
  que le support du clavier depuis $\chi$CAS est moins bien optimisé
  qu'avec les autres méthodes d'installation décrites ici. Par contre
  les bootloader d'\ahref{https://getupsilon.web.app/}{Upsilon} et \ahref{https://getomega.dev/}{Omega} ont du support pour lancer
  des versions plus récentes du système d'exploitation Epsilon de Numworks.
\item
{\bf Installation manuelle}\\
Pour installer ou mettre \`a jour $\chi$CAS sur votre 
Numworks N0110~:
r\'ecup\'erez sur votre ordinateur le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/khi.zip}{khi.zip}.
\begin{itemize}
\item Si n\'ecessaire, installez dfu-util
  \begin{itemize}
  \item sur Mac, installez \ahref{https://brew.sh/}{brew} si n\'ecessaire puis
depuis un Terminal (dans Utilitaires) faire\\
    \verb|brew install dfu-util|
  \item sous Linux debian compatible, ouvrir un Terminal et faire\\
  \verb|sudo apt-get install dfu-util|\\
Vous pouvez aussi compilez et installer \`a partir du \ahref{http://dfu-util.sourceforge.net/}{source}.\\
  R\'ecup\'erez 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/50-numworks-calculator.rules}{ce fichier} et copiez le
  dans \verb|/etc/udev/rules.d|. Si vous avez install\'e un package
  debian, cela peut se faire par la commande\\
\verb|sudo cp /usr/share/giac/doc/50-numworks-calculator.rules /etc/udev/rules.d|
Vous pouvez aussi cr\'eer un fichier
\verb|/etc/udev/rules.d/50-numworks-calculator.rules|  de contenu~:
\begin{verbatim}
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="a291", TAG+="uaccess"
SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", TAG+="uaccess"
\end{verbatim}
\item sous Windows, t\'el\'echargez et installez la version
  \ahref{http://dfu-util.sourceforge.net/releases/dfu-util-0.9-win64.zip}{64 bits}
  ou \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/dfu-win32.zip}{32 bits}
  (\ahref{http://dfu-util.sourceforge.net/releases/}{provenance}).
  L'ex\'ecutable s'appelle \verb|dfu-util-static.exe|.
  Si n\'ecessaire \'editez le fichier \verb|updaten110.bat| (64 bits)
  ou \verb|updaten110_32.bat| (32 bits)
  pour adapter les chemins d'installation. Le fichier actuel
  suppose que l'on a desarchiv\'e \verb|khi.zip|
  et \verb|dfu-util-0.9-win64.zip| depuis le m\^eme r\'epertoire racine
  (par exemple \verb|c:\temp|)
  et qu'on lance \verb|updaten110.bat| (64 bits)
  ou \verb|updaten110_32.bat| (32 bits) en cliquant sur le fichier
  dans l'explorateur de fichiers. 
  \end{itemize}
\item Tapez la commande \verb|./updaten110| (Linux/Mac) ou
  ex\'ecutez \verb|updaten110.bat| (Windows 64 bits)
  ou \verb|updaten110_32.bat| (Windows 32 bits).
  Les commandes \verb|dfu-util| sont les suivantes
\begin{verbatim}
dfu-util -i 0 -a 0 -s 0x08000000 -D bootloader.bin -R
dfu-util -i 0 -a 0 -s 0x90000000 -D khi.A.bin -R
dfu-util -i 0 -a 0 -s 0x90180000 -D khi.B.bin -R
dfu-util -i 0 -a 0 -s 0x90200000:force -D apps.tar
\end{verbatim}
Vous pouvez ajouter des fichiers scripts Python ou sessions Xcas (ou
m\^eme des programmes) \`a
l'archive \verb|apps.tar|
avec la commande \verb|tar rvf apps.tar <filenames>|. Ils seront
alors visibles depuis $\chi$CAS hors mode examen (et l'ajout est
compatible avec la certification du firmware disponible depuis
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{le
kit de connexion Numworks}).
\end{itemize}
\end{enumerate}
Apr\`es installation, red\'emarrez la calculatrice par appui sur le
bouton RESET si n\'ecessaire. 

{\bf Multi-boot}\\
Si vous avez install\'e une version r\'ecente de $\chi$CAS, votre
calculatrice peut dor\'enavant lancer deux firmwares~:
\begin{itemize}
\item une version du logiciel du constructeur Numworks,
d\'eriv\'ee de la version 15.5 d'Epsilon (c'est la derni\`ere version
dont la licence permet les modifications et redistribution, qui date
de mai 2021). C'est le firmware du slot 1.
Il est techniquement possible d'installer Epsilon 18 dans ce slot 1,
mais ce n'est pas recommand\'e, car l'utilisation de $\chi$CAS
n'est pas possible depuis Epsilon 18, il faut alors rebooter pour le
lancer depuis le slot 2.
Vous pouvez consulter la section \ref{sec:eps18} pour
trouver l'\'equivalent dans $\chi$CAS des fonctionnalit\'es
math\'ematiques qui ont \'et\'e ajout\'ees dans Epsilon par
rapport \`a la version 15.5.
\item un mini-firmware lanceur. Il n'affiche aucune des applications
du constructeur \`a part les param\`etres, mais permet
de lancer $\chi$CAS (et d'autres
applications externes) avec plus de m\'emoire disponible. 
C'est le firmware du slot 2.
\end{itemize}
Pour v\'erifier l'\'etat des slots de votre calculatrice,
maintenez la touche 4 enfonc\'ee et en appuyant sur le
bouton RESET \`a l'arri\`ere, puis relachez la touche 4. Cela
lance le multi-boot et affiche le contenu des slots. Notez que le slot 3
est incompatible avec $\chi$CAS (il s'agit du slot B du multi-boot
$\varphi$).

Pour passer du slot 1 au slot 2, appuyez sur
la touche 1 ou 2, faites simultan\'ement RESET \`a l'arri\`ere,
puis relachez la touche 1 ou 2. 

{\bf Protection contre des sites potentiellement malveillants}\\
Si vous ne l'avez pas d\'ej\`a fait, mettez \`a jour $\chi$ et $\chi$CAS afin
de b\'en\'eficier d'un minimum de protection si vous naviguez
sur Internet avec votre calculatrice branch\'ee.
Une fois cela fait, en fonctionnement normal,
il est impossible \`a un site d'\'ecrire dans la
flash de la calculatrice. Vous ne pourrez modifier
la flash qu'en activant le multi-boot (par reset+4)
ou le mode de r\'ecup\'eration (reset+6). 
{\bf Soyez particuli\`erement vigilants avant de faire reset+4 ou
  reset+6}. En particulier, si vous voulez conserver le controle de 
votre calculatrice (\'eviter un verrouillage)
et la compatibilit\'e avec $\chi$CAS, ne faites jamais reset+4 ou reset+6 depuis les
sites de Numowrks m\^eme si on vous le demande. Si votre calculatrice est bloqu\'ee ou pour
\'echanger des scripts, rendez-vous sur 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{mon
  kit de connexion Numworks}.

{\bf Mode examen}\\
L'installation de $\chi$CAS et $\chi$ dans les slots 1 et 2 est
conforme \`a la r\'eglementation fran\c{c}aise du mode examen.
Un surveillant d'examen qui souhaite s'assurer qu'une calculatrice
Numworks n'a pas subi de modifications pour frauder peut le certifier
depuis \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{mon
  kit de connexion Numworks}.

{\bf Lancement de $\chi$CAS}\\
Tapez sur la touche Back puis Entree pour lancer $\chi$CAS.

{\bf Licences d'utilisation~}:\\
la licence choisie par Numworks
pour son syst\`eme d'exploitation rend impossible la publication
d'un firmware binaire unique contenant \'egalement un logiciel libre.
Le logiciel est donc d\'ecompos\'e en deux parties,
\verb|khi.*|, sous licence
\ahref{https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode}
      {Creative Commons Attribution-NonCommercial-
  ShareAlike 4.0 International Public License}
et \verb|apps.tar| sous
licence \ahref{https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html}{GPL2}.

\subsection{Certification des calculatrices non verrouillées en examen.}
Contrairement à certaines rumeurs, 
{\bf utiliser des logiciels à source ouvert 
non installés par le constructeur sur sa calculatrice
n'est pas synonyme de fraude}, dès l'instant où ce logiciel respecte
la réglementation en vigueur, qui à ce jour est
\ahref{https://www.education.gouv.fr/bo/15/Hebdo42/MENS1523092C.htm}{ici},
complétée par le 
\ahref{http://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/irem/Calculatrices_examens_specifications_techniques.pdf}{cahier des charges}. 
C'est d'ailleurs le cas de KhiCAS sur des calculatrices graphiques 
d'autres marques.

De plus ici, il est possible de vérifier qu'une calculatrice non verrouillée
fait tourner un firmware et une version de $\chi$CAS n'ont pas été
modifiés et sont conformes
à la réglementation française du mode examen depuis
\ahref{https://xcas.univ-grenoble-alpes.fr/nw/nws.html#exam}{la page Numworks du site de Xcas}.
Le test peut se faire en moins de 30 secondes en connectant un ordinateur
(avec le cable fourni avec la calculatrice) 
ou une tablette ou un smartphone avec la calculatrice 
(avec un cable USB-C vers cable USB-C ou USB-micro
qu'on peut se procurer pour un prix entre 5 et 10 euros). \\
\includegraphics[width=10cm]{unlock15.png}
\includegraphics[width=10cm]{unlock16.png} 
\includegraphics[width=10cm]{unlock17.png}

Le code de la page web extrait la flash
externe de la calculatrice et compare la signature sha256
du firmware transmis et de l'application $\chi$CAS 
avec une base de données d'installations conformes.
%% La certification nécessite que l'élève ait exactement la même
%% installation que celles que j'ai enregistrées sur le site, 
%% ce qui nécessite
%% que le kernel et le firmware ont été générés à l'identique
%% (patchs et compilateur), donc une diffusion publique
%% du kernel et firmware au format binaire soit au titre
%% de l'interopérabilité, soit par autorisation de Numworks.
Me contacter pour plus d'informations.

\section{Installation sur Numworks verrouillée.}
Si vous ne vous sentez pas d'ouvrir votre calculatrice ou ne voulez
pas investir dans le matériel nécessaire, cette section est pour vous!

\subsection{Installation de base sur Numworks verrouillée,}
\label{sec:n120}
Si votre calculatrice est verrouillée et si vous ne voulez
pas la déverrouiller, 
vous pouvez quand même installer 
$\chi$CAS depuis la 
\ahref{https://xcas.univ-grenoble-alpes.fr/nw/nws.html}{page Numworks du site de Xcas} 
en utilisant un navigateur webUSB compatible (Chromium, Chrome, Edge...).

Mais cette version de $\chi$CAS n'est pas accessible en mode
examen, alors que la réglementation française autorise le calcul
formel aux examens et que Numworks propose un mode examen
spécifique à la France. Ceci défavorise les élèves qui possèdent
une Numworks verrouillée par rapport à leurs camarades qui
peuvent se payer une calculatrice CAS constructeur (environ
deux fois plus chère), Numworks porte avec les décideurs
qui imposent le mode examen l'entière responsabilité
de cette inégalité.

De plus les applications externes sont désactivées
en cas de reset (et en cas de crash sur Epsilon 20 à 24), il faut
alors réinstaller
\ahref{https://xcas.univ-grenoble-alpes.fr/nw/nws.html#etape4}{en cliquant sur le bouton lanceur}
ou 
\ahref{https://xcas.univ-grenoble-alpes.fr/nw/nws.html#reactiver}{réactiver}
avec un ordinateur le lanceur de $\chi$CAS, dans le premier cas cela
pourrait engendrer une usure prématurée du secteur correspondant
de la mémoire flash (en particulier pour les développeurs
d'applications externes pour qui il peut être nécessaire
de faire plusieurs dizaines de tests par jour avant
de localiser et corriger des erreurs). Numworks
est au courant de ces problèmes, mais ne donne pour l'instant
aucun signe de vouloir les résoudre.
La section \ref{sec:optimal} explique comment atténuer cet inconvénient
sur N0110 et N0115 de manière purement logicielle. Si vous êtes pressé vous
pouvez passer tout de suite à la section \ref{sec:firststep}
et y revenir plus tard.

\subsection{Installation optimisée sur N0110 verrouillée et sur N0115.}
\label{sec:optimal}
Cette section s'adresse aux personnes ne souhaitant pas ouvrir leur
calculatrice pour procéder à un déverrouillage matériel comme
expliqué à la section \ref{sec:unlock} mais qui veulent (un peu) optimiser
leur installation de $\chi$CAS, en l'installant sur Epsilon 19.5.
Cette section ne vous concerne pas si vous possédez~:
\begin{itemize}
\item une Numworks N0120, en effet à ma connaissance, 
il n'y a pas eu de version publique de Epsilon $<20$ avec support
des applications externes.
\item
une Numworks N0110 déverrouillable,
si vous arrivez à vous procurer une image binaire 
signée d'un firmware Epsilon 18.2
et à la lancer. En effet, si vous arrivez à lancer Epsilon 18.2, vous pourrez 
déverrouiller une N0110 sans l'ouvrir
\ahref{https://phi.getomega.dev/}{avec le jailbreak Phi}.
Si vous n'avez pas d'image binaire d'Epsilon 18.2, la section \ref{sec:18.2}
explique comment en créer une.
\item une Numworks N0110 verrouillée avec Epsilon $\geq 24.11.0$. En
effet, Numworks a activé un mécanisme anti-downgrade qui empêche
d'installer des versions antérieures de Epsilon. Ce mécanisme
utilise un ``niveau de sécurité'', lu au début du kernel, et
empêche le lancement d'un kernel dont le niveau de sécurité est
strictement inférieur à celui du bootloader. Si le niveau
de sécurité du kernel est strictement supérieur à celui du bootloader,
le bootloader met à niveau son niveau de sécurité, ce qui est
irréversible (sauf déverrouillage matériel bien sur).
\end{itemize}
Cette section vous concerne 
si vous possédez une N0110 non déverrouillée ou une N0115 
et arrivez à vous procurer une image binaire signée d'Epsilon 19.5,
je vous conseille alors de l'utiliser pour installer $\chi$CAS.
En effet, avec Epsilon 19.5, les applications externes sont automatiquement
réactivées en sortie de mode examen et en cas de crash ou reset,
on peut réactiver toutes les applications externes simultanément,
par exemple en cliquant sur le 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nws.html#reactiver}{bouton rendre visibles les apps externes} de ma page Numworks
ou par la commande\\
\verb|dfu-util -i 0 -a 0 -s 0x90200000:leave|\\
avec un avantage important, cette commande ne réécrit rien 
sur la flash de la calculatrice,
ce qui évite une usure prématurée (on peut déplorer que Numworks
n'ait pas eu ce souci en tête pour les applications externes
sur les versions ultérieures
d'Epsilon, alors que pour le mode examen, il en tiennent compte).

Pour installer une version d'Epsilon, 
faire reset+6 sur la calculatrice (maintenir appuyé
la touche 6 tout en enfonçant puis relachant la touche reset), allez
sur \ahref{https://ti-planet.github.io/webdfu_numworks/}{le site webdfu de tiplanet} et choisissez Flash Slot A (0x90000000).
Si vous arrivez à booter Epsilon 18.2 sur une N0110, 
rendez-vous \ahref{https://phi.getomega.dev/}{ici pour la déverrouiller},
installez le \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/boot/n0110/bootloader_patched.bin}{bootloader d'Upsilon} puis installez $\chi$CAS
comme expliqué en section \ref{sec:unlocked15} ou \ref{sec:unlocked16}.

La suite de cette section est un peu technique, 
mais je ne vois pas comment l'éviter. Elle explique comment
générer un firmware 18.2, pourquoi
la fourniture à un tiers d'un patch de 
firmware Epsilon 19.5 est très probablement
légale en vertu des lois sur l'interopérabilité, 
et comment faire tourner une version plus récente d'Epsilon
sur Epsilon 19.5.
Pour effectuer les manipulations techniques, 
on suppose que le lecteur a accès à une machine Linux debian ou ubuntu
ou compatible (par exemple dans une
machine virtuelle, ou depuis WSL sous Windows).

Sur les versions d'Epsilon $\geq$ 20, à chaque reset 
(et crash jusqu'en version 24), 
sous prétexte de sécurité,
Epsilon sabote les applications externes installées en
mettant à 0 le 1er octet du secteur de flash, sans rien demander 
à l'utilisateur. Ceci nécessite une 
réinstallation de l'application externe à chaque fois, 
ce qui décourage fortement
l'utilisation d'applications externes (surtout si on en a plusieurs), 
et cela risque de diminuer inutilement
la durée de vie de la flash de la calculatrice (le nombre de cycles
d'effacement et écriture de la flash est limité). 
Aucun des constructeurs
concurrents (TI, Casio) n'agit ainsi. 

Dans cette section, on explique comment générer un firmare Epsilon 18.2 
qui permet de déverrouiller logiciellement la calculatrice
dans certains cas, ou comment utiliser Epsilon 19.5. Il
est essentiel ici de comprendre que l'amorçage de la calculatrice
autorise l'exécution d'un firmware en flash externe
uniquement s'il est signé par Numworks. 
La version 18.2 d'Epsilon est la dernière version pour laquelle
le code source complet du firmware exécuté en flash externe est
disponible. 

\subsubsection{Générer un firmware 18.2 pour tenter le déverrouillage d'une N0110 sans l'ouvrir.} \label{sec:18.2}
Cette section est à destination des personnes qui ont une Numworks
N0110 qui a été verrouillée par 
mise à jour vers Epsilon $\geq$16 entre 2021 et fin 2022, et
qui n'ont pas réussi à se procurer un firmware 18.2 par d'autres
moyens.

On peut reproduire un firmware 18.2 non signé identique à Epsilon
de la manière suivante sur un système Linux 
\begin{verbatim}
  apt-get install build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config python3 python3-pip dfu-util bsdiff
  pip3 install lz4 pypng stringcase
  cd ~/Downloads
  wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/10-2020q4/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
  cd /usr/local
  sudo tar xfa ~/Downloads/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
  export PATH=/usr/local/gcc-arm-none-eabi-10-2020-q4-major/bin:$PATH
  cd
  git clone https://github.com/parisseb/epsilon
  mv epsilon epsilon18
  cd epsilon18
  git checkout 6f231d531fa74574e00f6b266ed4d9c86a9d5ab3
  make kernel.A.bin
  make userland.onboarding.A.bin
\end{verbatim}
Il suffit de concaténer le kernel et l'userland 
\begin{verbatim}
  cp output/release/device/n0110/kernel/kernel.A.bin kernel18.bin
  truncate -s 65536 kernel18.bin
  cp output/release/device/n0110/userland/userland.onboarding.A.bin userland18.bin
  cat kernel18.bin userland18.bin > epsilon18.bin
\end{verbatim}
et d'ajouter la signature pour obtenir un firmware signé
18.2, par exemple avec hexedit~:\\
\verb|hexedit epsilon18.bin| \\ 
Cette signature n'est pas soumise au copyright,
car obtenue par un procédé algorithmique complètement déterministe,
ce n'est donc pas une oeuvre originale de l'esprit, elle n'a de plus
jamais été secrète (puisque le firmware 18.2 a été diffusé publiquement
par Numworks pendant plusieurs mois en 2022), il s'agit d'une 
information au sens de l'article L122-6-1 IV pour permettre
le déverrouillage des calculatrices qui ont été verrouillées
avant la sortie d'Epsilon 19 et l'utilisation de tous les logiciels
rendus incompatibles avec Epsilon 16 (\ahref{https://getomega.dev/}{Omega}, \ahref{https://getupsilon.web.app/}{Upsilon}, Khi...), sa diffusion
est donc légale. Elle se décompose en deux parties
\begin{itemize}
\item au début du kernel, les 4 premiers octets doivent être mis à 0.
Il s'agit d'un niveau de sécurité permettant à Numworks dans le futur
de refuser de faire tourner un kernel signé si le niveau de sécurité
inscrit en flash interne de la calculatrice est supérieur 
strict au niveau de sécurité
du kernel (donc ici dès que le niveau de sécurité en flash interne
est non nul)\\
Les 4 octets suivants indiquent l'offset de la signature à partir
de l'offset 8. Sur les 18.2, il faut indiquer 70 24 12 00, donc l'offset de la 
signature est 0x122478.
\begin{verbatim}
00000000   00 00 00 00  70 24 12 00  F0 0D C0 DE  31 38 2E 32 
\end{verbatim}
\item En 0x122478, la signature elle-même sur les 64 derniers octets.
Je peux l'envoyer à toute personne qui en a besoin pour
interopérabilité avec KhiCAS sur simple demande par email
en indiquant ce motif.
%% \begin{verbatim}
%% 00122470                             C4 C8 E4 EE  3B E9 5F 8F  E...........;._.
%% 00122480   4E 28 2A D9  F7 2A F2 D6  C7 D4 96 CD  40 BE E1 B3  N(*..*......@...
%% 00122490   2D C6 29 0F  41 D0 8A 5D  8B AE 42 BC  5F B5 AD 29  -.).A..]..B._..)
%% 001224A0   55 0E 70 35  20 91 A9 F3  C4 F4 3D 8E  30 9F BD 64  U.p5 .....=.0..d
%% 001224B0   12 C5 79 48  3A 8A 87 0D 
%% \end{verbatim}
\end{itemize}
Sur certaines calculatrices verrouillées, vous pourrez installer
ce firmware en maintenant appuyé la touche 6 tout en appuyant sur la touche
reset au dos de la calculatrice, puis relâchez reset puis 6. Vous
pouvez maintenant flasher la calculatrice
depuis le \ahref{https://ti-planet.github.io/webdfu_numworks/}{le site webdfu de tiplanet} ou par la commande~:\\
\verb|dfu-util -i 0 -a 0 -s 0x90000000 -D epsilon18.bin|\\
Après reset, si le firmware démarre, félicitations, vous pouvez maintenant
déverrouiller votre calculatrice avec le
\ahref{https://phi.getomega.dev/}{jailbreak Phi}, puis installer
le bootlodaer d'\ahref{https://getupsilon.web.app/}{Upsilon} 
ou de \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{Khi} ou de
\ahref{https://getomega.dev/}{Omega} et passer à la section 
\ref{sec:unlocked16} ou \ref{sec:unlocked15}.


\subsubsection{Utiliser un firmware 19.5 (n0110/n0115)} \label{sec:19.5}
Malheureusement, il n'est pas possible d'utiliser Epsilon 18.2 directement
sur la plupart des machines verrouillées, car les bootloaders
plus récents de Numworks interdisent le downgrade vers
la version 18.2 vulnérable au jailbreak Phi.
Techniquement parlant, Numworks a ajouté une 2ème signature, distincte
de la précédente, et qui couvre également les 8 premiers octets du noyau,
et le bootloader utilise cette signature 
si il a été installé après le printemps 2022. Les firmwares à partir
de la version 19 contiennent les deux signatures, permettant
l'utilisation sur les deux versions de bootloader.
{\bf Attention}, en mars 2026, Numworks a incrémenté le niveau de sécurité
de ses firmwares. Si vous avez fait une mise à jour vers Epsilon 25 (ou 24.11),
il est trop tard,
vous ne pourrez plus redescendre vers des version antérieures, donc
pas vers Epsilon 19.5. Vous pouvez vérifier la version d'Epsilon
dans Paramètres, A propos.

Le point critique est donc de 
se procurer une version signée du firmware 19.5 pour N0110 ou N0115.
Le plus simple est évidemment
d'en obtenir une copie depuis une calculatrice 
installée avec Epsilon 19.5, en extrayant le firmware
par exemple depuis le 
\ahref{https://ti-planet.github.io/webdfu_numworks/}{webDFU de tiplanet} 
ou avec dfu-utils
\begin{verbatim}
dfu-util -i 0 -a 0 -s 0x90000000:0x200000:force -U epsilon19.5.bin
\end{verbatim}

Remarque~: 
une grosse partie du source de ce firmware (l'userland, un peu plus 
de 1M) est disponible sur github, et peut donc être recompilé à l'identique.
\begin{verbatim}
  git clone -b version-19 https://github.com/parisseb/epsilon
  mv epsilon epsilon19
  cd epsilon19
  make userland.onboarding.A.bin
\end{verbatim}
Une petite partie, le kernel (32K environ), n'est plus disponible en code source
depuis la version 18.2, elle est soumise au copyright de Numworks
qui empêche sa rediffusion sans autorisation. Ce noyau n'apporte aucune
fonctionnalité originale par rapport au noyau de la version 18.2, il a pour
seule fonction d'interfacer avec le matériel physique de la calculatrice.
Sans protection au démarrage, on pourrait interfacer le kernel 18.2 et 
l'userland 19.5.
Mais ici il est indispensable d'avoir un kernel 19.5 avec l'userland 19.5, 
car ils sont combinés dans la signature.
Sans être juriste, il me semble donc que la rediffusion d'un patch
permettant de passer du kernel 18.2 au kernel 19.5 
est conforme à l'esprit de 
l'article L122-6-1 du code de la propriété intellectuelle, 
pour assurer l'interopérabilité des applications externes
de manière normale (sans usure prématurée de la flash, et avec
réactivation des applications externes simultanément), mais je conseille
plutôt le déverrouillage matériel.
Muni du kernel et du userland, il faudra encore rajouter la 2ème signature pour
pouvoir booter ce firmware. 
Le script \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/mk19.5}{mk19.5} permet de générer un firmware 19.5 à l'aide de 2 fichiers
de patch (kernel 18.2 vers 19.5 et signature 19.5).

Pour installer Epsilon 19.5, faire reset+6 sur la calculatrice puis envoyer
le firmware depuis
\ahref{https://ti-planet.github.io/webdfu_numworks/}{le site webdfu de tiplanet}
ou avec une commande du type\\
\verb|dfu-util -i 0 -a 0 -s 0x90000000 -D epsilon19.5.bin|\\
Une fois Epsilon 19.5 installé, vous pouvez ajouter des applications
externes, et en cas de cycle d'activation/désactivation du mode
examen, elles seront automatiquement réactivées, en cas de crash/reset,
il suffit de rendre visible
les applications externes depuis Epsilon 19.5, avec la commande\\
\verb|dfu-util -i 0 -a 0 -s 0x90200000:leave|\\
ou depuis le \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nws.html#reactiver}{bouton rendre visible les apps externes} de ma page Numworks


\subsubsection{Epsilon sur Epsilon 19.5}
Si vous avez besoin de fonctionnalités des versions
plus récentes de Epsilon, il est possible d'installer un lanceur
de firmware en tant qu'application externe, et de 
recompiler un firmware, ici Epsilon 23.2.3 ou 24.10/11,
à partir du source disponible sur github et de modifications 
pour 
\begin{itemize}
\item empêcher l'écrasement du secteur de lancement des applications
externes
\item faire fonctionner ce firmware à la suite d'Epsilon 19.5 et
de l'application lanceur de firmware, dans la première partie
de la flash (slot A), pour laisser assez de place
contigüe pour $\chi$CAS (dans la seconde partie, slot B).
\end{itemize}
Commencez par cloner la branche du dépot Epsilon (24)\\
\verb|git clone -b backup24 https://github.com/parisseb/epsilon|\\
ou pour la version 23\\
\verb|git clone -b version-23 https://github.com/parisseb/epsilon|\\
Modifications à apporter à  
{\tt ion/src/device/include/n0110/config/board.h}
pour ``shifter'' l'userland de 0x160000 octets, aux lignes 69, 75, 88~:
\begin{verbatim}
69c69
< constexpr uint32_t SlotAOffset = 0x00160000;
--- au lieu de
> constexpr uint32_t SlotAOffset = 0;
75c75
< constexpr uint32_t PersistingBytesVirtualOrigin = ExternalFlashOrigin + ExternalFlashLength / 2 - PersistingBytesLength - SlotAOffset;
--- au lieu de
> constexpr uint32_t PersistingBytesVirtualOrigin = ExternalFlashOrigin + ExternalFlashLength / 2 - PersistingBytesLength;
88c88
< constexpr uint32_t UserlandLength = 0x280000; // ExternalFlashLength / 2 - KernelLength - ExtraDataLength - PersistingBytesLength;
--- au lieu de
> constexpr uint32_t UserlandLength = ExternalFlashLength / 2 - KernelLength - ExtraDataLength - PersistingBytesLength;
\end{verbatim}
Modification pour éviter l'écrasement du secteur de lancement
des apps externes, fichier
{\tt ion/src/device/userland/drivers/external_apps.cpp},
rechercher la fonction \verb|App::eraseMagicCode() {| et mettre au début
\begin{verbatim}
   return; // do not erase magic code
\end{verbatim}
%% et pour autoriser les applications externes depuis 23.2.3, 
%% modifications du fichier
%% {\tt ion/src/device/userland/Makefile}
%% \begin{verbatim}
%% 11c11
%% <   external_apps.cpp: \
%% ---
%% >   external_apps.cpp:+allow3rdparty \
%% 15a16,19
%% > )
%% >
%% > ion_device_userland_src += $(addprefix ion/src/shared/dummy/, \
%% >   external_apps.cpp:-allow3rdparty \
%% \end{verbatim}

On compile avec\\
\verb|make userland.A.allow3rdparty.bin # V=1|\\
Puis selon la version d'Epsilon faire, pour Epsilon 23
\begin{verbatim}
truncate -s 1572864 output/release/device/n0110/userland/userland.A.allow3rdparty.bin
cp output/release/device/n0110/userland/userland.A.bin userland23.bin
objdump  -C -t output/release/device/n0110/userland/userland.A.elf | sort > dump110_t
\end{verbatim}
et pour Epsilon 24
\begin{verbatim}
cp output/release/n0110/userland.A.allow3rdparty.bin userland24.bin
truncate -s 1441792 userland24.bin
objdump  -C -t output/release/n0110/userland.A.allow3rdparty.elf | sort > dump110_t
\end{verbatim}
%% Les modifications du Makefile ci-dessus ne sont peut-être pas nécessaire 
%% si on fait\\
%% {\tt make userland.A.allow3rdparty.bin}

Puis on envoie ce userland, qui commence en 0x90170000, avec une
des deux commandes\\
\verb|dfu-util -i 0 -a 0 -s 0x90170000 -D userland23.bin|\\
\verb|dfu-util -i 0 -a 0 -s 0x90170000 -D userland24.bin|\\
Pour pouvoir accéder à Epsilon 23.2.3 ou 24.10/11 depuis Epsilon 19.5, 
on envoie le 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/run.bin}{lanceur de firmware}
avec la commande\\
\verb|dfu-util -i 0 -a 0 -s 0x90150000 -D run.bin|\\
Le source de ce lanceur de firmware est
disponible \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/run.zip}{ici}, il détecte un firmware à lancer sur les secteurs de flash
0x17 à 0x1f.

On peut maintenant profiter de Epsilon 23.2.3 ou 24.10/11 
avec des contraintes de réinstallation d'applications externes
allégées. 
En cas de crash/reset, il suffit de rendre visible
les applications externes d'Epsilon 19.5, avec la commande\\
\verb|dfu-util -i 0 -a 0 -s 0x90200000:leave|\\
ou depuis le \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nws.html#reactiver}{bouton rendre visibles les apps externes} de ma page Numworks, puis on relance
l'application lanceur du firmware 23.2.3/24.10/11.

\subsection{Installation optimisée sur N0120/N0115/N0110 avec Delta sur Epsilon}
\label{sec:delta}
Delta est un dérivé d'Epsilon 15.5 avec les améliorations d'Upsilon, 
qui a été modifié
pour pouvoir s'exécuter sur un noyau Epsilon ($\geq 19$). Sur une
machine verrouillée, il est possible de lancer Delta depuis
une application externe installée sur l'OS officiel 
(Epsilon) de la calculatrice~:
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nws.html#install}{installation de Delta}.
C'est une construction à plusieurs étages~:
\begin{itemize}
\item le noyau Epsilon officiel
\item le userland Epsilon officiel qui se lance au démarrage de la calculatrice
\item l'application externe lanceur de firmware tiers, 
il faut une version binaire pour chaque
version du Epsilon officiel
\item le firmware tiers, ici Delta. Une fois Delta lancé,
le userland officiel Epsilon ne fait plus rien.
\item Delta a ses propres applications externes, dans un format
analogue à celui de Omega/Upsilon/Khi. La présence d'un secteur
de flash dédié au mode examen nécessite de fractionner les applications
externes en deux parties, la partie ``rodata'' (read-only data) qui 
s'installe avant le secteur du mode examen, et le reste qui s'installe
après.
\end{itemize}
Si vous ne voulez pas installer via le navigateur,
ci-dessous des binaires précompilés.
\begin{enumerate}
\item 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/n110unlocked.zip}{pour n0110/n0115}.
Vérifiez (dans Paramètre, A propos) votre version d'Epsilon
et passez en mode recovery (reset+6) puis
\begin{itemize}
\item version 19.5
lancer le script \verb|sendn110redist19| pour la 1ère installation.
Lancer le script \verb|activate19| à chaque reset/crash.
\item autres versions
lancer le script \verb|sendn110redist| pour la 1ère installation.
Lancer le script \verb|senddelta_sector1?| à chaque reset,
en remplaçant le \verb|?| par 7 pour Epsilon 24/25, 8 pour Epsilon 21, 22
et 9 pour Epsilon 23.
Si vous n'avez pas besoin des nouvelles fonctionnalités d'Epsilon 20 
ou plus récentes, je vous conseille vivement de passer en Epsilon 19.5,
car la réactivation de l'application externe lanceur ne nécessite pas
de formatter le secteur de la flash de la calculatrice qui le lance.
\end{itemize}
\item 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/n120unlocked.zip}{pour n0120}.
Passer en mode recovery (reset+6) et 
lancer le script \verb|sendn120redist| pour la 1ère installation.
Lancer le script \verb|senddelta120_sector1?| à chaque reset,
en remplaçant le \verb|?| par 7 pour Epsilon 24/, 8 pour Epsilon 21, 22, 25
et 9 pour Epsilon 23.
Comme pour les n0110, cela use le secteur de lancement, mais il n'existe
pas à ma connaissance de version 19.5 pour n0120 autorisant
les applications externes.
\end{enumerate}
Si vous préférez recompiler, les sources sont
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/delta.tar.bz2}{Delta} (depuis le répertoire ion avec un des shells scripts
\verb|mk110, mk120, link*|, et en adaptant les fichiers ld 
flash et n0120.ld ou n0110.ld) et 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/runups.zip}{l'application lanceur} (exécuter \verb|./addr| avec
la Numworks branchée, pour générer
le fichier \verb|ram.ld|, puis \verb|make clean; make| qui
génère \verb|app.bin| à envoyer par \verb|./sendapp|).
Les applications externes ne sont pas spécifiques à un firmware, voici
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/runups.zip}{le source des apps externes} qu'on compile avec \verb|mkarm110b|
ou \verb|mkarm120b| du répertoire \verb|khiext|.

Une fois l'installation effectuée,
vous pouvez sauvegarder votre flash externe depuis le 
\ahref{https://ti-planet.github.io/webdfu_numworks/}{webDFU de tiplanet},
ou par
\begin{verbatim}
#! /bin/bash
/bin/rm flash.bin
dfu-util -i 0 -a 0 -s 0x90000000:force:0x800000 -U flash.bin
\end{verbatim}
et cloner votre installation sur d'autres machines identiques
en mode récupération, soit
depuis le site de TI Planet, soit par la commande
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90000000 -D flash.bin
\end{verbatim}



\section{Simulateur de Numworks avec $\chi$CAS (smartphone, tablette, vidéoprojection...)}
Pour des questions de licences logicielles, il semble actuellement 
nécessaire de compiler soi-même le simulateur si on veut utiliser 
une version d'Epsilon récente,
dont la license est maintenant "All rights reserved".
Si c'est plutôt Xcas (ou Python) qui vous int\'eresse,
vous pouvez {\bf utiliser le simulateur d'Upsilon, bas\'e
sur Epsilon 15.5, avec Xcas}. Il est entièrement compatible
avec l'installation de Delta sur calculatrice déverrouillée 
(section \ref{sec:delta}).
\begin{enumerate}
\item Version sans installation,
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/kcasfr.html}{utilisable depuis un navigateur} compatible (Firefox, Chrome,...).\\
Pour lancer Xcas depuis le menu principal de la Numworks simulée, 
appuyez/cliquez sur la touche
Back de la calculatrice simulée.\\
Cette version permet de partager facilement une session de calculs Xcas
éventuellement accompagné d'un programme, 
en affichant un QR-code qu'on peut flasher avec
un smartphone ou une tablette. Pour afficher le QR-code de la session,
tapez sur la touche Power du simulateur. Sur une
calculatrice, il suffit de sauvegarder la session~: taper shift EXE,
puis choisir 2 ou 3. Appuyez sur la touche Back pour revenir au shell.\\
Si vous êtes enseignant, vous pouvez préparer une session 
avec le simulateur ou avec Xcas et vidéo-projeter le QR-code,
vos élèves peuvent alors le flasher avec un smartphone ou une tablette.\\
Les versions à jour de Xcas pour calculatrices Numworks et Casio 
permettent également d'afficher un QR-code pour partager une
session. Mais les calculatrices n'ont pas de lecteur de QR-code donc
ne permettent pas de charger une session de cette manière.
\item PC avec Windows~: t\'el\'echargez 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/upsilon.zip}{upsilon.zip},
ouvrez l'archive et ex\'ecutez {\tt upsilon.exe}
\item Mac version stable (test\'e avec OS 14.4 et 12.7.1)~: t\'el\'echargez
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/Upsilon.dmg}{Upsilon.dmg},
ouvrir l'image disque {\tt Upsilon.dmg} et installez.\\
Remerciements \`a Adrien Bertrand 
qui m'a aid\'e pour ce portage et a sign\'e ce package.
% \item derni\`ere version pour Mac~: t\'el\'echargez
% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/upsilon.dmg}{upsilon.dmg},
% ouvrir l'image disque {\tt upsilon.dmg}.
% Pour installer, faire un clic droit sur {\tt Upsilon.pkg}
% en maintenant la touche Control enfonc\'ee, choisir Ouvrir
% puis suivre les instructions. L'application {\tt upsilon.app}
% est alors install\'ee dans les \verb|/Applications|.\\
% Si vous n'\^etes pas administrateur, ouvrez un Terminal
% (tapez Terminal depuis le launchpad) et copiez-collez
% \begin{verbatim}
% cd /tmp
% tar xvf /Volumes/upsilon/Upsilon.pkg Payload
% cd /Applications
% tar xvf /numworks/Payload
% \end{verbatim}
\item Linux ou compilation depuis le source~:
\begin{verbatim}
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/upsilon.tar.bz2
tar xfj upsilon.tar.bz2
cd Upsilon
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
tar xfj ext.tar.bz2
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/upsilon_cas_full.tgz
tar xfz upsilon_cas_full.tgz
\end{verbatim}
puis ex\'ecuter \verb|mksimu| (Linux) ou \verb|mkmac| (Mac) ou
\verb|mkwin| (Windows). La compilation de la version javascript fonctionne
avec emscripten 1.40 et le script \verb|mkw|, elle nécessite
des versions des librairies GMP, MPFR et MPFI compilées avec \verb|-fPIC|,
ces libraries se trouvent dans l'archive 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/giac/emgiac3.tgz}{emgiac3}, ce répertoire contient aussi  
une copie de 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/giac/emsdk_1.40.1.tar.bz2}{emscripten 1.40.1} 
installée
sous Ubuntu 20 pour architecture \verb|x86_64|.
\end{enumerate}
Voici maintenant une {\bf procédure de compilation
semi-automatisée pour Epsilon 22+Xcas}
(si vous souhaitez savoir ce qui
se passe sous le capot, rendez-vous à la section \ref{sec:eps22})
\begin{enumerate}
\item PC avec Windows
\begin{enumerate}
\item Installez \ahref{https://www.msys2.org}{msys2/mingw64}
\item
Ouvrir un terminal mingw64 depuis le menu principal de toutes les 
applications windows, msys2. Dans le menu Options de la fenêtre mingw64
(coin en haut à gauche), 
sélectionner Keys, puis cocher Ctrl-shift-letter shortcut,
ceci vous permettra de coller avec Ctrl-shift-V.
\item
copiez-collez dans le terminal (Ctrl-C puis Ctrl-shift-V) \\
\verb|  pacman -S wget|\\
\verb|  wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwwin|\\
\verb|  ./nwwin|\\
Patientez, le temps que le compilateur fasse le travail. 
Si tout va bien le simulateur \verb|epsilon.exe| 
va s'ouvrir. L'exécutable du simulateur est
\verb|c:\msys64\home\username\epsilon\epsilon.exe| 
où \verb|username| est votre nom d'utilisateur.
Vous pouvez le recopier dans un autre répertoire ou sur un autre PC.\\
Attention, les licences ne permettent pas la publication de cet exécutable.
\end{enumerate}
\item Mac~:
\begin{enumerate}
\item Depuis le launchpad, tapez Terminal dans le champ de recherche, 
ceci vous permet d'ouvrir un Terminal
\item Téléchargez le fichier 
  \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nwmac}{nwmac}, vérifiez qu'il se trouve dans votre répertoire Téléchargements
(Downloads)
\item Copiez-collez (command-c et command-v) la commande \\
  \verb|  ~/Downloads/nwmac|\\
Patientez, le temps que le compilateur fasse le travail. 
Si tout va bien le simulateur 
va s'ouvrir. Il a été automatiquement recopié dans le répertoire
\verb|/Applications| et peut donc se lancer comme n'importe
quelle autre application. 
\item Optionnel~: si vous souhaitez faire une installation sur un autre Mac
dans un cadre d'utilisation privée\\
Un package \verb|Khicasnw.pkg| 
a été créé dans le répertoire Téléchargements. Vous
pouvez faire une image disque en lançant l'utilitaire de disque 
Mac puis menu Fichier, nouvelle image. Recopiez
le package dans l'image disque, éjectez l'image disque du Finder 
puis recopiez l'image disque vers l'autre Mac (par le réseau
ou avec une clef USB), et ouvrez-là
avec le Finder de l'autre Mac puis cliquez sur le package en maintenant
la touche Control enfoncée.\\
Attention, les licences ne permettent pas la publication de cette image disque.
\end{enumerate}
\item Linux~: cf. la section \ref{sec:eps22}
\end{enumerate}

{\bf Pour lancer le simulateur}, tapez \verb|./simu| (Linux) ou
cliquez sur \verb|upsilon.exe| (windows) ou
ouvrir \verb|upsilon.app| dans \verb|Applications| (mac) 
(ou \verb|epsilon.app| depuis le répertoire \verb|epsilon| 
si vous compilez la version
Epsilon 22). Ensuite pour lancer $\chi$CAS, vous pouvez utiliser le
raccourci Esc depuis le menu principal de la Numworks simulée. 
Attention, la touche shift du clavier ne simule pas
la touche shift de la calculatrice, afin de pouvoir composer les
caractères tels que 1 à 9 ou 0 sur un clavier français. Il faut taper
la touche Alt gauche du PC ou Opt gauche du Mac pour simuler 
un appui sur shift. 
Pour faire une copie d'écran du simulateur, tapez Ctrl-P, sous Linux
la copie est sauvegardée sous le nom \verb|/numworks/epsilon.png|, 
pensez à le renommer avant une nouvelle capture écran. Le source
du simulateur prévoit de pouvoir faire shift-Ctrl-P pour 
copier dans le presse-papier, mais ce n'est pas encore fonctionnel
avec Linux/Windows, seulement sur Mac.
%% Pour sauvegarder l'état du simulateur, tapez Ctrl-S, sous Linux
%% l'état est sauvegardé sous le nom \verb|/numworks/epsilon.nws|.

Le simulateur simule la flash utilisateur avec un fichier
nommé \verb|scripts.tar|. Vous pouvez le créer avec
l'utilitaire d'achivage \verb|tar|  en y mettant des sessions Xcas
(sauvegardées dans Xcas 
depuis le menu Fichier, Exporter comme, HP/Casio)
et des scripts Python. Vous pouvez utiliser comme exemple
le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/khi92.tar}{khi92.tar}
dont l'installation est proposée en même temps que $\chi$CAS
sur les calculatrices,
il suffit de le renommer \verb|scripts.tar| et de le copier
dans le r\'epertoire \verb|Documents| sur Mac 
ou dans le r\'epertoire courant sur Linux/Windows.

\section{Premiers pas} \label{sec:firststep}
N.B.~: vous pouvez aussi consulter ce \ahref{https://github.com/Yaya-Cout/$\chi$CAS_guide/blob/626b9786ff19504152628cfa42447c87ab73f648/$\chi$CAS_guide.pdf}{Tutoriel par fmOOmf et Yaya.Cout}.

Depuis le menu principal de la Numworks, 
d\'eplacez le curseur jusqu'\`a l'icone $\chi$CAS
puis tapez EXE (raccourci clavier, selon la version de $\chi$CAS + ou Back,
puis EXE). 
Ceci ouvre un ``shell'' dans lequel vous pouvez
taper la plupart des commandes de calcul formel de Xcas.
Au premier lancement, vous avez le choix de l'\'evaluateur entre
Xcas et MicroPython, on suppose ici que vous choisissez Xcas en tapant
OK ou EXE. Si vous avez choisi MicroPython, lisez la section
correspondante \ref{sec:micropy}. Pour passer \`a Xcas
(respectivement Python), depuis une ligne de commande vide, taper les
touches \verb|shift ) 8 OK|. 
%% Attention
%% sur les Numworks N0115/N0120/N0110 verrouillées (section \ref{sec:n120}), 
%% il faut taper  les touches \verb|shift| et \verb|)| en même temps.

Par exemple, tapez 
\verb|1/2+1/6|
puis EXE, vous devriez voir le r\'esultat \verb|2/3| s'afficher
sur la ligne du dessous. 

Vous pouvez recopier dans la ligne de commande
une commande de l'historique en utilisant le
curseur vers le haut ou vers le bas puis EXE, puis vous pouvez
modifier la commande et l'ex\'ecuter. Par exemple, taper sur la
touche curseur vers le haut, EXE et remplacez \verb|1/6| par \verb|1/3|.

Vous pouvez utiliser le r\'esultat de la derni\`ere commande
avec la touche \verb|Ans| de la calculatrice.
Il vaut en g\'en\'eral mieux d\'efinir une variable comme r\'esultat 
d'une commande si on souhaite la r\'eutiliser. Pour cela, on
utilise une des deux instructions d'affectation~:
\begin{itemize}
\item l'affectation vers la droite \verb|=>| s'obtient avec la 
touche \verb|sto|$\rightarrow$ de la 
calculatrice, par exemple \verb|2=>a| met 2 dans la variable a.
Vous pouvez ensuite utiliser \verb|a| dans un calcul, sa
valeur sera remplac\'ee par 2.
\item l'affectation vers la gauche \verb|=|.
Par exemple \verb|a=2| fait la m\^eme chose que \verb|2=>a|.
\end{itemize}
%% Si vous commencez une ligne de commande en tapant la touche $\rightarrow$,
%% le syst\`eme ins\'ere automatiquement \verb|Ans=>| ce qui permet 
%% facilement de donner un nom au r\'esultat d'une commande.

Pour vous aider \`a saisir les commandes Xcas les plus utiles,
$\chi$CAS dispose d'un catalogue d'une centaine de commandes,
avec une courte description et le plus souvent un exemple 
d'ex\'ecution facile \`a recopier. 
Appuyez sur 
la touche Toolbox, choisissez une cat\'egorie avec le curseur, 
par exemple \verb|Algebre|, tapez EXE,
puis choisissez une commande avec le curseur, par exemple \verb|factor|.
Un deuxi\`eme appui sur la
touche Toolbox vous affiche une courte description de la commande,
en g\'en\'eral avec un exemple. En tapant sur Ans (ou EXE), vous recopiez
l'exemple en ligne de commande. Vous pouvez alors valider (EXE) ou
modifier la commande et valider (EXE) 
pour factoriser un autre polyn\^ome que celui
donn\'e en exemple. Essayez avec \verb|factor| (touche Toolbox,
puis \verb|Algebre|).

Parmi ces commandes, celles qui sont le plus utilis\'ees sont accessibles
par des menus rapides activ\'es par la touche shift suivi d'un chiffre,
de \verb|.|, de {\tt 10^x}, de \verb|(| ou de \verb|)|, comme
le rappelle la ligne en bas de l'\'ecran, par exemple shift suivi
de 1 affiche un menu d'alg\`ebre o\`u on retrouve la commande
\verb|factor|. 

Lorsqu'une commande est entr\'ee sans arguments, un ``tooltip''
(petit rectangle sur fonds jaune) affiche une courte description de ce que fait
la commande et la syntaxe, pour voir en entier l'aide sur la commande
il suffit de taper sur la touche fl\`eche vers le bas (ou sur la touche var).
Taper sur Ans pour entrer les arguments du premier exemple de l'aide.
Taper sur la touche Back (\`a droite de OK) pour effacer le tooltip.

Lorsque vous ex\'ecutez une commande et qu'elle
renvoie une expression, celle-ci est affich\'ee
en \'ecriture naturelle (affichage 2-d). Vous pouvez faire d\'efiler 
l'affichage avec les touches du curseur lorsque l'expression est grande.
Tapez sur Back (\`a droite de OK) pour revenir au shell.

Maintenant essayez de taper la commande \verb|plot(sin(x))|.
Indication: tapez Toolboox, puis s\'electionner 
\verb|Courbes|, ou utilisez le menu rapide shift 3.

Lorsqu'une commande renvoie un graphe, celui-ci est affich\'e. Vous
pouvez modifier la fen\^etre graphique d'affichage 
avec les touches \verb|+| ou \verb|-| 
(zoom in ou out),
les touches du curseur, orthonormaliser le rep\`ere (touche \verb|/|)
ou faire une recherche automatique de l'\'echelle (autoscale 
touche \verb|*|). Pour enlever ou remettre les axes et graduations,
tapez sur var.
Tapez sur Back pour revenir au shell.

Vous pouvez effacer l'historique des calculs et les variables
pour commencer un nouvel exercice~: ouvrez le menu principal 
taper shift puis EXE,
s\'electionnez \verb|9 Effacer historique|.
Vous avez ensuite le choix entre
effacer l'\'ecran en conservant les variables
(OK) ou en les effa\c{c}ant (Back). Vous pouvez visualiser
la place occup\'ee par les variables en tapant sur la touche \verb|var|.
Pour effacer une variable pour faire de la place en m\'emoire,
s\'electionnez la commande \verb|purge| dans ce menu, puis
taper le nom de variable \`a effacer (ou s\'electionnez la variable
depuis le menu \verb|var|).

Pour revenir au menu principal de la Numworks,
il faut taper HOME. 
Sur la plupart des installations,
la touche HOME renvoie directement au menu principal de la Numworks,
pour accéder au menu de $\chi$CAS, il faut
taper les touches shift puis EXE.
Sur les N0110 non verrouillées avec Omega/Upsilon/Khi, la touche HOME
ouvre le menu de $\chi$CAS, pour revenir au menu de la Numworks,
il faut taper HOME plusieurs fois (2 fois depuis le shell).

Lorsque vous quittez $\chi$CAS,
les variables et l'historique des calculs
sont sauvegard\'es, ils seront restaur\'es lorsque vous reviendrez
dans $\chi$CAS.

Remarques~:
\begin{itemize}
\item
  Depuis le shell de calcul, les touches 1 \`a 9, 0, \verb|.| et
  \verb|x10|$^x$, \verb|(|, \verb|)|
  pr\'ec\'ed\'ees de shift (ou en maintenant shift enfoncé selon
  la version de $\chi$CAS) font apparaitre un
  petit menu pour saisir rapidement certaines commandes.
\item Lorsque le curseur est sur la ligne de commande juste apr\`es
  un nom de commande, l'appui sur la touche curseur vers le bas
  permet de voir l'aide sur la commande (si l'aide existe) et
  de saisir un exemple. 
\item  Exemple~: tapez shift-2, puis 3 (integrate), fl\`eche vers
  le bas, puis Ans ou EXE\\
  Modifiez l'expression \`a int\'egrer selon vos besoin puis tapez EXE
\item Lorsqu'il reste peu de mémoire (affichage en haut lorsqu'on
  tape sur la touche var), on peut essayer de restaurer de la place en
  effaçant des variables avec la commande \verb|purge|
  (accessible depuis la touche \verb|var|). On peut aussi
  quitter $\chi$CAS et le relancer pour repartir d'une situation où la mémoire
  n'est pas fragmentée.
%% \item
%% La prise en compte du clavier est un
%% peu différente entre les versions de $\chi$CAS
%% pour Epsilon récents
%% et celle prévue pour Epsilon 15.5. L'appui sur la 
%% touche HOME de la calculatrice fait sortir immédiatement de $\chi$CAS
%% pour revenir au menu principal de la Numworks.
%% Il faut taper sur les touches shift puis EXE pour
%% ouvrir le menu ``fichier'' de $\chi$CAS (au lieu de HOME
%% sur les N0110 non verrouillées).
\item
Notez que pour insérer un caractère non présent sur le clavier, vous 
pouvez taper sur shift puis \verb|*| qui ouvre la table
de caractères ASCII. La touche shift suivie de \verb|+|
renvoie le caractère de tabulation, qui permet d'indenter
dans un programme, ou d'afficher de l'aide.
\end{itemize}

\section{Sauvegarde et \'echange de donn\'ees.}
Remarque~: Si votre session n'est pas trop grande, vous pouvez l'afficher
sous forme de QR code sur la calculatrice. Depuis le shell, 
ouvrir le menu Fichier (touches shift EXE ou touche
HOME selon la version de $\chi$CAS),
choisir Enregistrer session, mettre le cas échéant un nom de session. 
Le QR code
s'affiche, vous pouvez le scanner avec un smartphone et obtenir un
clone de votre session sur votre smartphone. Le QR code s'affiche
également si vous quittez $\chi$CAS depuis le menu principal (shift EXE ou HOME
deux fois de uite). 

Si vous 
disposez du cable adéquat, vous pouvez
connecter le smartphone à une autre Numworks et y recopier la session
(cf. section suivante). Si vous n'avez pas de cable adéquat, vous pouvez
appuyer avec le doigt sur l'icone d'enveloppe en haut et envoyer la
session par email, puis depuis un PC vous pourrez recopier la session
sur une autre calculatrice.

\subsection{Depuis un navigateur webusb (Chromium ou Chrome ...)}
\begin{itemize}
\item
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{Le
  kit de connexion Numworks} utilis\'ee avec un
navigateur compatible webusb, par exemple Chrome ou Chromium ou Edge,
permet d'\'echanger des donn\'ees
avec la calculatrice Numworks~: des scripts Python ou des backups.
On peut aussi installer $\chi$CAS, 
personnaliser le contenu de la m\'emoire flash de la calculatrice.
Pour les N0110 non verrouillées, on peut porter assistance \`a une
calculatrice bloqu\'ee et certifier que le firmware install\'e
sur une calculatrice est conforme \`a la r\'eglementation fran\c{c}aise.
\item
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/xcasfr.html}{La
  version web de Xcas} 
permet d'\'echanger des donn\'ees avec la calculatrice Numworks. 
Cliquez sur le bouton Détecter à gauche du bouton Numworks$\rightarrow$
pour détecter la calculatrice, ensuite
en cliquant sur le bouton Numworks$\rightarrow$, on peut importer
un script de la calculatrice vers la feuille de calcul du navigateur,
le modifier, puis le renvoyer vers la calculatrice avec le bouton
$\rightarrow$Numworks. \\
N.B.~: pour afficher un graphique sur la version web, taper sur une ligne 
vide \verb|,| ou \verb|.| ou \verb|;| selon le type de graphique
%En affichant la section Numworks de la documentation
%(depuis le bouton Doc) on a \'egalement acc\`es \`a la certification
%du firmware Delta+$\chi$CAS.
\end{itemize}

\subsection{Depuis Xcas pour Windows, Linux}
V\'erifiez que 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/install_fr.html}{Xcas}.
 est en version 1.7.0-31 ou ult\'erieure,
si n\'ecessaire installez ou mettez \`a jour.

Sous Linux, v\'erifiez que
\ahref{http://dfu-util.sourceforge.net/}{dfu-util} 
est bien install\'e et que le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/50-numworks-calculator.rules}{\tt
  50-numworks-calculator.rules} a \'et\'e copi\'e dans
\verb|/etc/udev/rules.d|. Si vous avez install\'e un package
  debian, cela peut se faire par la commande\\
\verb|sudo cp /usr/share/giac/doc/50-numworks-calculator.rules
/etc/udev/rules.d|

Les outils pour se connecter avec la Numworks se trouvent dans le menu
\verb|Fich|, sous-menu \verb|Numworks|.
Vous pouvez~:
\begin{itemize}
\item ouvrir un programme de la calculatrice dans la session actuelle
  Xcas ou ouvrir une session $\chi$CAS Numworks
de la calculatrice dans un nouvel onglet de Xcas,
\item envoyer la session actuelle Xcas comme une session $\chi$CAS
sur votre calculatrice,
\item envoyer le programme de l'\'editeur de programme courant
sur votre calculatrice
\item cr\'eer une nouvelle session Xcas contenant tous les programmes
de votre calculatrice
\item effacer les programmes de votre calculatrice et les
remplacer par tous les programmes de la session Xcas actuelle 
\item faire une sauvegarde de votre calculatrice
\item restaurer votre calculatrice \`a partir d'une sauvegarde
\item installer $\chi$CAS sur une calculatrice (il suffit de le
  faire une fois pour toutes)
\item d\'ebloquer une calculatrice N0110. Ceci fonctionnera
sur toute calculatrice N0110 qui n'est pas verrouill\'ee par
une mise \`a jour faite sur le site de Numworks apr\`es septembre
2021. Cela utilise
le bootloader du fabricant du microprocesseur (ST) 
que l'on lance en maintenant la touche 6
de la calculatrice enfonc\'ee en appuyant sur RESET 
\`a l'arri\`ere de la calculatrice en m\^eme temps.
Ce sous-menu envoie un bootloader ``rescue mode'' dans la RAM de la
calculatrice et l'ex\'ecute, on peut ensuite installer Khi+$\chi$CAS (ou toute
autre version d\'eriv\'ee d'Epsilon $\leq 15$).
\item certifier que la version de Khi+$\chi$CAS de la
 calculatrice N0110 non verrouillée d'un \'el\`eve est identique \`a
celle fournie avec Xcas (et n'a donc pas \'et\'e
modifi\'ee et recompil\'ee en y ajoutant des donn\'ees
personnelles).
\end{itemize}
Sur Mac, il est recommand\'e d'utiliser le kit de connectivit\'e web
Numworks de la section pr\'ec\'edente.

\subsection{Gestion de la m\'emoire flash sur la calculatrice}
Depuis la version du 14 octobre 2021,
vous pouvez lancer un mini-gestionnaire de fichiers en flash 
depuis le menu Applications de $\chi$CAS
(touches shift Ans
puis valider puis avant-avant-dernier item). 
Ce gestionnaire permet
\begin{itemize}
\item de lister les fichiers install\'es en flash et d'afficher
des informations (dont la date de cr\'eation)
\item de copier un script depuis la RAM vers la flash (ce qui la
  pr\'eserve d'un effacement par un reset ou un crash de la
calculatrice). Notez qu'un script en flash peut être importé
depuis $\chi$CAS sans être recopié dans le scriptstore RAM de la Numworks.
% La date de cr\'eation de ces fichiers apparait
% alors en unit\'e de temps mesur\'e par l'horloge RTC de la
% calculatrice depuis le dernier reset.
\item de modifier la visibilit\'e d'un fichier ou de le renommer.
Dans ce sous-menu, on valide les changements par OK ou EXE,
on les annule avec la touche Back.
\item d'effacer r\'eellement les fichiers marqu\'es comme
non visibles pour faire de la place (Vider la corbeille). 
\end{itemize}
Attention, si vous faites des modifications, cela \'ecrit
en flash, or on ne peut pas \'ecrire ind\'efiniment sur
le m\^eme secteur en flash (pour
la flash externe, Numworks a assigne une taille de 64K aux secteurs).
Pour augmenter la dur\'ee de vie de la m\'emoire flash,
il est conseill\'e de ne vider la corbeille
que lorsqu'il est vraiment n\'ecessaire de faire de la place. En effet,
si on ne vide pas la corbeille, les nouveaux fichiers ajout\'es en flash
vont progressivement \^etre \'ecrits dans de nouveaux secteurs, 
ce qui r\'epartira
mieux l'usure de la flash. (Un ``vrai'' syst\`eme de fichiers fait
normalement cela automatiquement). Si vous n'avez pas besoin de
beaucoup de place pour stocker des fichiers par rapport à la place
disponible (6*64K à 1M selon la version de $\chi$CAS), 
vous pouvez aussi ajouter un gros fichier inerte de taille
un multiple de 64K vers le d\'ebut de l'archive (\`a partir du fichier
d'indice 10 si vous voulez conserver la certification
sur les N0110 non verrouillées), que vous
changez de temps en temps.

Par ailleurs, lorsque vous lancez le mode examen sur les N0110 
non verrouillées utilisant Khi, 
l'\'etat de la calculatrice est
automatiquement sauvegard\'e dans le dernier secteur 
de la m\'emoire flash (sauf s'il
n'y a aucun script Python).
Plus tard, lorsque vous avez quitt\'e le mode examen (en branchant la
calculatrice), vous pouvez restaurer l'\'etat de la calculatrice
depuis le menu shift EXE (ou HOME), Configuration/mode examen.

\section{Commandes usuelles de calcul formel}

\subsection{D\'evelopper et factoriser}
Depuis le catalogue, s\'electionner le sous-menu \verb|Algebre|
(2) ou le menu rapide shift-1
\begin{itemize}
\item \verb|factor|~: factorisation. Raccourci clavier shift-*
  (pr\'efix\'e) ou \verb|=>*| (infix\'e touche sto puis *),
  par exemple \giacinputmath{x^4-1=>*}.
Utiliser \verb|cfactor| pour factoriser sur $\C$.
\item \verb|partfrac|~: d\'eveloppement d'un polyn\^ome ou
d\'ecomposition en \'el\'ements simples pour une fraction. Raccourci
clavier \verb|=>+| (touche sto puis +), 
par exemple \giacinputmath{ (x+1)^4=>+} 
ou \giacinputmath{1/(x^4-1)=>+}.
\item \verb|simplify|~: essai de simplifier une expression.
Raccourci clavier \verb|=>/| (touche $\rightarrow$ puis /), 
par exemple \giacinputmath{sin(3x)/sin(x)=>/}
Attention, cette commande est gourmande en m\'emoire, et la Numworks
en a peu, le risque de reset existe.
\item \verb|ratnormal|~: d\'evelopper une expression,
\'ecrire une fraction sous forme irr\'eductible.
\end{itemize}

\subsection{Analyse}
Depuis le catalogue (Toolbox), s\'electionner le sous-menu \verb|Analyse|
(4) ou le menu rapide shift-2
\begin{itemize}
\item \verb|diff|~: d\'erivation. On peut aussi utiliser la notation
\verb|'| (alpha-shift-") pour d\'eriver par rapport \`a $x$, ainsi
\giacinputmath{diff(sin(x),x)} et \giacinputmath{sin(x)'} sont \'equivalents.
Pour d\'eriver plusieurs fois, ajouter le nombre de d\'erivations
par exemple \giacinputmath{diff(sin(x^2),x,3)}.
\item \verb|integrate|~: primitive si 1 ou 2 arguments,
par exemple 
\giacinputmath{integrate(sin(x))} ou \giacinputmath{integrate(1/(t^4-1),t)}
pour $\int \frac{1}{t^4-1} \ dt $\\
Calcul d'int\'egrale d\'efinie si 4 arguments, par
exemple \giacinputmath{integrate(sin(x)^4,x,0,pi)}
pour $\int_0^\pi \sin(x)^4 \ dx$. Mettre une des bornes
d'int\'egration sous forme approch\'ee si on souhaite un calcul
approch\'e d'int\'egrale d\'efinie, par exemple
\giacinputmath{integrate(sin(x)^4,x,0.0,pi)}\\
\item \verb|limit|~: limite d'une expression.
Exemple \giacinputmath{limit((cos(x)-1)/x^2,x=0)}
\item \verb|tabvar|~: tableau de variations d'une expression.
Par exemple \giacinputmath{tabvar(x^3-7x+5)}
on peut v\'erifier avec le graphe \giacinput{plot(x^3-7x+5,x,-4,4)}
\item \verb|taylor| et \verb|series|~: d\'eveloppement de Taylor
(ou d\'eveloppement limit\'e ou asymptotique). Par exemple
\giacinput{taylor(sin(x),x=0,5)}
\item \verb|sum|~: somme discr\`ete. Par exemple
\giacinputmath{sum(k^2,k,1,n)} calcule $\sum_{k=1}^n k^2$,
\giacinputmath{sum(k^2,k,1,n)=>*} calcule la somme et l'\'ecrit sous
forme factoris\'ee.\\
\end{itemize}

\subsection{R\'esoudre}
Depuis le catalogue, s\'electionner le sous-menu \verb|Resoudre|
(Toolbox puis touche ln)
\begin{itemize}
\item \verb|solve| permet de r\'esoudre de mani\`ere exacte
une \'equation (se ramenant \`a une \'equation polynomiale).
Il faut pr\'eciser la variable si ce n'est pas \verb|x| par
exemple \giacinputmath{solve(t^2-1=0,t)}.\\
Si la recheche exacte \'echoue, la commande \verb|fsolve|
permet de faire une r\'esolution approch\'ee, soit par
une m\'ethode it\'erative en partant d'une valeur
initiale \giacinputmath{fsolve(cos(x)=x,x=0.0)}, soit par
dichotomie  \giacinputmath{fsolve(cos(x)=x,x=0..1)}.\\
Pour avoir des solutions complexes, utiliser \verb|csolve|.\\
On peut faire des hypoth\`eses sur la variable que l'on cherche,
par exemple \giacinputmath{assume(m>1)} puis \giacinputmath{solve(m^2-4=0,m)}.
\item \verb|solve| permet aussi de r\'esoudre des syst\`emes
polynomiaux simples, on donne en 1er argument la liste des
\'equations, en 2\`eme argument la liste des variables.
Par exemple intersection d'un cercle et d'une droite
\giacinputmath{solve([x^2+y^2+2y=3,x+y=1],[x,y])}
\item \verb|linsolve| permet de r\'esoudre des syst\`emes
lin\'eaires. On lui passe la liste des \'equations et la liste
des variables (par convention une expression \'equivaut
\`a l'\'equation expression=0). Par exemple
\giacinputmath{linsolve([x+2y=3,x-y=7],[x,y])}
\verb|linsolve| renvoie la solution g\'en\'erale du syst\`eme 
(y compris si la solution n'est pas unique).
\item \verb|desolve| permet de r\'esoudre de mani\`ere exacte
certaines \'equations diff\'erentielles, par exemple 
pour r\'esoudre $y'=2y$, on tape \verb|desolve(y'=2y)|.\\
Un exemple o\`u on indique une condition initiale, 
la variable ind\'ependante
et la fonction inconnue~:\\
\verb|desolve([y'=2y,y(0)=1],x,y)|
Utiliser \verb|odesolve|
pour une r\'esolution approch\'ee et \verb|plotode| pour une
repr\'esentation graphique de solution calcul\'ee de mani\`ere
approch\'ee. 
\item \verb|rsolve| permet de r\'esoudre de mani\`ere exacte
certaines relations de r\'ecurrences $u_{n+1}=f(u_n,...)$,
par exemple les suites arithm\'etico-g\'eom\'etriques, par
exemple $u_{n+1}=2u_n+3, u_0=1$
\giacinputmath{rsolve(u(n+1)=2*u(n)+3,u(n),u(0)=1)}
\end{itemize}

\subsection{Arithm\'etique}
Lorsque cela est n\'ecessaire,
on distingue l'arithm\'etique des entiers de celle des polyn\^omes
par l'existence du pr\'efixe \verb|i| (comme \verb|integer|) dans
un nom de commande, par exemple \verb|ifactor| factorise un entier
(pas trop grand) alors que \verb|factor| factorise un polyn\^ome
(et \verb|cfactor| factorise un polyn\^ome sur les complexes).
Certaines commandes fonctionnent \`a la fois pour les entiers et
les polyn\^omes, par exemple \verb|gcd| et \verb|lcm|.

\subsubsection{Entiers}
Depuis le catalogue, s\'electionner le sous-menu \verb|Arithmetic, Crypto|
(Toolbox 5)
\begin{itemize}
\item \verb|iquo(a,b)|, 
\verb|irem(a,b)| quotient et reste de la division euclidienne
de deux entiers.\\
\giacinputmath{iquo(23,13),irem(23,13)}
\item \verb|isprime(n)| teste si $n$ est un nombre premier.
Le test est probabiliste pour de grandes valeurs de $n$.
\giacinputmath{isprime(2^64+1)}
\item \verb|ifactor(n)| factorise un entier pas trop grand
(les algorithmes utilis\'es se limitent \`a la division et Pollard-$\rho$,
il n'y avait pas de place pour le crible quadratique).
Par exemple
\giacinputmath{ifactor(2^64+1)}\\
Raccourci clavier touches $\rightarrow$ puis * (\verb|=>*|)
\item \verb|gcd(a,b)|, \verb|lcm(a,b)| PGCD et PPCM de deux entiers
ou de deux poln\^omes\\
\giacinputmath{gcd(25,15),lcm(25,15)}\\
\giacinputmath{gcd(x^3-1,x^2-1),lcm(x^3-1,x^2-1)}
\item \verb|iegcd(a,b)| renvoie 3 entiers $u,v,d$ tels que
$au+bv=d$ o\`u $d$ est le PGCD de $a$ et $b$, avec $|u|<|b|$ et
$|v|<|a|$.\\
\giacinputmath{u,v,d:=iegcd(23,13); 23u+13v}
\item \verb|ichinrem([a,m],[b,n])| lorsque cela est possible,
renvoie $c$ tel que $c=a \pmod m$ et $c=b \pmod n$ (si $m$ et $n$
sont premiers entre eux, $c$ existe).
\giacinputmath{c,n:=ichinrem([1,23],[2,13]); irem(c,23); irem(c,13)}
\item \verb|powmod(a,n,m)| calcule $a^n \pmod m$ par
l'algorithme de la puissance rapide modulaire.
\giacinputmath{powmod(7,22,23)}
\end{itemize}
Les commandes \verb|asc| et \verb|char| permettent de convertir
une chaine de caract\`eres en liste d'entiers (entre 0 et 255) et
r\'eciproquement, ce qui permet de faire facilement de la cryptographie
avec des messages sous forme de chaines de caract\`eres.

\subsubsection{Polyn\^omes}
Depuis le catalogue, s\'electionner le sous-menu \verb|Polynomes| (8).
La variable est par d\'efaut $x$, sinon il faut la sp\'ecifier en
g\'en\'eral en dernier argument, par exemple \verb|degree(x^2*y)|
ou \verb|degree(x^2*y,x)| renvoient 2, alors que \verb|degree(x^2*y,y)|
renvoie 1
\begin{itemize}
\item \verb|coeff(P,n)| coefficient de $x^n$ dans $P$, \verb|lcoeff(P)|
coefficient dominant de $P$, par exemple
\giacinputmath{P:=x^3+3x; coeff(P,1); lcoeff(P)}
\item \verb|degre(P)| degr\'e du polyn\^ome $P$.
\giacinput{degree(x^3)}
\item \verb|quo(P,Q)|, \verb|rem(P,Q)| quotient et reste de la division
euclidienne de \verb|P| par \verb|Q|
\giacinputmath{P:=x^3+7x-5; Q:=x^2+x; quo(P,Q); rem(P,Q)}
\item \verb|proot(P)|~: racines approch\'ees de $P$ (r\'eelles et complexes)\\
\giacinput{proot(x^5+x+1)}
Repr\'esentation graphique~:\\
\giacinput{point(proot(x^5+x+1))}
\item \verb|interp(X,Y)|~: pour deux listes
de m\^eme taille, polyn\^ome d'interpolation
passant par les points $(X_i,Y_i)$. \\
\giacinputmath{X,Y:=[0,1,2,3],[1,-3,-2,0]; P:=interp(X,Y)=>+}
Repr\'esentation graphique\\
\giacinput{scatterplot(X,Y); plot(P,x,-1,4)}
\item \verb|resultant(P,Q)|~: r\'esultant des polyn\^omes
$P$ et $Q$
\giacinput{P:=x^3+7x-5; Q:=x^2+x; resultant(P,Q)}
\item \verb|hermite(x,n)|~: n-i\`eme polyn\^ome de Hermite,
orthogonal pour la densit\'e $e^{-x^2}dx$ sur $\R$
\item \verb|laguerre(x,n,a)|~: n-i\`eme polyn\^ome de Laguerre,
\item \verb|legendre(x,n)|~: n-i\`eme polyn\^ome de Legendre,
orthogonal pour la densit\'e $dx$ sur $[-1,1]$
\item \verb|tchebyshev1(n)| et \verb|tchebyshev2(n)|
polyn\^omes de Tchebyshev de 1\`ere et 2\`eme esp\`ece
d\'efinis par~:
$$T_n(\cos(x))=\cos(nx), \quad U_n(\cos(x))\sin(x)=\sin((n+1)x)$$
%\item \verb|bernoulli(n,x)| polyn\^ome de Bernoulli
\end{itemize}

\subsubsection{$\mathbb{Z}/n\mathbb{Z}$ et corps finis}
Pour travailler avec des classes modulo $n$, utiliser la notation
\verb|a mod n|, par exemple \verb|sqrt(2 mod 7)|.
Ceci s'applique aussi pour travailler sur des corps finis premiers
$\mathbb{Z}/p\mathbb{Z}$. Pour travailler sur des corps finis
non premiers, il faut d'abord d\'efinir le corps avec \verb|GF|,
puis on utilise un polyn\^ome en le g\'en\'erateur du corps.

\subsection{Alg\`ebre lin\'eaire, vecteurs, matrices}
Xcas ne fait pas de diff\'erence entre vecteur et liste. Par
exemple pour faire le produit scalaire de deux vecteurs, on peut
saisir~:
\begin{giaconload}v:=[1,2]; w:=[3,4]\end{giaconload}
\giacinput{dot(v,w)}

Pour saisir une matrice \'el\'ement par \'el\'ement, taper
sur shift-7 (touche M comme matrice) puis \verb|matrix(|
ou selon le modèle \verb|shift EXE i| ou \verb|HOME i| (editer matrice). 
Vous pouvez ensuite
cr\'eer une nouvelle matrice ou \'editer
une matrice existante parmi la liste de variables propos\'ees. 
Pour de petites matrices, vous pouvez aussi
entrer en ligne de commandes
une liste de listes de m\^eme taille. Par exemple
pour d\'efinir la matrice
$$ A=\left(\begin{array}{cc} 1 & 2 \\ 3 & 4 \end{array}\right)$$
on tape \begin{giaconload}A:=[[1,2],[3,4]]\end{giaconload} 
ou \giacinputmath{[[1,2],[3,4]]=>A}

Il est fortement conseill\'e de stocker les matrices dans des variables
pour \'eviter de les saisir plusieurs fois.

Pour entrer une matrice dont les coefficients sont
donn\'es par une formule,
on peut utiliser la commande \verb|matrix|, par
exemple 
\giacinputmath{matrix(2,2,(j,k)->1/(j+k+1))} 
renvoie
la matrice dont le coefficient ligne $j$ et colonne $k$ vaut
$\frac{1}{j+k+1}$ (attention les indices commencent \`a 0). 

La matrice identit\'e de taille $n$ 
est renvoy\'ee par la commande \verb|idn(n)|,
alors que \verb|ranm(n,m,loi,[parametres])| renvoie
une matrice \`a coefficients al\'eatoires de taille $n,m$.
Par exemple 
\giacinputmath{U:=ranm(4,4,uniformd,0,1)}
\giacinputmath{N:=ranm(4,4,normald,0,1)}

Pour ex\'ecuter une commande sur des matrices, s'il s'agit
d'arithm\'etique de base (\verb|+,-,*| inverse), on utilise
les op\'erations au clavier. Pour les autres commandes.
depuis le catalogue, s\'electionner le sous-menu \verb|Matrices|
(Toolbox sin)
\begin{itemize}
\item \giacinputmath{eigenvals(A)}
\giacinputmath{eigenvects(A)} 
renvoient les valeurs
propres et vecteurs propres d'une matrice carr\'ee $A$. 
\item \giacinputmath{P,D:=jordan(A)} 
calcule la forme normale de Jordan d'une matrice $A$
(\`a coefficients exacts) et renvoie les matrices $P$ et $D$ telles que
$P^{-1}AP=D$, avec $D$ triangulaire sup\'erieure (diagonale si $A$ est
diagonalisable)
\item \giacinputmath{Ak:=matpow(A,k)} calcule la puissance $k$-i\`eme
d'une matrice $A$ avec $k$ une variable formelle.
\item \verb|rref| effectue la r\'eduction sous forme \'echelonn\'ee
d'une matrice $A$ (pivot de Gauss)
\item \verb|lu| calcule la d\'ecomposition $LU$ d'une matrice $A$
et renvoie une permutation de matrice $P$ et deux matrices $L$
triangulaire inf\'erieure et $U$ triangulaire sup\'erieure telles que
$PA=LU$. Le r\'esultat de la commande 
\giacinput{P,L,U:=lu(A)} peut
\^etre pass\'e en argument \`a la commande \giacinput{linsolve(P,L,U,v)}
pour r\'esoudre un syst\`eme $Ax=b$ de matrice $A$ en r\'esolvant
deux syst\`emes triangulaires (calcul en $O(n^2)$ au lieu
de $O(n^3)$).
\item \verb|qr| calcule la d\'ecomposition $QR$ d'une matrice $A$
et renvoie deux matrices $Q$ orthogonale et $R$ triangulaire sup\'erieure
telles que $A=QR$.
\item \verb|svd(A)| calcule la factorisation en valeurs
singuli\`eres d'une matrice $A$, et renvoie 
$U$ orthogonale, $S$ vecteur des valeurs singulières, $Q$
orthogonale tels que \verb|A=U*diag(S)*tran(Q)|. Le rapport
de la plus grande valeur singuli\`ere de $S$ sur la plus petite
donne le nombre de condition de $A$ relativement \`a la norme euclidienne,
plus ce nombre est grand, plus on perd en pr\'ecision en r\'esolvant
un syst\`eme $Ax=b$ lorsque $b$ n'est pas connu exactement.
\end{itemize}


\section{Probabilit\'es et statistiques}

\subsection{Tirages al\'eatoires}
Depuis le catalogue, s\'electionner le sous-menu \verb|Probabilites|
(Toolbox 9) puis s\'electionnez \giacinput{rand()} (r\'eel selon
la loi uniforme dans $[0,1]$) ou 
\giacinput{n:=6:; randint(n)} 
(entier
entre 1 et $n$). De nombreuses autres fonctions al\'eatoires
existent, avec comme pr\'efixe \verb|rand|, suivi par le nom
de la loi, par exemple \verb|randbinomial(n,p)| renvoie
un entier al\'eatoire selon la loi binomiale de param\`etres $n,p$.
Pour cr\'eer un vecteur ou une matrice al\'eatoire, utiliser la commande
\verb|ranv| ou \verb|ranm| (menu \verb|Alglin, Matrice|), 
par exemple pour un vecteur de 10 composantes
selon la loi normale centr\'ee r\'eduite 
\giacinputmath{ranv(10,normald,0,1)}

\subsection{Lois de probabilit\'es}
Depuis le catalogue, s\'electionner le sous-menu \verb|Probabilites| (9).
Les lois propos\'ees dans le catalogue sont la loi binomiale, la loi normale,
la loi exponentielle et la loi uniforme. 
D'autres lois sont disponibles depuis \verb|Tout|~:
\verb|chisquared|, \verb|geometric|, \verb|multinomial|
\verb|studentd|, \verb|fisherd|, \verb|poisson|.

Pour obtenir la distribution cumul\'ee d'une loi, on saisit le nom de la loi
et le suffixe \verb|_cdf| (s\'electionner \verb|cdf| dans le catalogue
sous-menu Probabilit\'es et taper Ans). 
Pour obtenir la distribution cumul\'ee inverse,
on saisit le nom de la loi et le suffixe \verb|_icdf|  
(s\'electionner \verb|cdf| dans le catalogue
sous-menu Probabilit\'es et taper EXE).

Exemple~: calcul de l'intervalle centr\'e $I$
pour la loi normale de moyenne 5000 et d'\'ecart-type 200
tel que la probabilit\'e d'\^etre en-dehors de $I$ soit de 5\%~:
\giacinput{M:=5000; S:=200; normald_icdf(M,S,0.025);normald_icdf(M,S,0.975)}

\subsection{Statistiques descriptives 1-d}
Ces fonctions agissent sur des listes
par exemple \begin{giaconload}l:=[9,11,6,13,17,10]\end{giaconload}
Depuis le catalogue, s\'electionner le sous-menu \verb|Statistiques|
(Toolbox log)
\begin{itemize}
\item \giacinput{mean(l)}~: moyenne arithm\'etique d'une liste
\item \giacinput{stddev(l)}~: \'ecart-type d'une liste\\
Utiliser
\giacinput{stddevp(l)} pour avoir un estimateur non biais\'e
de l'\'ecart-type d'une population dont \verb|l| est un \'echantillon
\item \giacinput{median(l)}, \giacinput{quartile1(l)}, 
\giacinput{quartile3(l)}
renvoient respectivement la m\'ediane, le 1er et 3\`eme quartiles
d'une liste
\end{itemize}
Pour les statistiques 1-d de listes avec effectifs, on remplace
\verb|l| par deux listes de m\^eme longueur, la 1\`ere liste
est la liste des valeurs de la s\'erie statistique, la 2\`eme
liste est la liste des effectifs.
Voir aussi les commandes du menu \verb|shift-3| 
\verb|histogram| et \verb|barplot|.

\subsection{Statistiques descriptives 2-d, r\'egressions.} \label{sec:stat2d}
Voir aussi la section \ref{sec:tableur} expliquant le tableur.

Entrez les deux listes de donn\'ees dans deux variables, par exemple
\verb|X:=[1,2,3,4,5]| et \verb|Y:=[3,5,6,8,11]|, ou dans une variable
matrice ayant 2 colonnes,
depuis le shell avec le menu \verb|shift-6| \verb|8 matrix(|.\\
Depuis le catalogue, s\'electionner le sous-menu \verb|Statistiques|
(touches \verb|Toolbox log|), pour les r\'egressions,
depuis le shell, tapez \verb|shift-6|.
\begin{itemize}
\item \verb|correlation(X,Y)| calcule la corr\'elation entre 
2 listes de m\^eme taille.
\item \verb|covariance(X,Y)| calcule la covariance entre 
2 listes de m\^eme taille.
\item les commandes de suffixe \verb|_regression(X,Y)| calculent
  des ajustements par r\'egression au sens des moindres carr\'es,
  les commandes de suffixe \verb|_regression_plot| tracent
  la courbe repr\'esentative de la r\'egression (Ces commandes affichent
de plus le coefficient $R^2$ qui permet de quantifier la qualit\'e
de l'ajustement (plus $R^2$ est proche de 1, meilleur est
l'ajustement).
  $\chi$CAS a des commandes pour faire des r\'egressions lin\'eaires,
  exponentielles, logarithmiques, puissance, polynomiales et logistique.
\item Par exemple \verb|linear_regression(X,Y)| renvoie
les coefficients $m,p$ de la droite de r\'egression lin\'eaire
$y=mx+p$. \\
\verb|linear_regression_plot(X,Y)|  trace la droite 
d'ajustement des donn\'ees contenues dans les listes
\verb|X,Y| de m\^eme taille.
\item voir aussi les commandes \verb|scatterplot|, \verb|polygonplot|
  et \verb|polygonscatterplot| pour afficher les donn\'ees
  sur un graphique. On peut superposer plusieurs courbes de r\'egression
  sur le m\^eme graphe en les s\'eparant par un \verb|;| en ligne
  de commande.
\end{itemize}
Ainsi pour afficher la droite de r\'egression lin\'eaire correspondant
aux donn\'ees \verb|X=[1,2,3,4,5]| et \verb|Y=[3,5,6,8,11]|,
tapez les deux commandes ci-dessus ou \'editez une matrice ayant 2 colonnes
avec le raccourci \verb|shift-6 8|. Puis \verb|shift-6 EXE|
(ou \verb|Toolbox log| puis
s\'electionnez la commande \verb|linear_regression_plot(|)
compl\'etez la commande par \verb|X,Y)| ou par le nom de variable
de la matrice puis EXE.

Remarque~: si vos donn\'ees sont dans une matrice \verb|m|
ayant 2 lignes au lieu de 2 colonnes, vous pouvez utiliser \verb|m^*|
pour transposer (en fait cela transconjugue, ce qui est identique
pour des donn\'ees r\'eelles).

\section{Courbes et autres repr\'esentations graphiques.}
Pour obtenir une repr\'esentation graphique, on saisit une commande
de trac\'e (ou plusieurs commandes s\'epar\'ees par \verb|;|).
Depuis le catalogue, s\'electionner le sous-menu \verb|Courbes|
(acc\`es rapide par Toolbox 7, ou shift-3 depuis le shell).
\begin{itemize}
\item \verb|plot(f(x),x=a..b)| trace le graphe de $f(x)$ pour $x\in [a,b]$.
On peut sp\'ecifier un pas de discr\'etisation avec \verb|xstep=|,
par exemple \giacinput{plot(x^2,x=-4..4,xstep=1)}
\item \verb|plot(x+y>0 and 2x+y<4 and x+2y<5)|~: repr\'esentation
graphique des solutions de ce syst\`eme d'in\'equations. Les
in\'equations polynomiales du premier et deuxi\`eme degr\'e
(d\'elimit\'es  par des droites et des coniques) b\'en\'eficient
d'un support am\'elior\'e, les bords de la zone solution sont calcul\'es
sous forme d'une ligne polygonale exacte (si tout est de degr\'e 1)
ou approch\'ee. Sinon, une discr\'etisation est calcul\'ee et la
zone repr\'esent\'ee est une suite de petits rectangles, ce qui donne
un aspect pixelis\'e au graphe, surtout sur la Numworks o\`u la
m\'emoire disponible et le temps n\'ecessaire au calcul ne permet pas
un graphe tr\`es pr\'ecis.\\
Si vous voulez aussi tracer les droites sur
cet exemple, tapez la commande \\
\verb|plot(x+y>0 and 2x+y<4 and x+2y<5);line(x+y=0);line(2x+y=4); line(x+2y=5)|
\item \verb|LineTan(f(x),x,x0)| trace la tangente au graphe
  de $f(x)$ en $x=x_0$.
\item \verb|plotarea(f(x),x=a..b,n,methode)|
  trace le graphe de $f(x)$ pour $x\in [a,b]$, et noircit
  une portion du plan qui approche l'aire sous la courbe,
  on peut pr\'eciser une m\'ethode d'int\'egration avec \verb|n|
  subdivisions parmi \verb|rectangle_droit|, \verb|rectangle_gauche|,
  \verb|trapezes|, \verb|simpson| (aller dans Toolbox , Options
  puis taper le d\'ebut du nom de la m\'ethode pour la saisir plus
  rapidement)
\item \verb|plotseq(f(x),x=[u0,a,b])| graphe ``en toile d'araign\'ee''
de la suite r\'ecurrente $u_{n+1}=f(u_n)$ de premier terme $u_0$ donn\'e.
Par exemple si $u_{n+1}=\sqrt{2+u_n}, u_0=6$ avec une repr\'esentation
sur $[0,7]$
\giacinput{plotseq(sqrt(2+x),x=[6,0,7])}
\item \verb|plotparam([x(t),y(t)],t=tm..tM)| courbe en param\'etriques
$(x(t),y(t))$ pour $t\in [t_m,t_M]$.
On peut sp\'ecifier un pas de discr\'etisation avec \verb|tstep=|
par exemple
\giacinput{plotparam([sin(2t),cos(3t)],t,0,2*pi)}
%On peut sp\'ecifier la fen\^etre graphique avec
\item \verb|plotpolar(r(theta),theta=a..b)| courbe
en polaires $r(\theta)$ pour $\theta \in [a,b]$,
par exemple
\giacinput{plotpolar(sin(3*theta),theta,0,2*pi)}
\item \verb|plotlist(l)| pour une liste \verb|l|,
trace la ligne polygonale reliant
les points de coordonn\'ees $(i,l_i)$ (indice $i$ commen\c{c}ant \`a 0).\\
\verb|plotlist([X1,Y1],[X2,Y2],...)| 
trace la ligne polygonale reliant
les points de coordonn\'ees $(X_i,Y_i)$ 
\item \verb|scatterplot(X,Y)|, \verb|polygonscatterplot(X,Y)|
pour 2 listes \verb|X,Y| de m\^eme taille, trace un nuage de points
ou une ligne polygonale reliant
les points de coordonn\'ees $(X_i,Y_i)$ 
\item \verb|histogram(l,class_min,class_size)| trace
l'histogramme des donn\'ees de la liste \verb|l| avec
comme largeur de classe \verb|class_size| en commen\c{c}ant
\`a \verb|class_min|. Par exemple, on peut tester la qualit\'e
du g\'en\'erateur al\'eatoire avec
\giacinput{l:=ranv(500,normald,0,1); histogram(l,-4,0.25); plot(normald(x),x,-4,4)}
\item \verb|plotcontour(f(x,y),[x=xmin..xmax,y=ymin..ymax],[l0,l1,...])|
  trace les courbes de niveaux $f(x,y)=l_0, f(x,y)=l_1, ...$.
\item \verb|plotdensity(f(x,y),[x=xmin..xmax,y=ymin..ymax])|
  repr\'esentation par niveaux de couleurs de la fonction de 2 variables
  \verb|x| et \verb|y| dans le rectangle sp\'ecifi\'e (par d\'efaut
  entre -4 et 4).
\item \verb|plotfield(f(t,y),[t=tmin..tmax,y=ymin..ymax])|
trace le champ des tangentes \`a l'\'equation diff\'erentielle
$y'=f(t,y)$. On peut ajouter en dernier param\`etre
optionnel \verb|,plotode=[t0,y0]|
pour tracer simultan\'ement la solution passant par la condition
initiale $y(t_0)=y_0$. Exemple $y'=\sin(ty)$ sur l'intervalle $[-3,3]$
en temps et $[-2,2]$ en $y$\\
\giacinput{plotfield(sin(t*y),[t=-3..3,y=-3..3],plotode=[0,1])}
On peut aussi utiliser la commande \verb|plotode| en-dehors d'une commande
\verb|plotfield|.
\ite pour tracer simultan\'ement plusieurs graphiques, il suffit de s\'eparer
les commandes de trac\'e par \verb|;|
\end{itemize}
Lorsqu'un graphique comporte des trac\'es de courbes (graphes de
fonction, courbes en param\'etriques ou en polaires), le mode
``trace'' est activ\'e par d\'efaut. Dans ce mode, l'appui sur la
touche curseur vers la droite ou la gauche permet de d\'eplacer
un pointeur sur la courbe active, en affichant les coordonn\'ees
du pointeur (et du param\`etre pour une courbe en param\'etriques)
et d'un vecteur tangent. S'il y a plusieurs arcs de courbe, les
touches de curseur haut et bas permettent de changer l'arc d'\'etude.
L'appui sur shift-2 permet d'afficher les informations sur la courbe
courante, si on confirme par OK ou EXE on acc\`ede \`a un tableau de valeurs.

Le menu Toolbox item 2 \'etude de courbes (raccourci touche x,n,t)
permet d'ajouter un vecteur normal pointant vers le centre de courbure
(raccourci shift-4),
ou/et le cercle osculateur (shift-5) et le rayon de courbure. On peut
aussi \`a partir de ce menu d\'eplacer le pointeur vers une position d\'etermin\'ee, ou
vers un point remarquable: racine, tangente horizontale ou verticale,
point d'inflexion, intersection avec un autre arc de courbe. On peut
enfin calculer une longueur d'arc ou l'aire sous la courbe entre
le pointeur et la marque. 

Lorsque vous faites une \'etude de courbe, les variables
\verb|x0,x1,x2,y0,y1,y2|
sont automatiquement affect\'ees avec l'expression de la position, vitesse
et acc\'el\'eration sur la courbe \'etudi\'ee. Lors de la recherche
d'une racine, tangente horizontale, inflexion, longueur d'arc, aire
sous la courbe, des variables contenant la derni\`ere recherche
sont cr\'ees.

Le menu \verb|Options| (Toolbox ,)
vous permet de sp\'ecifier certaines options graphiques~:
\begin{itemize}
\item pour les couleurs, on utilise 
\verb|display=couleur|, par exemple
\giacinput{plot(sin(x),display=red)}
\item Pour changer l'\'epaisseur des segments (y compris les lignes
polygonales utilis\'ees pour tracer une courbe), utiliser
\verb|display=line_width_2| \`a \verb|display=line_width_8|.
Pour changer \`a la fois la couleur et l'\'epaisseur, additionnez les
attributs, par exemple~:
\verb|display=red+line_width_2|
\item Les cercles ainsi que les rectangles dont les bords sont
parall\`eles aux axes peuvent \^etre remplis avec l'attribut
\verb|display=filled| (qui peut s'additionner \`a d'autres attributs).
\item Pour remplacer la fen\^etre graphique calcul\'ee automatiquement
par des valeurs pr\'ed\'efinies, saisir
\verb|gl_x| ou/et \verb|gl_y| et indiquer l'intervalle
en $x$ ou en $y$ souhait\'e, la commande doit pr\'ec\'der une
commande de trac\'e. Par exemple 
\giacinput{gl_x=-2..2;gl_y=-1..4;plot(exp(x))}
\item
Pour enlever les axes, s\'electionner \verb|axes| 
(\verb|axes=0|). La commande doit pr\'ec\'eder une commande de
trac\'e.
\end{itemize}

Les versions récentes de $\chi$CAS permettent de représenter
en 3d ou 4d des fonctions de 2 variables à valeur réelle ou complexe, par
exemple \verb|plot(x^2-y^2)| pour représenter
la fonction de $\mathbb{R}^2 \rightarrow \mahtbb{R}$
ou \verb|plot((x+i*y)^2-9)| pour représenter
la fonction de $\mathbb{C} \rightarrow \mahtbb{C}$ qui à
$z$ associe $z^2-9$. Dans ce dernier cas, le module est représenté
selon l'axe $Oz$ et l'argument par une couleur de l'arc en ciel, de $-\pi$
en bleu violet à 0 en vert (en passant par jaune et orange) et de 0 à $\pi$
en passant par cyan.

Pour préciser des options en 3d/4d,
il faut utiliser la commande \verb|plotfunc|,
par exemple\\
\verb|plotfunc((x+i*y)^3-1,[x=-2..2,y=-2..2],nstep=500)|\\
pour tracer $z \rightarrow z^3-1$ depuis le carré du plan complexe
centré en l'origine
de coté 4, avec une discrétisation utilisant 500 petits rectangles.

\section{Géométrie analytique 2d/3d.}
Les commandes de géométrie analytique permettent de créer des objets
géométriques et de calculer les caractéristiques
d'objets géométriques, par exemple créer une droite
passant par deux points, trouver les coordonnées de points 
d'intersection, l'équation
cartésienne ou les équations paramétriques d'une droite, 
de plans, cercles, ... 
Elles sont par exemple utiles pour vérifier les calculs
de géométrie dans l'espace en spécialité maths en Terminale.
Ces commandes ne sont pas limitées à de la géométrie ``pure''
mais permettent également de gérer des courbes et d'effectuer
des calculs (par exemple longueur de courbe, courbure, repère de
Frénet...).
Les commandes les plus utilisées se trouvent dans le menu 
Toolbox vers la fin, raccourcis
claviers depuis le menu Toolbox {\tt $x^2$} et \verb|(| pour la
géométrie dans le plan et dans l'espace respectivement.

Ces commandes peuvent s'utiliser directement dans le shell
de $\chi$CAS, depuis l'éditeur de programmes, ou dans l'application
de géométrie interactive décrite à la section \ref{sec:geo}.
L'utilisation dans le shell est particulièrement
bien adaptée à de petites constructions, 
pour lesquelles la visualisation des objets géométriques
n'apporte pas énormément, comme on en trouve actuellement dans les
exercices de géométrie 3d en Terminale spécialité maths (il
s'agit en fait d'exercices d'algèbre linéaire déguisés).
Lorsqu'on veut créer et visualiser des constructions géométriques avec
beaucoup d'objets, il vaut mieux apprendre à
utiliser l'application de géométrie
interactive (section \ref{sec:geo}).

\subsection{Construction d'objets géométriques.}
Un objet géométrique se construit avec une commande, par exemple\\
\giacinput{A:=point(1,2)}\\
 permet de créer le point du plan
de coordonnées (1,2), \verb|A:=point(1,2,3)|
le point 3d de
coordonnées (1,2,3). Un droite se construit avec 2 points en argument,
ou un point et un vecteur directeur, ou avec une équation cartésienne,
ou pour une droite du plan avec un point et une pente.

Les commandes de géométrie du plan acceptent l'affixe complexe
d'un point comme argument équivalent à un point, par exemple\\
\giacinput{D:=droite(1+2i,2-i)}\\
 crée la droite passant par les
points d'affixe $1+2i$ et $2-i$ (donc les points de coordonnées
(1,2) et (2,-1)).

Lorsqu'une commande du shell renvoie un objet géométrique, on en voit
la représentation graphique 2d ou 3d. Cette représentation affiche
uniquement les objets présents dans la commande. Pour voir tous
les objets géométriques créés, il suffit de taper une commande
contenant les noms de variable de tous les objets. Par exemple
tapez successivement (en vous aidant du menu Toolbox {\tt $x^2$}\\
\giacinput{A:=point(1,2)}\\
\giacinput{B:=point(2,-1)}\\
\giacinput{D:=droite(A,B)}\\
\giacinput{A,B,D}\\
Si vous ne voulez pas avoir l'affichage d'un objet géométrique, il suffit
de terminer votre commande par \verb|:;|. Par exemple\\
\giacinput{M:=mediatrice(A,B):;}\\
stocke dans la variable \verb|M| la médiatrice du segment $AB$ 
sans l'afficher.

Exemple hors géométrie ``pure''\\
\giacinput{f(x):=x^2}\\
\giacinput{G:=plot(f(x),x=-3..3)}\\
\giacinput{M=point(1,1)}\\
\giacinput{T:=tangente(G,M)}\\
\giacinput{G,M,T}


\subsection{Propriétés d'objets géométriques}
Il s'agit de commandes qui renvoient des données numériques ou
symboliques caractéristiques d'un objet géométrique, 
par exemple les coordonnées d'un point\\
\giacinput{coordonnees(A)}\\
l'équation cartésienne d'une droite\\
\giacinput{equation(D)}\\
On peut chainer ces commandes, par exemple
pour avoir le rayon du cercle circonscrit aux 3 points $A,B,C$
préalablement définis dans les variables de même nom, on tape\\
\giacinput{C:=point(1,-3):;rayon(circonscrit(A,B,C))}\\
\giacinput{pente(T);f'(1)}

\subsection{Exemples au bac} \label{sec:bac}
\subsubsection{2025 métropole jour 1, exercice 3}
Voici des indications pour vérifier l'exercice 3
du \ahref{https://www.apmep.fr/IMG/pdf/Metro_J1_17_06_2025_DV.pdf}{sujet 2025 de métropole jour 1}.
Construction initiale~:
\begin{verbatim}
A=point(-1,0,5)
B=point(3,2,-1)
O=point(0,0,0)
\end{verbatim}
affirmation 1 : VRAIE \\
\verb|B-A| renvoie les coordonnées du vecteur directeur de $AB$ 
et on compare avec celui de l'équation paramétrique, 
qui passe en $t=0$ par $B$. 
Attention une droite admet plusieurs représentations paramétriques, 
\verb|parameq(droite(A,B))| ne donne pas la même équation 
que celle de l'énoncé.

affirmation 2 : FAUSSE\\
\verb|eq:=equation(plan(O,A,B))| renvoie 
$-10*x+14*y-2*z=0$ 
donc un vecteur normal au plan est (-10,14,-2), qui n'est pas 
colinéaire au vecteur $n$

affirmation 3 : VRAIE\\
on voit que les 2 droites ne sont pas parallèles (vecteurs directeurs non colinéaires)
on teste si elles sont sécantes\\
\verb|solve([15+k=1+4s,8-k=2+4s,-6+2],[k,s])| 
renvoie [[-4,5/2]] donc sécantes, donc coplanaires

affirmation 4 : VRAIE\\
\verb|C=point(2,-1,2)|\\
\verb|distance(plan(x-y+z+1=0),C)| renvoie $2\sqrt{3}$.
on peut aussi le faire de tête en remplaçant les coordonnées de $C$ 
dans l'équation du plan et en divisant par la racine carrée 
de la somme des carrés des coefficients de $x,y,z $
(c'est la norme du vecteur normal, $\sqrt{3}$)\\
\verb|(2-(-1)+2+1)/sqrt(1+1+1)|

\subsubsection{2025, métropole, jour 2, exercice 2}
Ci-dessous des indications pour vérifier l'exercice 2 du \ahref{https://www.apmep.fr/IMG/pdf/Metropole__spe_J2_18_06_2025_DV_2.pdf}{sujet de métropole 2025 jour 2}.

{\bf Partie A}
\begin{enumerate}
\item
\verb|solve([3/2+2t=s,2+t=3/2+s,3-t=3-2s],[t,s])| \\
renvoie [[-1,-1/2]] donc $t=-1$ (et $s=-1/2$), 
les droites sont bien sécantes et\\
\verb|S0=subst([3/2+2t,2+t,3-t],t=-1)|\\
\verb|S=point(S0)|\\
Attention $S0$ n'est pas un point géométrique mais la liste des 
coordonnées de $S$.
\item
\verb|A=point(-1,2,1)|\\
\verb|B=point(1,-1,2)|\\
\verb|C=point(1,1,1)|\\
\verb|n=[1,2,4]|\\
La différence de 2 points est le vecteur les reliant, 
et * entre 2 vecteurs calcule leur produit scalaire
\verb|(B-A)*n| renvoie 0, de même pour \verb|(C-A)*n|
donc $n$ est normal au plan.\\
\verb|subst(x+2y+4z,[x,y,z],coordonnees(A))| 
renvoie 7, c'est la bonne constante pour l'équation du plan.
\item
\verb|subst(x+2y+4z,[x,y,z],S0)| renvoie 35/2 donc $S$ 
n'est pas dans le plan $ABC$.
\item
a/ \verb|H=point(-1,0,2)|, \verb|H-S| renvoie [-1/2,-1,-2] soit $-n/2$ 
et \verb|subst(x+2y+4z,[x,y,z],H)| renvoie 7\\
b/ \verb|distance(H,S)| renvoie \verb|(sqrt(21))/2|, c'est la distance
de S à son projeté, donc la distance minimale entre un point de $ABC$ et $S$.
\end{enumerate}

{\bf Partie B}\\
On paramètre le segment $CS$ avec un réel $k \in [0,1]$\\
\verb|M=C+k*(S-C)|\\
\verb|coordonnees(M)|

Le triangle est rectangle en $M$ si le produit scalaire des vecteurs $AM$
et $BM$ est nul\\
\verb|eq=(M-A)*(M-B)|\\
\verb|sol=solve(eq=0,k)|
renvoie \verb|list[(-6*sqrt(14)+12)/45,(6*sqrt(14)+12)/45]|, 
\verb|evalf(sol)| met en évidence une solution dans l'intervalle [0,1] \\
Ou numériquement\\
\verb|fsolve(eq=0,k)|\\
il y a une solution sur le segment ($k=0.76...$).

Autre méthode, on cherche si le segment $CS$ intersecte la sphère de centre
le milieu de $AB$ passant par $A$ et $B$~:\\
\verb|I=inter(segment(C,S),sphere(milieu(A,B),distance(A,B)/2))|\\
\verb|coordonnees(I)|\\
renvoie \verb|[[-(sqrt(14)-3)/5,1,-(-2*sqrt(14)-9)/5]]|


\subsubsection{Indications pour les autres sujets de Terminale 2025 1ère sessios}
Vous pouvez trouver d'autres exemples dans les indications
de correction des sujets de Terminale spécialité maths de 1ère session
du bac 2025 pour Casio Graph 90
\ahref{https://xcas.univ-grenoble-alpes.fr/forum/viewtopic.php?f=22&t=2993}{sur le forum de Xcas}. Les commandes sont identiques, les raccourcis claviers
principaux de la Casio se traduisent de la manière suivante
sur la Numworks~:
\begin{itemize}
\item F1, F2, F3 (Casio 90+) par shift 1, shift 2, shift 3 (Numworks)
\item F4 (Casio) par Toolbox (Numworks)
\item F6 (Casio) par shift EXE (Numworks)
\item EXIT (Casio) par Back (Numworks)
\item => est la touche ``sto'' (affectation post-fixée) représentée
sur le clavier de la Numworks par $\rightarrow$ en jaune (touche
shiftée de $x^y$)
\end{itemize}

\section{Application de g\'eom\'etrie interactive 2d/3d.} \label{sec:geo}
L'application de géométrie
permet de construire des figures dans le plan ou dans l'espace,
et de faire bouger un point et tout ce qui en d\'epend pour illustrer
certaines propriétés (géométrie
dynamique). On peut faire des constructions de géométrie euclidienne
pure, mais aussi avec des graphes de fonction, des coniques, etc.
L'application possède deux ``vues'': la vue graphique et la vue
symbolique qui contient les commandes Xcas permettant de créer la figure
(la philosophie de cette application est proche de celle du logiciel
Geogebra, avec les commandes de Xcas).

\subsection{Modes, vue graphique et symbolique.}
Taper shift-Ans  pour afficher la liste des
applications additionnelles, puis OK puis sélectionnez soit une nouvelle
figure 2d ou 3d soit une figure existante. Vous pouvez aussi ouvrir
l'application de géométrie depuis un graphe (par exemple après avoir
tapé \verb|plot(sin(x))|) en tapant shift EXE ou Home 
selon le modèle puis Sauvegarder figure.

Au lancement on est dans la vue graphique en mode repère, les touches de curseur
permettent de changer de point de vue. Pour changer le mode, utiliser
la touche Toolbox, pour passer en vue symbolique et vice-versa taper OK.
Par exemple tapez Toolbox 3 pour passer en mode point
qui permet de construire des points en déplaçant
le pointeur et en tapant OK ou tapez Toolbox 5 pour passer
en mode triangle qui permet de construire
un triangle à partir de ses 3 sommets, on déplace le pointeur et on tape OK
trois fois. Pour déplacer le pointeur, utiliser les touches de déplacement,
pour se déplacer plus rapidement, faire shift touche de curseur. Si on
est proche d'un point existant, son nom apparait en bas. Pour
déplacer le pointeur vers un point existant, vous pouvez aussi
taper le nom du point (par exemple touche alpha A).

Le mode pointeur permet de sélectionner un point et de le
déplacer pour observer comment la construction varie, ce qui permet
de mettre en évidence des propriétés de la figure, par exemple concurrence
de 3 droites.

Si vous tapez sur la touche Back depuis la vue graphique
de l'application, vous revenez au mode repère ou si vous y étiez
vous passez en vue symbolique. Vous pouvez ajouter
des objets à la construction depuis cette vue, en mettant une commande
par ligne. Tapez EXE pour passer à la ligne. Tapez OK
pour revenir à la vue graphique. Dans la vue symbolique, vous
pouvez sauvegarder la construction géométrique au format texte
(avec une extension \verb|.py|, même s'il ne s'agit pas
d'un script Python).
Tapez Back pour quitter l'application de géométrie.

Lorsque vous quittez l'application de géométrie,
la figure est automatiquement sauvegardée
dans une variable Xcas qui a le même nom que celui du nom de fichier
affiché dans la vue symbolique. Vous pouvez purger la variable Xcas
si vous voulez effacer la figure de la session.

\subsection{Exemples}
\subsubsection{Exemple 2d~: cercle circonscrit.}
Depuis le shell, taper shift-Ans sélectionner nouvelle figure 2d et valider OK.
Puis Toolbox 5 Triangle, OK pour créer le premier sommet du triangle
puis déplacer le pointeur avec les touches de déplacement, OK pour créer
le 2ème sommet du triangle, déplacer le pointeur à nouveau et OK
pour créer le triangle.

Version longue en construisant le centre~:
Taper Toolbox 7, sélectionner 8 Mediatrice, déplacer
le pointeur de sorte que seul un segment du triangle
soit sélectionné (affichage
en bas à droite \verb|perpen_bisector D5,D|),
taper OK pour créer la médiatrice du segment, déplacer le curseur
sur une autre arête du triangle et OK pour créer la 2ème médiatrice,
optionnellement sur le 3ème segment pour avoir les 3 médiatrices.
Puis Toolbox 6 et 4 Intersection unique. Déplacer le curseur vers
une des médiatrices, taper OK puis vers une autre médiatrice, taper OK,
ceci crée le centre du cercle circonscrit. Pour tracer le cercle,
taper Toolbox 4, déplacer le curseur au centre du cercle (vous pouvez
utiliser les touches de déplacement ou juste taper
alpha H ou la bonne lettre si le centre du cercle s'appelle autrement),
puis OK puis sur un des sommets et OK.

Version courte avec la commande \verb|circonscrit|~:
taper Toolbox 9 puis circonscrit puis sélectionner chaque
sommet avec OK (alpha A OK alpha B OK alpha C OK, remplacez A, B, C
par les lettres du sommet du triangle).

Version en vue symbolique~:
taper Back puis en fin de script sur une ligne vide (taper EXE s'il
faut en créer une), taper\\
\verb|c:=circonscrit(A,B,C)| OK

\subsubsection{Exemple 3d: bac septembre 2019~}
On considère un cube $ABCDEFGH$ et on vérifie que le segment $DE$ est 
perpendiculaire au plan $ABG$\\
Taper shift Ans pour lancer l'application de géométrie puis nouvelle figure 3d.
\begin{itemize}
\item Taper Puis Back ou OK pour passer en vue symbolique.
Puis alpha c shift =
puis Toolbox flèche haut deux fois pour sélectionner 3D puis OK puis 5 pour cube
puis Toolbox (aide), qui explique que
les 2 premiers arguments de cube sont les sommets d'une ar\^ete,
le troisième est un point d'un plan d'une face. Le premier
exemple nous convient ici exactement, on tape Ans et on obtient
\verb|c=cube([0,0,0],[1,0,0],[0,1,0])|
On tape EXE pour voir le cube puis + plusieurs fois pour zoomer et EXE
pour revenir à la vue symbolique.
\item
Vous pouvez sauvegarder à tout moment la construction au format
texte depuis
le menu (touche shift-EXE ou Home selon le modèle).
\item
On passe à la ligne en tapant EXE. Puis on définit les sommets
du cube en tapant \verb|A,B,C,D,E,F,G,H:=|
(taper alpha shift A , alpha shift B etc.),
puis Toolbox et flèche vers le haut 3 fois
pour sélectionner Géometrie puis flèche vers le haut 4 fois pour sélectionner
\verb|sommets| OK et mettre c en argument \verb|sommets(c)|.
Taper OK pour visualiser puis OK à nouveau pour revenir en vue
symbolique.
\item
Passer à la ligne avec EXE puis créer le plan ABG
en tapant alpha shift P = puis shift-2 pour
ouvrir le menu rapide lines et 8 pour saisir plane. La commande plan
prend en arguments 3 points pour définir le plan (on peut aussi donner
une équation cartésienne), ici A,B,G, \verb|P=plan(A,B,G,|
on va lui ajouter une couleur avec le menu rapide shift 4 disp
\verb|display=filled+green|, vérifier en visualisant avec OK OK.
\item
On passe à la ligne (EXE) et on crée le segment DE
alpha S = shift 2 sélectionner la commande segment avec OK
puis D,E et shift 4 pour lui donner une couleur
\verb|S=segment(D,E,color=cyan)|
(on pouvait aussi créer le segment depuis la vue graphique en mode Lignes
mais déplacer le pointeur est un peu lent).
\end{itemize}
La construction est donc la suivante:
\begin{verbatim}
c=cube([0,0,0],[1,0,0],[0,1,0])
A,B,C,D,E,F,G,H=sommets(c)
P=plan(A,B,G,display=filled+green)
S=segment(D,E,display=cyan)
\end{verbatim}
Vous pouvez taper OK pour la visualiser et utiliser les flèches de
déplacement pour changer de point de vue. Taper OK ou Back pour revenir
en vue symbolique. Pour quitter l'application taper Back. Taper OK pour
sauvegarder la figure si nécessaire.

Vous pouvez depuis le shell de $\chi$CAS accéder à de nombreuses informations
de géométrie analytique, par exemple \verb|equation(P)| (menu
Toolbox Géométrie) vous donnera
l'équation cartésienne du plan $P$ ou \verb|is_orthogonal(P,S)|
(à saisir depuis le catalogue complet Toolbox OK)
vous confirmera que le plan $P$ est orthogonal au segment $S$.

%% Pour le moment, aucune application de g\'eom\'etrie interactive n'a \'et\'e
%% port\'ee, l'utilisation de commandes de g\'eom\'etrie analytique
%% de Xcas est donc
%% possible en ligne de commandes, avec des noms de commande en anglais
%% pour le moment, par exemple \verb|point|, \verb|segment|,
%% \verb|circle|, \verb|circumcircle|, \verb|incircle|
%% \verb|line|, \verb|triangle|, \verb|polygon|,
%% \verb|parallel|, \verb|perpendicular|, \verb|bisector|,
%% \verb|perpen_bisector|, \verb|center|, \verb|radius|,
%% \verb|distance|, ...

\section{Unit\'es et constantes physiques.}
Le menu Toolbox permet d'ouvrir
un sous-menu constantes physiques (raccourci \verb|Toolbox pi|)
et unit\'es physiques (raccourci \verb|Toolbox sqrt|) avec
\begin{itemize}
  \item des commandes de gestion d'unit\'e\\
    \verb|mksa| pour convertir vers les unit\'es fondementales du syst\`eme
    international\\
    \verb|usimplify| pour simplifier en utilisant une seule
    unit\'e lorsque c'est possible, ou un produit de deux.\\
    \verb|ufactor| pour forcer l'\'ecriture d'une unit\'e en fonction
    d'une autre\\
    \verb|=>| (raccourci touche sto) pour convertir entre deux unit\'es
    compatibles
  \item une liste non exhaustive d'unit\'es physiques
  \item une liste de constantes physiques fondementales.
\end{itemize}
Exemples de commandes~:\\
\verb|60_(km/h) => _(m/s)|\\
\verb|mksa(_hbar_)|\\
\verb|usimplify(1_W*1_s)|\\
\verb|ufactor(1_W,1_J)|

\section{\'Editeur d'expressions}
Lorsqu'un calcul renvoie une expression, elle est affich\'ee en plein 
\'ecran dans
l'\'editeur d'expression 2d. Depuis l'historique des calculs, si le niveau
s\'electionn\'e est une expression, l'appui sur shift-5 (2d) affiche
l'expression dans l'\'editeur 2d. En ligne de commande, l'appui
sur shift-5 ouvre aussi l'\'editeur 2d, soit avec 0 si la ligne
de commande \'etait vide, ou avec le contenu de la ligne de commande si
celle-ci est syntaxiquement correcte.

Lorsque l'\'editeur 2d est ouvert, l'expression est affich\'ee en
plein \'ecran et une
partie de l'expression est s\'electionn\'ee. On peut alors agir sur
la s\'election en ex\'ecutant des commandes saisies via les menus
ou le clavier, on peut aussi \'editer la s\'election (en mode de saisie
1d). Ceci permet de retravailler des sous-expressions
ou d'\'editer une expression en \'ecriture naturelle.

Vous pouvez annuler la derni\`ere modification effectu\'ee en
tapant sur shift-3 (undo).

Taper OK pour quitter l'\'editeur 2d et copier l'expression en ligne de
commande, taper Back pour quitter sans recopier l'expression.

Exemple 1~: nous allons saisir 
$$ \lim_{x \rightarrow 0} \frac{\sin(x)}{x}$$
Depuis une ligne de commande vide, taper shift-5 (2d), vous devez voir 0 
s\'electionn\'e. Tapez sur la touche x et EXE, maintenant c'est x qui
est en surbrillance. Tapez sur la touche sin, c'est $\sin(x)$ qui
est en surbrillance. Tapez sur la touche de division (au-dessus de -), 
vous devez voir $\frac{\sin(x)}{0}$ avec 0 en surbrillance, tapez
x puis EXE, vous devez voir $\frac{\sin(x)}{x}$ avec
x au d\'enominateur en surbrillance. Tapez sur le curseur
fl\`eche vers le haut pour mettre $\frac{\sin(x)}{x}$ en surbrillance,
puis shift-2 4 (pour limit). L'expression est correcte, vous pouvez taper OK
pour la recopier en ligne de commande et OK \`a nouveau pour
ex\'ecuter le calcul.
Si on avait voulu
une limite en $+\infty$, il aurait fallu d\'eplacer la s\'election
avec curseur vers la droite, puis faire shift-1 7 (oo) OK.

Exemple 2~: nous allons saisir
$$ \int_0^{+\infty} \frac{1}{x^4+1} \ dx $$
Depuis une ligne de commande vide, taper shift-5 (2d), puis shift-2 3
(integrate),
vous devez voir
$$ \int_0^1 0 \ dx$$
avec $x$ s\'electionn\'e. Il faut donc changer le 1 de la borne sup\'erieure
et le 0 \`a int\'egrer. Pour modifier le 0, curseur vers la gauche pour
le s\'electionner puis \verb|1/(x^4+1)| EXE, puis curseur vers
la gauche shift-1 7 EXE. Taper sur OK pour recopier vers la ligne
de commande puis OK pour effectuer le calcul, le r\'esultat s'affiche
dans l'\'editeur 2d, OK quitte l'\'editeur avec dans l'historique
l'int\'egrale et sa valeur (en syntaxe alg\'ebrique 1d).

Exemple 3~: nous allons calculer et simplifier 
$$ \int \frac{1}{x^4+1} \ dx $$
Depuis une ligne de commande vide, taper shift-5 (2d), puis shift-2 3
(integrate),
vous devez voir
$$ \int_0^1 0 \ dx$$
D\'eplacez le curseur sur le 0 de la borne inf\'erieure de l'int\'egrale
et tapez sur la touche DEL, vous devez voir
$$ \int 0 \ dx$$
avec le tout s\'electionn\'e. Utilisez le curseur vers le bas
pour s\'electionner 0 et tapez \verb|1/(x^4+1)| EXE puis OK pour
recopier en ligne de commande puis OK pour ex\'ecuter le calcul,
le r\'esultat s'affiche maintenant dans l'\'editeur 2d.\\
On peut alors s\'electionner avec les touches du curseur par exemple
l'argument d'un des arctangentes et ex\'ecuter shift-1 EXE (simplify) 
pour effectuer une simplification partielle du r\'esultat, puis
recommencer avec l'autre arctangente.\\
On peut simplifier encore plus, en rassemblant les logarithmes. Pour
cela il faut d'abord \'echanger deux des arguments de la somme. 
S\'electionnez un des logarithmes avec des d\'eplacements du curseur,
puis tapez shift-curseur droit ou gauche,
cela \'echange l'argument s\'electionn\'e avec son fr\`ere de droite ou
de gauche. Tapez ensuite 
 alpha curseur vers la droite ou vers la gauche, ceci augmente la
s\'election en ajoutant le fr\`ere de droite ou de gauche.
Une fois les deux logarithmes s\'electionn\'es, menu shift-1 2 EXE
(factor), puis
descendez la s\'election sur la somme ou diff\'erence de logarithmes,
allez dans le menu Toolbox puis EXE (Tout), tapez les lettres l, n, c
ce qui d\'eplace \`a la premi\`ere commande commen\c{c}ant par \verb|lnc|,
s\'electionnez \verb|lncollect|, validez et tapez enfin sur EXE (eval).

\section{Sessions de calculs}

\subsection{Edition de l'historique.}
En utilisant la touche curseur vers le haut/bas, on se d\'eplace dans
l'historique des calculs, le niveau courant est en surbrillance. 

Pour modifier l'ordre des niveaux dans l'historique des calculs,
tapez alpha-curseur vers le haut ou vers le bas.
Pour effacer un niveau, appuyez sur la touche DEL (le niveau
est recopi\'e dans le presse-papiers).

Pour
modifier un niveau existant, on tape sur shift-5 ou sur shift-4. Dans le
premier cas, c'est l'\'editeur 2d qui est appel\'e si le niveau
est une expression, dans le
deuxi\`eme cas, c'est l'\'editeur texte qui est appel\'e.
Taper Back pour annuler les modifications ou EXE pour valider.
Si les modifications sont valid\'ees, les lignes de commande situ\'ees
en-dessous de la ligne modifi\'ee seront automatiquement calcul\'ees,
tenant compte des modifications, par exemple si vous modifiez un niveau
comme \verb|A:=1|, les lignes situ\'ees en-dessous d\'ependant de \verb|A|
seront actualis\'ees.

Ce processus peut \^etre automatis\'e en utilisant un curseur,
que l'on peut cr\'eer avec un assistant, depuis le menu principal
(shift EXE ou HOME), Parameter. 
Une fois cr\'e\'e, vous pouvez modifier un curseur
en tapant sur les touches + ou - lorsque le niveau contenant
la commande \verb|assume| ou \verb|parameter| est s\'electionn\'e
(tapez * ou / pour une modification plus rapide).

\subsection{Variables}
En appuyant sur la touche \verb|var| vous affichez la liste
des variables qui ont une valeur, ainsi que des commandes de gestion
de variables. D\'eplacez le curseur vers une variable puis EXE pour
la recopier en ligne de commande, DEL copie en ligne de commande
la commande d'effacement de la variable (confirmez ensuite avec EXE).
La commande \verb|restart| permet d'effacer toutes les variables.
La commande \verb|assume| permet de faire une hypoth\`ese sur
une variable, par exemple \verb|assume(x>5)| (\verb|>| se trouve
dans le menu shift-PRGM).


%% \subsection{Sauvegarde et \'echange de sessions avec Xcas.}
%% Depuis l'historique des calculs, avec le menu HOME, vous pouvez sauvegarder
%% une session de travail sur la m\'emoire de stockage de la
%% calculatrice. Les fichiers ont comme extension \verb|xw|.
%% Mais il n'existe actuellement pas de moyen d'\'echanger ces fichiers
%% avec un ordinateur et la m\'emoire de stockage est tr\`es restreinte.
%% Vous pouvez alors sauvegarder ces fichiers sur votre ordinateur en
%% connectant la calculatrice comme clef USB (choix F1), depuis
%% l'explorateur de fichiers de votre ordinateur.

%% Ces fichiers sont compatibles avec Xcas et Xcas pour Firefox. Vous
%% pouvez ouvrir une session depuis le menu Fich, Ouvrir de Xcas
%% ou depuis le bouton Charger/Parcourir de la page de 
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/xcasfr.html}{Xcas pour Firefox}.
%% Vous pouvez sauvegarder des sessions Xcas et Xcas pour Firefox au format
%% \verb|xw| dans le menu Fich, Exporter comme $\chi$CAS de Xcas, 
%% ou le bouton Export de Xcas pour Firefox.



\section{Programmation}
L'environnement de programmation de $\chi$cas est assez complet:
un \'editeur, l'interpr\'eteur de Xcas avec toutes ses commandes
(compatibilit\'e partielle avec les modules Python
math, cmath, random, turtle, numpy, scipy, giacpy, matplotlib
et un sur-ensemble du module kandinsky), avec  un outil de mise au point
permttant l'ex\'ecution en pas \`a pas.

Vous pouvez programmer en utilisant
les structures de commande en fran\c{c}ais de Xcas
ou en utilisant la compatibilit\'e de
syntaxe Python. Les programmes tr\`es courts (en une ligne)
peuvent \^etre saisis directement en ligne de commande. Les
programmes plus longs ou que l'on souhaite sauvegarder
seront saisis dans l'\'editeur de programmes sur
la calculatrice, ou bien transf\'er\'es depuis un PC ou
une autre calculatrice.

Plusieurs programmes sont install\'es apr\`es un reset de la calculatrice
(des polygones avec la tortue, la fractale de Mandelbrot, le calcul
des racines d'un polyn\^ome de degr\'e 2).
Vous pouvez les visualiser depuis le shell en tapant shift-EXE ou Home 
selon le modèle de calculatrice,
puis Ouvrir script, les interpr\'eter avec la touche OK et les
ex\'ecuter depuis le shell (Back puis var pour s\'electionner la fonction).

%% Attention
%% sur les Numworks N0115/N0120/N0110 verrouillées (section \ref{sec:n120}), 
%% la touche HOME renvoie directement au menu principal de la Numworks,
%% pour simuler l'action de HOME des N0110 non verrouillées, il faut
%% taper les touches shift puis EXE.

\subsection{Prise en main (programmation)}
{\bf Un premier exemple en ligne de commande~}:\\
une fonction d\'efinie par une expression alg\'ebrique. On
saisit \verb|nom_fonction(parametres):=expression|
Par exemple, pour d\'efinir le p\'erim\`etre d'un cercle de
rayon $r$, on peut taper
\giacinput{peri(r):=2*pi*r}
puis on peut calculer \giacinput{peri(1)}.

{\bf Autre exemple, pour calculer l'intervalle de confiance de seconde}
connaissant une fr\'equence $p$ et un effectif $n$, on tape\\
\giacinput{F(P,N):=[P-1/sqrt(N),P+1/sqrt(N)]}\\
puis on teste \giacinput{F(0.4,30)}

{\bf Autre exemple~: avec la tortue de Xcas}\\
La tortue de Xcas est un petit robot qui se d\'eplace selon des 
ordres qui lui sont donn\'es en laissant une trace de son passage.
Les commandes de la tortue sont accessibles depuis le dernier item
du menu Toolbox, par le raccourci Toolbox $x^2$.
Saisir la commande {\tt avance} dans ce menu puis valider, vous
devez voir la tortue (symbolis\'ee par un triangle) avancer de 10 pixels.
Taper Back pour revenir en ligne de commande.
Saisir la commande \verb|tourne_gauche| et valider, la tortue a tourn\'e
de 90 degr\'es. R\'ep\'eter
3 fois ces deux commandes pour afficher un carr\'e.\\
Pour effacer le dessin et ramener la tortue \`a l'origine,
saisir la commande {\tt efface}.
Pour faire des dessins tortue, il est conseill\'e d'utiliser l'\'editeur
de programmes (cf. ci-dessous).

{\bf Autre exemple~: une boucle ``oneliner'' en syntaxe Xcas.}\\
Ouvrez le menu Programmes (Toolbox cos), puis s\'electionnez l'exemple
de \verb|pour| (curseur sur pour puis Ans)\\
\giacinput{pour j de 1 jusque 10 faire print(j,j^2); fpour;}
tapez sur EXE, vous devez voir les carr\'es des entiers de 1 \`a 10.

{\bf Exercice~:} faire faire un carr\'e \`a la tortue en utilisant
une boucle.

{\bf Utilisation de l'\'editeur}\\
Modifions cet exemple pour faire afficher les carr\'es de 1 \`a $n$
en utilisant la syntaxe compatible Python et
l'\'editeur de programmes.
Tapez sur Back pour passer du shell \`a l'\'editeur de programmes.
Si on vous demande programme ou Tortue faites OK.
Ceci ouvre l'\'editeur avec une maquette de fonction
\verb|def f(x):|
V\'erifiez que la syntaxe Python
est activ\'ee (menu principal shift EXE ou HOME), sinon activez-la (8).
Remplacez \verb|x| par \verb|n|, puis 
d\'eplacez le curseur en fin de ligne et passez \`a la
ligne (EXE).
Tapez Shift-2 puis EXE (\verb|for|), placez
un \verb|j| entre \verb|for | et \verb|in range(|
puis un \verb|n| entre les parenth\`eses de \verb|range()|.
\`A la ligne suivante, tapez shift-3 7 (\verb|print|)
et validez (EXE), puis tapez \verb|j,j^2)|. Vous devriez avoir le 
programme suivant~:
\begin{giacprog}
def f(n):
  for j in range(1,n+1):
    print(j,j^2)
  return x
\end{giacprog}
Remplacez \verb|x| par \verb|n| dans \verb|return| (ou effacez la ligne).
N.B.: pour la puissance, on peut utiliser \verb|^| ou \verb|**|
dans $\chi$CAS
(il faut utiliser \verb|**| en Python).

Maintenant, tapez OK.
Si tout va bien, vous devez voir \verb|Success| dans la ligne d'\'etat.
Sinon, le num\'ero de ligne de la premi\`ere erreur est indiqu\'e ainsi que
le mot qui a provoqu\'e l'erreur. Le curseur est positionn\'e sur la ligne
o\`u l'erreur a \'et\'e d\'etect\'ee (il peut arriver que l'erreur soit 
situ\'ee avant mais d\'etect\'ee un peu plus loin seulement). Si vous
utilisez la syntaxe en Python, notez que les structures de programmation
sont traduites en langage Xcas, les erreurs affich\'ees le sont par
rapport \`a cette traduction (donc des mots-clefs de fin de structure
comme \verb|end| peuvent avoir \'et\'e ajout\'ees).

Si le programme est syntaxiquement correct, vous pouvez le sauvegarder
depuis le menu principal (shift EXE ou HOME). Pour l'ex\'ecuter, revenez \`a la
ligne de commande en tapant la touche Back, tapez par
exemple \verb|f(10)|, vous devriez voir s'afficher
les carr\'es de 1 \`a 10.


{\bf 3i\`eme exemple~: Calcul de l'intervalle de confiance de terminale S}\\
En syntaxe Xcas.
On peut le saisir en ligne de commande
\giacinput{F(P,N):=[P-1.96*sqrt(P*(1-P)/N),P+1.96*sqrt(P*(1-P)/N)]}
On peut \'eviter les calculs redondants en utilisant une variable
locale (utiliser Toolbox Programmes
pour saisir fonction, local, return et ffonction)\\
\begin{giacprog}
fonction F(P,N) 
  local D; 
  D:=1.96*sqrt(P*(1-P)/N); 
  return [P-D,P+D]; 
ffonction;
\end{giacprog}

{\bf Exercice~} Cr\'eez un fichier \verb|carre.py| contenant
un script pour afficher un carr\'e avec la tortue.
Cr\'eez un fichier \verb|carren.py| 
pour afficher un carr\'e de $n$ pixels, en utilisant
une fonction d'argument $n$ et l'instruction \verb|repete|.

{\bf Solution~}
Depuis l'\'editeur de script, faire shift EXE ou HOME  puis 5 (Effacer).
Puis shift-4 \verb|efface|.
Ajouter 4 fois \verb|avance; tourne_gauche;|.
Appuyer sur OK pour tester. Sauvegardez (shift EXE ou HOME puis 
3 Sauvegarder comme).

Effacer \`a nouveau (shift EXE ou HOME 5 effacer)
Puis shift-4 \verb|efface|.
Ajouter avant la ligne \verb|efface|
\begin{verbatim}
def f(n):
  for j in range(4):
    avance(n)
    tourne_gauche
\end{verbatim}
puis apr\`es la ligne \verb|efface;| tapez par exemple \verb|f(40)|
puis OK. Ensuite faire shift EXE ou HOME 3 (Sauvegardez comme).

{\bf Un exemple de fonction non alg\'ebrique~: le calcul du PGCD de 2 entiers.}\\
Utiliser EXE pour passer \`a la ligne. 
En syntaxe Xcas 
\begin{giacprog}
fonction pgcd(a,b)
  tantque b!=0 faire
    a,b:=b,irem(a,b);
  ftantque;
  return a;
ffonction
\end{giacprog}
Le m\^eme en syntaxe Python 
\begin{giacprog}
def pgcd(a,b):
  while b!=0:
    a,b=b,a % b
  return a
\end{giacprog}
On v\'erifie \giacinput{pgcd(12345,3425)}

{\bf Mise au point}\\
La commande \verb|debug| permet 
d'ex\'ecuter une fonction en mode pas-\`a-pas, i.e.
visualiser l'\'evolution des variables instruction par instruction,
par exemple\\
\verb|debug(pgcd(12345,3425))|

\subsection{Quelques exemples}
Le r\'epertoire \verb|prog| de l'archive 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/casio/khicasio.zip}{khicasio.zip}
contient quelques exemples de TP pour classes de seconde de l'IREM
de Grenoble~:
\begin{itemize}
\item utilisation de la tortue pour introduire la programmation textuelle
et la notion de fonction (PDF+corrections fichiers py)
\item longueur approch\'ee d'un arc de courbe (PDF+correction fichier py)
\item tableau de valeurs, recherche de minimum (enonce et morceaux
de programmes, fichier tabval.py)
\end{itemize}
ainsi que quelques autres programmes (avec fr\'equemment
une repr\'esentation graphique)~:
\begin{itemize}
\item fr\'equence dans un \'echantillon, intervalle de fluctuations (freq.py)
\item le paradoxe du duc de Toscane (toscane.py)
\item r\'esolution d'\'equation du second degr\'e (deg2.py)
\item dichotomie (dicho.py)
\item m\'ethode des rectangles (integr.py),
\item fractale de Mandelbrot (mandel.py)
\item un benchmark utilis\'e par tiplanet pour mesurer la vitesse
de l'interpr\'eteur (qcc.py)
\end{itemize}

\subsection{Commandes utilisables}
Contrairement aux adaptations de MicroPython propos\'ees par
les constructeurs (dont
celui de la Numworks N0110), la programmation en (simili-)Python 
dans $\chi$CAS n'est pas une application ind\'ependante. 
Vous pouvez donc utiliser tous les types
de Xcas (par exemple les rationnels) et appliquer toutes
les commandes de Xcas dans vos programmes. Ceci correspond
plus ou moins \`a un environnement Python avec les modules
\verb|math|, \verb|cmath|, \verb|random| (plus complet
que le module \verb|urandom| fourni par les constructeurs),
\verb|scipy|, \verb|numpy|, un petit module de graphiques
pixelis\'e 
(\verb|set_pixel(x,y,c)|, \verb|set_pixel()|
pour synchroniser l'affichage, \verb|clear()|,
\verb|draw_line(x1,y1,x2,y2,c)|, 
\verb|draw_polygon([[x1,y1],[x2,y2],...],c)|,
\verb|draw_rectangle(x,y,w,h,c)|, \verb|draw_circle(x,y,r,c)|,
la couleur+epaisseur+remplissage \verb|c| est un param\`etre optionnel,
\verb|draw_arc(x,y,rx,ry,t1,t2,c)| permet de tracer un arc
d'ellipse).
et pour remplacer \verb|matplotlib| on peut utiliser
les commande graphiques dans un rep\`ere de $\chi$CAS
(\verb|point|, \verb|line|, \verb|segment|, \verb|circle|,
\verb|barplot|, \verb|histogram| et les commandes \verb|plot...|).
De plus, vous pouvez travailler avec des expressions et faire
du calcul formel dessus.
Pour la liste compl\`ete des commandes
et une pr\'esentation d\'etaill\'ee, on renvoie \`a la documentation
de Xcas.

\section{Interpr\'eteur MicroPython int\'egr\'e} \label{sec:micropy}
$\chi$CAS est maintenant fourni avec son propre interpr\'eteur MicroPython
(qui n'est pas identique \`a celui fourni par Numworks).
Pour passer dans
$\chi$CAS de l'interpr\'eteur Xcas \`a MicroPython et r\'eciproquement
vous pouvez taper la commande \verb|python| ou \verb|xcas| dans
le shell sur une ligne vide. Ces commandes sont accessibles
dans le menu rapide shift ).

Attention, si vous lancez MicroPython apr\`es avoir travaill\'e
avec Xcas ou/et avec le tableur, il peut ne pas y avoir assez
de m\'emoire pour le tas MicroPython, dans ce cas vous risquez
de perdre votre session de travail, pensez \`a la sauvegarder.
Par d\'efaut, 40K sont r\'eserv\'es pour MicroPython. Vous
pouvez modifier cette valeur jusqu'\`a 64K dans la configuration
(shift EXE ou Home puis touche ln). Si vous choisissez une valeur
haute, il peut \^etre n\'ecessaire de quitter $\chi$CAS
et de le r\'eouvrir pour que le tas puisse \^etre allou\'e
dans une zone m\'emoire contigu\"e (probl\`eme de fragmentation
du tas sinon). 

Remarque~: lorsque l'interpr\'eteur Xcas est actif, si vous passez
en argument \`a la commande \verb|xcas| ou \verb|python| le
nom de variable d'une fonction que vous avez programm\'ee, cela
affiche son texte source sous forme d'une chaine de caract\`eres
en syntaxe Xcas ou Python. Vous pouvez donc programmer en syntaxe
Xcas et traduire ensuite en Python si vous devez vous
conformer \`a des r\`egles qui imposent ce langage.

\subsection{Les modules math, cmath, random}
Ce sont les modules natifs fournis par MicroPython (\verb|urandom|
a \'et\'e renomm\'e \verb|random|), et qui sont
conforme au standard. D'autres modules MicroPython standard
qui ne sont pas destin\'es \`a faire des maths sont disponibles.

\subsection{Le module graphic}
Il s'agit d'un module natif MicroPython qui exporte de Xcas des fonctions
de trac\'e pixelis\'es. Une partie des commandes est accessible
depuis le menu rapide shift 0.
Ce module a des synonymes, \verb|kandinsky| et \verb|casioplot|
afin de faciliter l'utilisation de scripts Python pour
calculatrices Numworks (Epsilon) et Casio.

\subsection{Le module matplotl}
Il s'agit d'un module natif MicroPython qui exporte de Xcas des fonctions
de trac\'e rep\'er\'e et vise \`a une certaine compatibilit\'e avec
le module \verb|matplotlib| (ou un de ses sous-modules) sur PC.
Une partie des commandes est accessible
depuis le menu rapide shift \verb|.|

\subsection{Le module arit}
C'est un module natif qui exporte de Xcas
des fonctions d'arithm\'etique enti\`ere~:
test de primalit\'e et prochain nombre premier (par Miller-Rabin),
factorisation d'entiers pas trop gros (d\'etection
par Pollard-rho du plus petit facteur premier, donc jusqu'\`a environ
9 chiffres), pgcd et identit\'e de B\`ezout, indicatrice d'Euler (si
on sait factoriser). J'y ai aussi inclus
deux fonctions de conversion liste vers chaine
de caract\`eres pour faciliter l'enseignement d'un peu de cryptographie.


\subsection{Le module linalg}
Il permet de manipuler les listes comme des vecteurs et les listes
de listes comme des matrices. Contrairement \`a Xcas,
Python n'est pas un langage sp\'ecifiquement adapt\'e aux maths,
il faut utiliser des
commandes pr\'efix\'ees \verb|add, sub, mul| pour effectuer
les op\'erations arithm\'etiques de base \verb|+ - *| sur les
vecteurs et matrices repr\'esent\'es par des listes.

Le module \verb|linalg| est un module natif, qui utilise Xcas
pour effectuer la quasi-totalit\'e des calculs.

\subsection{Le module numpy}
C'est une surcouche du module \verb|linalg| qui d\'efinit une
classe \verb|array| pour repr\'esenter les vecteurs et les matrices.
On peut alors utiliser \verb|+ - *| pour faire les op\'erations
de base sur vecteurs et matrices.

Le module \verb|numpy| n'est pas un module natif, c'est un texte
source \'ecrit en Python. Son importation consomme donc de la m\'emoire
RAM. Vous pouvez \'ecrire votre propre version de \verb|numpy.py|
et la stocker dans le scriptstore, elle prendra alors la pr\'ec\'edence
sur la version utilis\'ee par d\'efaut. Cette derni\`ere vise \`a assurer
un minimum de compatibilit\'e avec le module du m\^eme nom sur PC.
Bien que non natif, ce module est disponible en mode examen
(le texte source par d\'efaut est int\'egr\'e au code source de
l'interpr\'eteur MicroPython).
%\begin[language=Python]{lstlisting}
\begin{verbatim}
import linalg
import math
class array: 
    def __init__(self, a): 
        self.a = a 
  
    def __add__(self, other): 
        return array(linalg.add(self.a , other.a))
  
    def __sub__(self, other): 
        return array(linalg.sub(self.a , other.a))
  
    def __mul__(self, other):
        if type(self)==array:
            if type(other)==array:
                return array(linalg.mul(self.a , other.a))
            return array(linalg.mul(self.a,other))
        return array(linalg.mul(self,other.a))
    
    def __rmul__(self, other): 
        if type(self)==array:
            if type(other)==array:
                return array(linalg.mul(self.a , other.a))
            return array(linalg.mul(self.a,other))
        return array(linalg.mul(self,other.a))

    def __matmul__(self, other):
        return __mul(self,other)

    def __getitem__(self,key):
        r=(self.a)[key]
        if type(r)==list or type(r)==tuple:
            return array(r)
        return r

    def __setitem__(self, key, value):
        if (type(value)==array):
            (self.a)[key]=value.a
        else:
            (self.a)[key]=value
        return None

    def __len__(self):
        return len(self.a)
    
    def __str__(self): 
        return 'array('+str(self.a)+')'
  
    def __repr__(self): 
        return 'array('+str(self.a)+')'
  
    def __neg__(self):
        return array(-self.a)

    def __pos__(self):
        return self
    
    def __abs__(self):
        return array(linalg.abs(self.a))

    def __round__(self):
        return array(linalg.apply(round,self.a,linalg.matrix))

    def __trunc__(self):
        return array(linalg.apply(trunc,self.a,linalg.matrix))

    def __floor__(self):
        return array(linalg.apply(floor,self.a,linalg.matrix))

    def __ceil__(self):
        return array(linalg.apply(ceil,self.a,linalg.matrix))

    def T(self):
        return array(linalg.transpose(self.a))
            
def real(x):
    if type(x)==array:
        return array(linalg.re(x.a))
    return x.real

def imag(x):
    if type(x)==array:
        return array(linalg.im(x.a))
    return x.imag

def conj(x):
    if type(x)==array:
        return array(linalg.conj(x.a))
    return linalg.conj(x)

def sin(x):
    if type(x)==array:
        return array(linalg.apply(math.sin,x.a,linalg.matrix))
    return math.sin(x)

def cos(x):
    if type(x)==array:
        return array(linalg.apply(math.cos,x.a,linalg.matrix))
    return math.cos(x)

def tan(x):
    if type(x)==array:
        return array(linalg.apply(math.tan,x.a,linalg.matrix))
    return math.tan(x)

def asin(x):
    if type(x)==array:
        return array(linalg.apply(math.asin,x.a,linalg.matrix))
    return math.asin(x)

def acos(x):
    if type(x)==array:
        return array(linalg.apply(math.acos,x.a,linalg.matrix))
    return math.acos(x)

def atan(x):
    if type(x)==array:
        return array(linalg.apply(math.atan,x.a,linalg.matrix))
    return math.atan(x)

def sinh(x):
    if type(x)==array:
        return array(linalg.apply(math.sinh,x.a,linalg.matrix))
    return math.sinh(x)

def cosh(x):
    if type(x)==array:
        return array(linalg.apply(math.cosh,x.a,linalg.matrix))
    return math.cosh(x)

def tanh(x):
    if type(x)==array:
        return array(linalg.apply(math.tanh,x.a,linalg.matrix))
    return math.tanh(x)

def exp(x):
    if type(x)==array:
        return array(linalg.apply(math.exp,x.a,linalg.matrix))
    return math.exp(x)

def log(x):
    if type(x)==array:
        return array(linalg.apply(math.log,x.a,linalg.matrix))
    return math.log(x)

def size(x):
    if type(x)==array:
        return linalg.size(x.a)
    return linalg.size(x)

def shape(x):
    if type(x)==array:
        return linalg.shape(x.a)

def dot(a,b):
    return a*b

def transpose(a):
    if type(x)==array:
        return array(linalg.transpose(x.a))

def trn(a):
    if type(x)==array:
        return array(linalg.conj(linalg.transpose(x.a)))
    return linalg.conj(linalg.transpose(x.a))

def zeros(n,m=0):
    return array(linalg.zeros(n,m))

def ones(n,m=0):
    return array(linalg.ones(n,m))

def eye(n):
    return array(linalg.eye(n))

def det(x):
    if type(x)==array:
        return linalg.det(x.a)
    return linalg.det(x)

def inv(x):
    if type(x)==array:
        return array(linalg.inv(x.a))
    return linalg.inv(x)

def solve(a,b):
    if type(a)==array:
        if type(b)==array:
            return array(linalg.solve(a.a,b.a))
        return array(linalg.solve(a.a,b))
    if type(b)==array:
        return array(linalg.solve(a,b.a))
    return linalg.solve(a,b)

def eig(a):
    if type(a)==array:
        r=linalg.eig(a.a)
        return array(r[0]),array(r[1])
    return linalg.eig(a)

def linspace(a,b,c):
    return array(linalg.linspace(a,b,c))

def arange(a,b,c=1):
    return array(linalg.arange(a,b,c))

def reshape(a,n,m=0):
    if type(n)==tuple:
        m=n[1]
        n=n[0]
    if type(a)==array:
        return array(linalg.matrix(n,m,a.a))
    return linalg.matrix(n,m,a)
\end{verbatim}
%\end{lstlisting}

\section{Applications additionnelles}
Les applications additionnelles sont accessibles en tapant shift Ans.
Il y a actuellement un tableur, le tableau p\'eriodique des \'el\'ements
(d'apr\`es Maxime Friess),
et trois exemples d'addin qui peuvent servir de mod\`ele aux
programmeurs~: la suite de Syracuse (tr\`es simple), la
fractale de Mandelbrot et les bassins d'attraction de la méthode
de Newton, et un jeu
de mastermind (qui peut aussi servir de passe-temps).

\section{Tableur} \label{sec:tableur}
Au lancement, vous avez un tableau de 14 lignes et 4 colonnes
remplies de 0. Vous pouvez changer la dimension depuis la configuration
du tableur (shift EXE ou Home puis configuration), mais attention, chaque cellule
utilise de la m\'emoire, un peu moins de 100 octets pour une cellule
remplie d'un nombre, plusieurs centaines d'octets si elle est
remplie par une formule, et la m\'emoire de la Numworks est tr\`es limit\'ee,
s'il n'y a pas assez de m\'emoire lors d'une allocation, vous
perdrez votre session de travail.
Pensez \`a faire une sauvegarde de votre session de temps en temps!

La syntaxe pour cr\'eer une formule est identique \`a celle d'un tableur
classique, on tape sur shift = puis on entre la formule, avec
des r\'ef\'erences relatives (par exemple \verb|=a1+1|)
ou absolues (\verb|=$a$1+1|). Pour saisir une cellule après avoir
tapé \verb|=|, on peut
déplacer le curseur vers la cellule cible, à condition de commencer
par un déplacement de curseur vers le haut ou vers le bas (sinon
le déplacement vers la droite ou la gauche déplace dans la ligne
de commande, pas dans le tableur).
On peut utiliser les commandes
de Xcas ainsi que des fonctions qu'on a programm\'ees.

Il y a des assistants de saisie sp\'ecifiques au tableur
dans les menus rapides shift 1, 2 et 3.
Par exemple pour g\'en\'erer des entiers cons\'ecutifs,
taper shift 3 puis OK ce qui cr\'ee une ligne de commande
contenant \verb|range(|, il suffit de mettre un entier $a$ ou deux entiers
$a$ et $b$ en arguments pour cr\'eer la liste des entiers entre 0 et $a-1$
ou entre $a$ et $b-1$ et la dispatcher sur la colonne.

Autre exemple, pour
avoir un tableau de valeurs de fonctions, se placer au d\'ebut
d'une colonne vide dont la colonne \`a droite est aussi vide
et taper shift 3, s\'electionner \verb|tablefunc| puis passer
en argument l'expression, par exemple \verb|sin(x)| (ou \verb|f(x)|
si vous avez d\'efini une fonction \verb|f|). Vous pouvez
ensuite r\'egler la valeur de d\'ebut et le pas dans le tableur.
Pour une suite r\'ecurrente, se placer en haut d'une colonne vide
et utiliser la commande \verb|tableseq| du menu rapide shift 3.

Pour s\'electionner une plage de cellules, taper simultan\'ement sur
shift et une touche de direction, vous pouvez ensuite
relacher shift et d\'eplacer le curseur en fin de s\'election.
Tapez OK pour valider (si vous la
passez en argument d'une formule saisie dans une cellule du tableur), ou
shift copy si vous voulez copier la s\'election dans le presse-papier
pour par exemple la recopier dans le shell avec shift paste.

Si vous utilisez un des assistants de statistiques 2d, faites la
s\'election des 2 colonnes avant de choisir la commande.
Par exemple, en 1\`ere ligne, 1\`ere colonne, tapez shift 3
s\'electionnez \verb|range| puis compl\'etez en \verb|range(6)|
comme valeurs de X
puis en face en 2\`eme colonne entrez des valeurs et Y.
D\'eplacez le curseur en 1\`ere ligne et en 1\`ere colonne,
puis shift-curseur
vers le base puis d\'eplacements du
curseur pour rejoindre l'autre extr\'emit\'e de la s\'election,
puis shift 2, puis par exemple \verb|polygonscatterplot|.
Pour voir le graphique, tapez shift 6. Pour voir sur le m\^eme graphique
la droite de r\'egression lin\'eaire correspondante, vous pouvez recommencer
la proc\'edure ou bien recopier la cellule contenant
la formule de \verb|polygonscatterplot| avec shift-copy shift-copy
et la coller avec shift paste en-dessous, puis la modifier (shift 4 OK)
en rempla\c{c}ant
\verb|polygonscatterplot| par \verb|linear_regression_plot|

Lorsqu'on utilise une plage de cellule en argument d'une commande, la
plage de cellule est aplatie en une seule liste. Si on souhaite utiliser
une matrice comme argument d'une commande, il faut reconstruire
la matrice \`a partir de la liste en utilisant la commande
\verb|matrix(l,c,liste)| o\`u \verb|l,c| sont les dimensions
de la matrice (c'est ce que fait l'assistant \verb|scatterplot|
du menu rapide de statistiques 2d (shift 2) si on s\'electionne
la plage de cellules auparavant).

Dans le menu accessible depuis la touche shift EXE ou HOME, vous pouvez ins\'erer
ou effacer une ligne ou une colonne, vous pouvez aussi donner un nom
de variable au tableur, la matrice des valeurs sera alors automatiquement
sauvegard\'ee dans cette variable, que vous pouvez utiliser ensuite depuis
le shell.

Si vous entrez dans une cellule une formule donnant un r\'esultat vecteur
ou matrice, celle-ci sera dispatch\'ee par d\'efaut
dans plusieurs cellules. On peut modifier cela dans la configuration
du tableur.



\section{Raccourcis claviers.} \label{sec:clavier}
\begin{itemize}
\item shift * (N0110 verrouillées, N0115, N0120): table de caractères
\item shift + (N0110 verrouillées, N0115, N0120): indentation ou aide
\item La touche d'effacement en mode alphab\'etique  a \'et\'e modifi\'ee
  (dans tout l'OS) pour effacer et ne pas renvoyer \verb|%|,
  car cela rend la correction d'erreur de frappes tr\`es p\'enible. Pour
  saisir \verb|%|, tapez shift \verb|/| (ce qui est facile
  \`a retenir quand on programme un peu).
\item on peut taper alpha-shift-\verb|"| pour saisir \verb|'|
  \item le caract\`ere \verb|\| est accessible via shift-\verb|-|.
  \item shift-1 \`a shift-6: selon le mode (Xcas ou Python)
    voir les l\'egendes
\item shift-7 (M) matrice, 8 complexes, 9 arithm\'etique enti\`ere,
  \verb|(| listes, \verb|)| programmation,
  \verb|0| probas \verb|.| r\'eels,
  \verb|x10^| arithm\'etique polynomiale,
  %, \verb|)|
  Si MicroPython est activ\'e, shift 7 linalg, 8 numpy,
  9 arithm\'etique enti\`ere, \verb|(| listes, \verb|)| programmation,
  \verb|0| matplotl, \verb|.| graphic, \verb|x10^| couleurs
\item Si Xcas est actif,
  \verb|=>| suivi d'une unit\'e physique effectue une conversion
  d'unit\'e, 
  \verb|=>| suivi d'une fonction permet d'ex\'ecuter des actions:\\
  \verb|=>*| \'ecriture sous forme de produit (pour une unit\'e, \'ecriture
  en utilisant les unit\'es fondementales du syst\`eme MKSA),\\
  \verb|=>+| \'ecriture sous forme de somme (pour une unit\'e, \'ecriture
  sous forme le plus simple possible),\\
  \verb|=>/| \'ecriture sous forme de quotient,\\
  \verb|=>sin|, \verb|=>cos|, \verb|=>tan|
  conversion vers des sinus, cosinus ou tangentes.\\
  \verb|=>,| permet de chronom\'etrer une \'evaluation,\\
  \verb|16=>=>| \'ecrit les entiers en base 16,
  \verb|10=>=>| en base 10, \verb|8=>=>| en base 8
\item shift-) 8 EXE permet de changer d'interpr\'eteur.
\end{itemize}

Dans l'\'editeur de programmes~:
\begin{itemize}
\item touches curseur shift\'ees: d\'eplacement en d\'ebut/fin de ligne/fichier.
\item shift copy ou shift et touche curseur simultan\'ement:
  d\'ebut de s\'election. D\'eplacer le curseur \`a l'autre
extr\'emit\'e puis taper sur DEL pour effacer la s\'election
et la copier dans le presse-papier ou sur
shift copy pour copier la s\'election sans l'effacer.
Pour coller le presse-papier, taper shift paste.
%Taper sur DEL pour annuler.
\item EXE: si une recherche/remplacement
de mot est active (apr\`es avoir fait shift EXE 6 ou Home 6 selon le modèle),
recherche l'occurence suivante d'un mot. Sinon, passe \`a la ligne.
\item DEL efface le caract\`ere pr\'ec\'edent ou la s\'election.
\item shift PASTE: copie le presse-papier
%\item AC/ON: annule la s\'election ou annule la recherche, sinon
%efface la ligne courante et la copie dans le presse-papier
\item var: bascule entre l'\'editeur et la figure tortue
\item Back: quitte l'\'editeur et revient en ligne de commandes. On
peut revenir ensuite \`a l'\'editeur en tapant \`a nouveau Back.
\end{itemize}

\section{Moteur de rendu 3d et g\'eom\'etrie.} \label{sec:geo3d}
La derni\`ere version de $\chi$CAS pour Numworks fournit un moteur
de rendu de graphique 3d, inspir\'e au d\'epart par le script 
\ahref{https://my.numworks.com/python/schraf/graph3d}{Python 3d} de Eric
Schrafstetter. 

Ce moteur de rendu apparait si vous créez une figure 3d
ou si vous entrez dans le shell ou
l'\'editeur de programmes
une commande renvoyant un graphe dans l'espace, par exemple
depuis le menu Toolbox, sous-menu 3d (raccourci \verb|(|)~:
\begin{itemize}
\item un plan, donn\'e par 3 points ou une \'equation cart\'esienne
par exemple \giacinput{plan(z=x)}
\item une surface $z=f(x,y)$ avec la commande \verb|plot(f(x,y))|
ou la commande \verb|plotfunc(f(x,y),[x,y],nstep=N)|
\item une surface param\'etr\'ee avec la commande \verb|plotparam|
\item un poly\`edre, en particulier les poly\`edres r\'eguliers
  (solides de Platon)
  correspondent \`a une commande \verb|tetrahedron|, \verb|cube|,
\verb|octahedron|, \verb|dodecahedron|, \verb|icosahedron|
\item une droite, un segment donn\'ee par 2 points ou par 2
  \'equations cart\'esiennes (droite uniquement).
\item une courbe gauche param\'etr\'ee, par exemple
\giacinput{plotparam([t,cos(t),sin(t)])}
\end{itemize}
Depuis le moteur, appuyez sur 
sur shift EXE ou HOME (ou sur Toolbox sauf depuis l'application
de géométrie 3d) pour modifier les
r\'eglages num\'eriquement et pour voir la liste des raccourcis
clavier, dont voici les plus importants~:
\begin{itemize}
\item les touches du curseur permettent de changer de point de vue.
Pendant le changement de point de vue, le calcul/affichage de la
sc\`ene est effectu\'e avec une pr\'ecision plus faible et
peut être interrompu en appuyant sur la touche Back.
\item la touche 5 permet de revenir au point de vue initial
\item la touche $y^x$ recalcule et affiche la sc\`ene 3d en
  pr\'ecision maximale, ce qui peut \^etre assez long. Vous pouvez
interrompre le calcul pr\'ecis en appuyant sur la touche Back
\item les touches \verb|+| et \verb|-| permettent de zoomer in ou out,
les touches \verb|*| et \verb|/| de faire un autoscale ou une
orthonormalisation
\item les touches 7,9,1,3 permettent de se d\'eplacer dans la sc\`ene
  3d selon $x$ et $y$.
\end{itemize}

Il est possible de cr\'eer des figures g\'eom\'etriques 2d ou 3d, et
de faire des calculs de g\'eom\'etrie analytique. Ouvrez l'\'editeur
de programmes, effacez si n\'ecessaire le patron \verb|def ...| ou
\verb|efface ...|, puis entrez une instruction par ligne. Pour passer
\`a la ligne, utilisez la touche EXE, pour afficher la construction
utilisez la touche OK. Les principales commandes de g\'eom\'etrie
se trouvent dans le menu Toolbox. Le menu rapide shift \verb|+|
affiche les commandes de g\'eom\'etrie les plus fr\'equentes,
le menu shift \verb|*| permet de donner facilement des couleurs
aux objets g\'eom\'etriques cr\'e\'es.

%% \section{Remarques}
%% La m\'emoire vive (RAM) disponible sur la Numworks est vraiment
%% tr\`es faible
%% (esp\'erons que ce sera modifi\'e dans les prochains mod\`eles!).
%% $\chi$CAS impl\'emente des garde-fous lorsque la m\'emoire est satur\'ee,
%% mais vous risquez de perdre le travail qui n'a pas \'et\'e
%% sauvegard\'e dans $\chi$CAS, ou pire dans l'ensemble des applications
%% de la calculatrice si elle reboote.

%% Il est donc conseill\'e de transf\'erer vos
%% programmes sur un ordinateur en branchant la calculatrice
%% et en faisant pointer sur l'ordinateur le navigateur
%% Chromium ou compatible sur
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{ce site}
%% ou avec les fonctions d'\'echange avec Xcas PC.

%% Il n'y
%% a pas pour le moment de m\'ecanisme de sauvegarde sur la flash des
%% donn\'ees. Ce serait bienvenu, d'une part cela lib\'ererait un peu
%% de RAM, d'autre part cela permettrait d'\^etre r\'esistant \`a un crash
%% et d'avoir une biblioth\`eque bien plus importante de programmes
%% mais aussi de sessions compatibles Xcas, Xcas pour Firefox et $\chi$cas
%% pour Casio (qu'il serait agr\'eable de pouvoir \'echanger sur le
%% workshop Numworks ou sur un autre espace par exemple sur tiplanet).

%% Certains changements de Khi affectent l'application Python
%% ou l'ensemble des applications~:
%% \begin{itemize}
%% \item La prise en compte du clavier a \'et\'e un peu modifi\'ee,
%%   cf. la section \ref{sec:clavier}.
%% %% \item L'espace de stockage pour les scripts passe de 16K \`a 20K,
%% %%   mais une partie de cet espace sert \`a stocker la session courante
%% %%   de $\chi$CAS.
%% %% \item La taille maximale d'un script \'editable dans l'application
%% %%   Python est ramen\'ee de 16K \`a 12K
%% %%   Vous pouvez avoir plusieurs scripts.
%% %%   Vous pouvez aussi \'editer vos scripts depuis $\chi$CAS en b\'en\'eficiant
%% %%   des plus de l'\'editeur de $\chi$CAS (parenthese matching, choix
%% %%   de la petite fonte de caract\`eres, plus besoin de faire du d\'efilement
%% %%   horizontal, test de la syntaxe directement depuis l'\'editeur, etc.).
%% %%   Vous pouvez aussi mettre au point vos scripts
%% %%   compatibles depuis le d\'ebuggueur de $\chi$CAS et les ex\'ecuter
%% %%   dans MicroPython si vous avez besoin de plus de vitesse que
%% %%   celle de l'interpr\'eteur de $\chi$CAS.
%% %% \item l'espace de travail pour MicroPython passe de 16K \`a 28K.
%% %%   Si vous \^etes limit\'e par l'espace m\'emoire de MicroPython
%% %%   et si votre script est compatible $\chi$CAS, sachez que l'espace
%% %%   de travail de $\chi$CAS est de 56K environ, et que la taille
%% %%   des objets de base est environ 3 fois plus faible dans $\chi$CAS
%% %%   (8 octets pour un petit entier ou flottant contre 24 en MicroPython).
%% %%   Par contre, la taille d'un script interpr\'et\'e dans $\chi$CAS
%% %%   est importante (de l'ordre de 6K pour l'exemple de Mandelbrot dont
%% %%   le source fait 440 octets).
%% %% \item 2 fonctions ont \'et\'e rajout\'ees dans MicroPython~: \verb|get_key()|
%% %%   qui renvoie un code touche (cf. \ref{sec:os}), et \verb|Pause(n)|
%% %%   qui attend approximativement $n$ secondes.
%% %%   On peut \`a nouveau utiliser un seul entier pour
%% %%   d\'ecrire une couleur.
%%   \item L'espace de travail pour les calculs hors de $\chi$CAS
%% est divis\'e par 2, afin de laisser de la place pour les calculs
%% dans $\chi$CAS. Je pense que cela suffit aux besoins des applications
%% interactives de Epsilon, pour les calculs un peu plus gros,
%% vous pouvez utiliser $\chi$CAS qui est g\'en\'erallement
%% plus rapide ou plus pr\'ecis. Quelques exemples~:
%% \begin{itemize}
%% \item calcul num\'erique
%%   $$ \sum_{n=1}^{1000} \sin(\cos(n+.5))$$
%%   $\chi$CAS: 0.64s, Epsilon: 1.5s environ
%%   (mesur\'e en prenant la somme jusque 10000 et en divisant par 10)
%% \item calcul matriciel exact, $a$ une matrice 4,4 inversible
%%   \`a coefficients entiers
%%   entre 0 et 10, on calcule \verb|det(1/a^32)|, il faut environ 0.1
%%   seconde avec $\chi$CAS et 5 secondes avec Epsilon.
%% \item le calcul d'une int\'egrale num\'erique g\'en\'eralis\'ee telle
%%   que $$ \int_{0.0}^1 \ln(x) \ dx$$
%%   renvoie undef avec Epsilon.
%%   Pr\`es d'une extr\'emit\'e singuli\`ere
%%   $$ \int_{0.001}^1 x \cos\left(\frac{1}{x}\right) \ dx $$
%%   $\chi$CAS renvoie 0.0181170904, Epsilon 0.01793743 (erreur relative 1\%)
%% \end{itemize}
%% \end{itemize}
%% Vous pouvez modifier ces param\'etrages en modifiant les sources de
%% Delta (les fichiers \`a modifier
%% sont \verb|poincare/include/poincare/tree_pool.h|,
%% \verb|apps/code/app.h|,
%% \verb|ion/include/ion/storage|) et en recompilant
%% (section \ref{sec:epsilon12}).

\section{Copyright, licences et remerciements}
\begin{itemize}
\item OS \ahref{https://github.com/numworks/epsilon}{Epsilon}
  de la Numworks, version 15.5 (c) 2021 Numworks.
  Sous licence
  \ahref{https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode}
      {Creative Commons Attribution-NonCommercial-
        ShareAlike 4.0 International Public License}\\
      Modifications par Damien Nicolet et Bernard Parisse, (c) 2019 et 2021
      (projets Delta, Khi), sous la m\^eme licence. Modifications par
      l'\'equipe du projet
      \ahref{https://github.com/Omega-Numworks/Omega}{Omega}
  (c) 2021 sous la m\^eme licence.
\\
Depuis la version 16, Epsilon est indiqué (c) Tous droits réservés.
La publication sur github donne toutefois un certain nombre de
\ahref{https://docs.github.com/en/site-policy/github-terms/github-terms-of-service#d-user-generated-content}{droits} à tout utilisateur de github. Le code
de la propriété intellectuelle,
\ahref{https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000044365559}{L.122-6-1} autorise également certains actes à des fins d'interopérabilité.
  \item Giac et $\chi$CAS, noyau de calcul (c) B. Parisse et R. De Graeve, 2024.
    Les calculs en entiers sont effectu\'es avec
    \ahref{https://gmplib.org/}{GMP}, les flottants multip\'ecision
    avec \ahref{https://www.mpfr.org/}{MPFR},
    l'arithm\'etique d'intervalle avec
    \ahref{https://gforge.inria.fr/projects/mpfi/}{MPFI}
\item Certaines parties du code sont sous licence MIT: 
\begin{itemize}
\item \ahref{https://github.com/micropython/micropython/blob/master/LICENSE}
{MicroPython 1.12 (c) Damien P. George}
\item \ahref{https://www.nayuki.io/page/qr-code-generator-library}
{QR code generator, project Nayuki}
\end{itemize}
\item Interface de $\chi$CAS adapt\'ee par B. Parisse \`a partir
de l'interface utilisateur du code source d'Eigenmath
cr\'e\'ee par Gabriel Maia et de l'interface utilisateur de Xcas.\\
  License d'utilisation de $\chi$CAS: GPL2.
  (voir le d\'etail
des conditions dans le fichier
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/LICENSE.GPL2}{LICENSE.GPL2} 
ou sur la page
\ahref{https://www.gnu.org/licenses/old-licenses/gpl-2.0.fr.html}{GPL2}
du site de la Free Software Foundation).
\item
Le code source de $\chi$CAS ainsi que des librairies 
GMP, MPFR, MPFI et de la version modifi\'ee de l'OS Numworks, sont
disponibles
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/khi.tgz}{pour la version N0110 non verrouillée}
et \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/khib.tgz}{pour les autres modèles}, qui utilisent aussi un
lanceur d'application externe
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/lanceur.zip}{version indépendante} (ou \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/launch.tgz}{version NWA})
\item
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/apps.tar}{L'archive apps.tar pour N0110 non verrouillée} 
contient d'autres applications, dont les licences sont (sauf
erreur involontaire de ma part)~:
\begin{itemize}
\item Nofrendo sous licence \ahref{https://www.gnu.org/licenses/old-licenses/lgpl-2.1.fr.html}{LGPL2}
\item Peanut-GB sous licence \ahref{https://opensource.org/licenses/MIT}{MIT}
\item Hexedit sous licence \ahref{https://opensource.org/licenses/BSD-2-Clause}{BSD2}
\end{itemize}
\item
  Remerciements \`a Damien Nicolet pour le premier portage de giac
  sur Numworks N100 (au prix d'une modification mat\'erielle), pour
  le portage de la newlib (librairie C/C++) sur N110 et la maintenance
  des sources au format git et la compatibilit\'e avec les sources
  de Numworks. Sans lui, ce portage n'existerait pas.\\
  Remerciement à Yaya.Cout pour son travail sur Upsilon,
de longs échanges de courriels,
  du code pour accéder aux informations des firmwares verrouillés
  et la rédaction de ce \ahref{https://github.com/Yaya-Cout/KhiCAS_guide/blob/626b9786ff19504152628cfa42447c87ab73f648/KhiCAS_guide.pdf}{Tutoriel (par fmOOmf et Yaya-Cout)}.\\
Remerciements à Ayabusa qui a ouvert la voie au déverrouillage
sur les N0120 en créant un patch du bootloader
ainsi que pour de longs échanges de courriels.\\
  Remerciement \`a Jean-Baptiste Boric pour tests et conseils,
  \`a Maxime Friess pour son squelette d'application hello
  et \`a toute l'\'equipe d'Omega pour les am\'eliorations qu'ils ont
  apport\'e \`a Epsilon.\\
  Remerciement \`a l'\'equipe de tiplanet, en particulier Xavier Andr\'eani,
  Lionel Debroux et Adrien Bertrand, pour le forum de discussion
  et tout le travail de
  mise en valeur de $\chi$cas (stockages d'archives, articles, concours).\\
  Remerciements au (ou à la) mystérieux ScarlettSpell, créateur
du site Nwagyu (aujourd'hui abandonné),
dont le portage de $\chi$CAS en application externe Numworks
m'a fortement incité à créer la nouvelle version de $\chi$CAS pour les Numworks
récentes verrouillées.
\item le tableau p\'eriodique des \'el\'ements est un portage de
  \ahref{https://github.com/M4xi1m3/nw-atom}{l'application de Maxime Friess} 
  avec son autorisation de diffusion sous licence GPL.
%\item Remerciement \`a Numworks France pour le pr\^et d'une
%calculatrice et une licence d'utilisation de l'\'emulateur.
\end{itemize}

\section{D\'eveloppement en C/C++.} \label{sec:dev}
Cette section s'adresse aux utilisateurs avanc\'es qui souhaitent programmer
leur calcultrice en exploitant toute sa puissance, donc
sans \^etre limit\'e par la faible quantit\'e de m\'emoire
disponible pour des scripts Python et la lenteur relative du
langage interpr\'et\'e. Le syst\`eme non modifi\'e
de la Numworks permet de le faire, mais il est difficile de
le maitriser, au-del\`a de modifications simples du code
existant (par exemple modifier la valeur de certains param\`etres),
il faut bien connaitre C++, la programmation orient\'e objet
et se limiter \`a une librairie standard tr\`es spartiate.
Cela limite \`a mon avis le nombre de d\'eveloppeurs
et la vitesse de d\'eveloppement sur cette plateforme,
encore plus si on est habitu\'e \`a un
environement de d\'eveloppement frugal, personnellement
j'utilise \verb|emacs| comme \'editeur de texte et un terminal,
les arborescences \`a plusieurs niveaux et les espaces de noms
imbriqu\'es d'Epsilon sont un cauchemar. Le temps n\'ecessaire \`a
la compilation d'Epsilon est d'ailleurs un indicateur de cette
complexit\'e.

Un autre probl\`eme est que modifier
Epsilon n\'ecessite d'utiliser la m\^eme licence de logiciel,
on ne peut donc pas d\'evelopper du logiciel libre.

Damien Nicolet et moi-m\^eme avons d\'evelopp\'e des modifications
autour de Epsilon, qui permettent de lancer un firmware d'extensions
\`a partir de Epsilon. C'est le projet Delta/Khi, qui permet d'utiliser la
\verb|newlib|, une impl\'ementation compl\`ete de la libc et
de la libstdc++, et offre un SDK en langage C et en C--
(i.e. avec un paradigme
de programmation imp\'eratif tr\`es proche du C donc beaucoup
plus accessible, avec les
avantages que procurent la librairie standard C++).
Ainsi ajouter une application toute simple comme la suite
de Syracuse n\'ecessite une dizaine de lignes de code,
programmer la fractale de Mandelbrot et les bassins
d'attraction ou
le jeu de mastermind font une bonne centaine de lignes (ces
trois exemples se trouvent dans le fichier \verb|kadd.cc| du
source de \verb|giac|) et l'interface
du tableur de $\chi$CAS de l'ordre d'un millier de lignes.

{\bf Licences}\\
L'utilisation du SDK de base de l'OS (\ref{sec:os}) vous impose
de choisir une licence permettant d'utiliser les services de base
d'un OS propri\'etaire, ce que toute licence de logiciel raisonnable
devrait permettre, c'est le cas en particulier de la GPL.
L'utilisation des autres fonctions du SDK impose une licence
compatible avec la GPL.

\subsection{Installation de l'environnement de d\'eveloppement.}
Je d\'ecris l'installation sous Linux debian/ubuntu compatible
depuis un terminal avec comme shell \verb|bash|.
On peut programmer sur d'autres OS, mais c'est plus facile sous Linux (en tout
cas c'est plus facile pour moi d'expliquer comment faire!). Si vous
travaillez habituellement sur Mac ou Windows, vous pouvez installer
une machine virtuelle, par exemple avec
\ahref{https://www.virtualbox.org/wiki/Downloads}{Virtualbox} et
y mettre une distribution Linux debian-compatible, par exemple
\ahref{https://xubuntu.org/}{xubuntu}.


On installe les packages n\'ecessaires pour compiler giac et pour
cross-compiler pour le processeur ARM~:
\begin{verbatim}
sudo apt-get install wget gdb gcc g++ libgmp-dev libmpfr-dev libmpfi-dev libpari-dev libgsl0-dev libxext-dev libpng-dev libjpeg-dev libreadline-dev libncurses5-dev mesa-common-dev libx11-dev libxt-dev libxft-dev libntl-dev libgl1-mesa-dev libgl-dev libao-dev hevea debhelper libfltk1.3-dev
sudo apt-get install build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config gcc-arm-none-eabi binutils-arm-none-eabi dfu-util
\end{verbatim}

%% \subsubsection{Epsilon 12} \label{sec:epsilon12}
%% Pour r\'ecup\'erar les sources, utilisez une des deux m\'ethodes suivantes
%% \begin{itemize}
%%   \item on r\'ecup\`ere tout en une seule commande~:
%% \begin{verbatim}
%% git clone https://github.com/Delta-NumWorks/delta
%% \end{verbatim}
%% \item
%%   on r\'ecup\`ere s\'epar\'ement Delta (la version modifi\'ee de Epsilon),
%%   puis les librairies n\'ecessaires pour compiler giac, puis giac.
%%   Cela assure d'avoir la version de Giac la plus \`a jour.
%% \begin{verbatim}
%% wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/delta12.tgz
%% tar xvfz delta12.tgz
%% cd delta
%% wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tgz
%% tar xvfz ext.tgz 
%% cd ext
%% wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/giac/giac_unstable.tgz
%% tar xvfz giac_unstable.tgz
%% cd ../..
%% \end{verbatim}
%%   \end{itemize}

%% Compilation pour la Numworks.
%% Les librairies n\'ecessaires \`a la compilation
%% de $\chi$CAS pour Numworks
%% sont pr\'ecompil\'ees dans le r\'epertoire \verb|ext/n0110/lib|. Il
%% faut juste compiler Delta.
%% \begin{verbatim}
%% cd delta
%% make V=1 USE_LIBA=0 EPSILON_DEVICE_BENCH=0 EPSILON_USB_DFU_XIP=0 EPSILON_ONBOARDING_APP=0 EPSILON_BOOT_PROMPT=update epsilon.dfu 
%% \end{verbatim}
%% Si vous voyez des messages tels que \verb|... switch -mcpu=cortex-m7 conflicts...|, c'est que le cross-compilateur ARM de votre distribution
%% Linux est trop ancien. Allez sur le site du
%% \ahref{https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads}{ARM SDK}, descendez
%% jusqu'\`a faire apparaitre la version 7 (vous pouvez essayer une version
%% plus r\'ecente mais les binaires risquent de ne pas fonctionner
%% sur votre distribution Linux), t\'el\'echargez
%% pour Linux x64 et ex\'ecutez la commande\\
%% \verb|cd && tar xvfj Downloads/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2|\\
%% puis ajoutez dans votre fichier \verb|~/.bashrc| la ligne\\
%% \verb|export PATH=~/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH|\\
%% sauvegardez, puis tapez les commandes\\
%% \verb|source ~/.bashrc|\\
%% \verb|cd delta|\\
%% \verb|make clean|\\
%% \verb|make V=1 USE_LIBA=0 EPSILON_DEVICE_BENCH=0 EPSILON_USB_DFU_XIP=0 EPSILON_ONBOARDING_APP=0 EPSILON_BOOT_PROMPT=update epsilon.dfu|

%% Les fichiers firmware d'extension \verb|dfu| sont dans le r\'epertoire
%% \verb|output/device/release/n0110|.
%% Pour les flasher sur la calculatrice faire
%% \begin{verbatim}
%% dfu-util -i0 -a0 -D  output/device/release/n0110/epsilon_cc.dfu #-s 0x90000000
%% dfu-util -i0 -a0 -D  output/device/release/n0110/epsilon_gpl.dfu #-s 0x92000000
%% \end{verbatim}
%% Le premier fichier est le firmware Epsilon avec les modifications
%% du projet Delta, qui fournit une interface pour programmer la calculatrice
%% en C et permet d'appeler une fonction de prototype
%% \verb|int ext_main()|, fonction qui doit \^etre
%% impl\'ement\'ee dans le deuxi\`eme firmware,
%% l'adresse fixe de \verb|ext_main| doit \^etre \verb|0x92000000| 
%% (plus pr\'ecis\'ement \verb|0x92000001| en mode Thumb du processeur ARM).
%% Par exemple, l'impl\'ementation de la fonction \verb|ext_main|
%% dans le firmware $\chi$CAS (sous licence GPL) compil\'e ici
%% lance le shell $\chi$CAS. On peut remplacer le firmware $\chi$CAS par
%% un autre firmware impl\'ementant une fonction
%% \verb|extern "C" int ext_main();| et
%% link\'ee \`a l'adresse fixe en \verb|0x92000001|
%% sans modifier le firmware Delta. Pour faire cela, il faut mettre
%% une ligne du type \verb|*(.text.ext_main)|
%% au d\'ebut de la section de la flash gpl
%% dans le fichier du linker (\verb|flash.ld|).

%% Pour compiler le simulateur, faire
%% \begin{verbatim}
%% cd ext/giac-1.5.0/src
%% ln -sf config.h.numworks.gmp config.h
%% make -f Makefile.numworks.simulator
%% /bin/cp simu/libgiac.a ../../simulator/lib
%% cd ../../..
%% /bin/rm output/simulator/debug/epsilon.elf
%% make V=1 DEBUG=1 PLATFORM=simulator
%% ln -sf output/simulator/debug/epsilon.elf simu
%% \end{verbatim}
%% Essayez mantenant de taper \verb|./simu| puis de lancer $\chi$CAS sur
%% le simulateur. 

%% Si vous modifiez un fichier de \verb|giac|, il faut mettre \`a jour
%% la libraire pour les deux architectures et la recopier
%% \begin{verbatim}
%% cd ext/giac-1.5.0/src
%% make -f Makefile.numworks.gmp
%% /bin/cp device/libgiac.a ../../n0110/lib
%% make -f Makefile.numworks.simulator
%% /bin/cp simu/libgiac.a ../../simulator/lib
%% cd ../../..
%% \end{verbatim}
%% % # ln -sf config.h.numworks.gmp config.h
%% % # make -f Makefile.numworks.gmp clean
%% % # make  -f Makefile.numworks.simulator clean
%% puis forcer l'\'edition de liens du firmware
%% \begin{verbatim}
%% /bin/rm output/device/release/n0110/epsilon*elf
%% make V=1 USE_LIBA=0 EPSILON_DEVICE_BENCH=0 EPSILON_USB_DFU_XIP=0 EPSILON_ONBOARDING_APP=0 EPSILON_BOOT_PROMPT=update epsilon.dfu
%% \end{verbatim}
%% et celle du simulateur
%% \begin{verbatim}
%% /bin/rm output/device/release/simulator/epsilon.elf
%% make V=1 DEBUG=1 PLATFORM=simulator
%% \end{verbatim}


\subsubsection{Epsilon 15.3.1/Khi (calculatrice), 12.3 (simulateur)}
\label{sec:epsilon12}
{\bf Simulateur Delta}\\
Pour r\'ecup\'erar les sources du simulateur, faire
\begin{verbatim}
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/delta_simu.tar.bz2
tar xvfj delta_simu.tar.bz2 
\end{verbatim}
Pour compiler le simulateur, vous pouvez lancer le script
\verb|delta/mksimu| 
ou vous pouvez ex\'ecuter les instructions suivantes
\begin{verbatim}
cd delta/ext/giac-1.6.0/src
ln -sf config.h.numworks.gmp config.h
make -f Makefile.numworks.simulator
/bin/cp simu/libgiac.a ../../simulator/lib
cd ../../..
/bin/rm output/simulator/debug/epsilon.elf
make V=1 DEBUG=1 PLATFORM=simulator
ln -sf output/simulator/debug/epsilon.elf simu
\end{verbatim}
Essayez mantenant de taper \verb|./simu| puis de lancer $\chi$CAS sur
le simulateur en tapant \verb|\| ou \verb|$| selon le clavier (cette touche
permet de simuler l'appui sur la touche HOME).

Attention, le support de MicroPython et de l'ex\'ecution en mode pas \`a pas
n'est pas compatible, \`a cause du code assembleur de certaines
fonctions situ\'ees dans les fichiers \verb|delta/python/src/py/nlr*|. En
cons\'equence si vous s\'electionnez MicroPython pour
\'evaluer dans $\chi$CAS, le simulateur plantera d\`es la premi\`ere
\'evaluation. Pour contourner ce probl\`eme,
il faut compiler ces fichiers \verb|nlr*| en mode release
puis copier les fichiers objets obtenus dans le r\'epertoire \verb|debug|
d'Epsilon/Delta. Pour faire cela, vous pouvez lancer le script
\verb|delta/mksimu|, puis le script \verb|delta/cpnlr|.
La prochaine ex\'ecution de \verb|delta/mksimu| devrait
alors donner un ex\'ecutable \verb|simu| qui permet d'activer
simultan\'ement l'\'evaluation MicroPython et la mise au point.

{\bf Version du source calculatrice avec le multi-boot Khi}~: faites
\begin{verbatim}
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/khi2.tgz
tar xvfz khi2.tgz
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/khi18.tgz
tar xvfz khi18.tgz
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/khiext.tgz
tar xvfz khiext.tgz
\end{verbatim}
khi2 est pour le slot 1, khi18 pour le slot 2 (et contient le
bootloader avec slot 2 en 0x90180000 et slot 3 en 0x90400000).

Il y a donc quatre arborescences distinctes, trois pour la calculatrice
(\verb|khi18|, \verb|khi2| et \verb|khiext|), une (\verb|delta|)
pour avoir un environnement de d\'eveloppement avec possibilit\'e
d'ex\'ecuter le code pas \`a pas. Cela pour deux raisons
\begin{itemize}
\item le simulateur a chang\'e dans Epsilon 14, et la nouvelle
  version est inutilisable sur ma machine (affichage flou peu lisible),
  je travaille donc avec l'ancienne version du simulateur (qui par
  ailleurs utilise le m\^eme toolkit FLTK que Xcas ce qui me facilite
  le travail pour adapter le simulateur pour debugguer efficacement)
\item le shell $\chi$CAS permet maintenant de choisir MicroPython comme
  \'evaluateur. Sur la calculatrice, $\chi$CAS et Epsilon sont compl\`etement
  s\'epar\'es donc chacun peut utiliser son propre MicroPython,
  mais sur le simulateur,
  il n'y a qu'une seule application, il faut donc utiliser le m\^eme
  source pour le MicroPython dans Epsilon et dans $\chi$CAS.
\end{itemize}

Le r\'epertoire \verb|khi2| contient l'arborescence pour compiler
pour l'OS calculatrice, \verb|khiext| pour les extensions. Les librairies n\'ecessaires
sont pr\'ecompil\'ees dans le r\'epertoire \verb|khiext/apps|.
\begin{verbatim}
cd khi2
make MODEL=bootloader epsilon.A.bin  
cd ../khiext
make 
\end{verbatim}
Si vous voyez des messages tels que \verb|... switch -mcpu=cortex-m7
conflicts...|, 
c'est que le cross-compilateur ARM de votre distribution
Linux est trop ancien. Allez sur le site du
\ahref{https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads}{ARM SDK}, descendez
jusqu'\`a faire apparaitre la version 9 (vous pouvez essayer une version
plus r\'ecente si votre distribution Linux est r\'ecente), t\'el\'echargez
pour Linux x64 et ex\'ecutez la commande\\
\verb|cd && tar xvfj Downloads/gcc-arm-none-eabi-9-2020-q2-update-linux.tar.bz2|\\
puis ajoutez dans votre fichier \verb|~/.bashrc| la ligne\\
\verb|export PATH=~/gcc-arm-none-eabi-9-2020-q2-update/bin:$PATH|\\
sauvegardez, puis tapez les commandes\\
\verb|source ~/.bashrc|\\
\verb|cd chemin_vers_khi2|\\
\verb|make|\\
\verb|cd ../khiext|\\
\verb|make|\\
\verb|cd ../|\\
{\bf Vous pouvez aussi \'editer les scripts \verb|mkarm|  des r\'epertoires
\verb|khi2| et \verb|khiext| et les ex\'ecuter \`a la place de \verb|make|}

Le fichier firmware de la version modifi\'ee de Epsilon,
\verb|epsilon.A.bin| est dans le sous-r\'epertoire
\verb|output/release/device/bootloader| de \verb|khi2|,
le fichier contenant les applications externes est \verb|apps.tar|
dans le r\'epertoire \verb|khiext|.
Pour les flasher sur la calculatrice, faire reset+4 sur la
calculatrice et
\begin{verbatim}
dfu-util -i0 -a0 -s 0x90000000 -D khi2/output/release/device/bootloader/epsilon.A.bin -R
dfu-util -i0 -a0 -D khiext/apps.tar -s 0x90200000:force
\end{verbatim}
Le premier fichier est le firmware Epsilon avec les modifications
des projet Delta/Omega/Khi. Ce projet 
fournit une interface pour programmer la calculatrice
en C et permet d'ex\'ecuter du code contenu
dans un fichier \verb|apps.tar| qui est stock\'e dans le
deuxi\`eme firmware.

Le r\'epertoire \verb|khi18| contient une version all\'eg\'ee de
Epsilon pour fournir un firmware de lancement minimal, qui permet
d'acc\'eder \`a plus de m\'emoire RAM dans $\chi$CAS. La compilation
est quasi-identique \`a celle dans \verb|khi2|\\
\verb|make MODEL=bootloader epsilon.B.bin|\\
ou \'editer et ex\'ecuter le script \verb|mkarm|.


{\bf $\chi$CAS}\\
Si vous modifiez le source de giac, il faut recompiler
la librairie \verb|libgiac.a| et la copier
dans \verb|../../lib|,
pour cela vous pouvez utiliser le script \verb|mkarm| dans le r\'epertoire
\verb|khiext|.
N'oubliez pas de r\'epercuter la modification dans le code source du
simulateur.

\subsubsection{Epsilon 19.5 à 23, compiler $\chi$CAS pour N0110/N0115/N0120.} \label{sec:eps22}
\begin{enumerate}
\item
Sur un {\bf Mac}, l'installation est un peu compliquée, car il faut construire
un binaire pour les deux architectures Intel et ARM64, il y a donc plusieurs
shells scripts spécifiques \verb|mkmac, mkarm, mkx86|
qui appellent 2 fichiers Makefile, un pour chaque architecture.
Pour pouvoir compiler, il faut installer homebrew et les d\'ependances
pour les deux architectures, sur un Mac r\'ecent arm64, cela se fait 
depuis un Terminal (tapez Terminal depuis le launchpad) avec les
commandes ci-dessous (taper command-C et command-V pour faire
du copier-coller)
\begin{verbatim}
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install numworks/tap/epsilon-sdk
brew install libpng gmp mpfr mpfi
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
arch -x86_64 /usr/local/bin/brew install libpng gmp mpfr mpfi
\end{verbatim}
Ensuite on tape
\begin{verbatim}
git clone -b version-23 https://github.com/parisseb/epsilon
cd epsilon
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
tar xfj ext.tar.bz2
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwsimu.tgz
tar xfz nwsimu.tgz
./mkmac
mv output/release/simulator/macos/epsilon.app /Applications
open /Applications/epsilon.app
\end{verbatim}

\item
Procédure de compilation sous {\bf Linux}.
Pour installer le simulateur avec $\chi$CAS, vérifiez que vous avez
installé l'environnement de développement (gcc, sdl, etc.) pour votre
PC. Si ce n'est pas le cas 
ouvrez un terminal, et copiez-collez les commandes ci-dessous
(raccourci shift-Ctrl-V pour copier dans le terminal)
\begin{verbatim}
sudo apt-get install wget build-essential git imagemagick libx11-dev libxext-dev libfreetype6-dev libpng-dev libjpeg-dev pkg-config python3 python3-pip
sudo apt-get gcc g++ libgmp-dev libmpfr-dev libmpfi-dev libpari-dev libgsl0-dev libxext-dev libpng-dev libjpeg-dev libreadline-dev libncurses5-dev mesa-common-dev libx11-dev libxt-dev libxft-dev libntl-dev libgl1-mesa-dev libgl-dev libao-dev hevea debhelper libecm1-dev libnauty2-dev libcliquer-dev libresample1-dev libxinerama-dev libsamplerate0-dev libfltk1.3-dev
pip3 install lz4 pypng stringcase
\end{verbatim}
puis exécutez toujours depuis un terminal les commandes
\begin{verbatim}
git clone -b version-23 https://github.com/parisseb/epsilon
cd epsilon
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
tar xfj ext.tar.bz2
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwsimu.tgz
tar xfz nwsimu.tgz
./mk
ln -sf output/release/simulator/linux/epsilon.bin simu
./simu
\end{verbatim}
Notez que la compilation par le script mk se fait en deux temps, d'abord
la compilation normale d'Epsilon mais qui renvoie des erreurs car elle
ne linke pas avec les librairies contenant Xcas et ses dépendances,
puis une édition de liens avec ce qui est nécessaire, et qui elle
ne doit pas renvoyer d'erreurs.

\item
{\bf Sur un PC Windows}\\
Premi\`ere m\'ethode~:
on peut installer une distribution Linux
en utilisant 
\ahref{https://learn.microsoft.com/fr-fr/windows/wsl/install}{WSL}
ou dans une machine virtuelle avec un logiciel de virtualisation comme
VirtualBox et suivre les indications Linux ci-dessus.\\ 
Deuxi\`eme m\'ethode~: installer
\ahref{https://www.msys2.org/}{Msys2/mingw64}.
Ensuite ouvrir depuis le menu principal Windows, dans Msys2 
un terminal mingw64. Dans le menu Options
de la fenêtre, sélectionner Keys, puis cocher Ctrl-shift-letter shortcut,
ceci vous permettra de coller avec Ctrl-shift-V.
Copier-coller la commande ci-dessous et exécutez-là~:
\begin{verbatim}
pacman -S git wget mingw-w64-x86_64-gcc mingw-w64-x86_64-freetype mingw-w64-x86_64-pkg-config mingw-w64-x86_64-libusb make mingw-w64-x86_64-python3 mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libpng mingw-w64-x86_64-imagemagick mingw-w64-x86_64-librsvg mingw-w64-x86_64-inkscape mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python-lz4 mingw-w64-x86_64-libpng gmp mpfr
echo "export PATH=/mingw64/bin:$PATH" >> .bashrc
pip3 install pypng stringcase
\end{verbatim}
Vérifiez que vous pouvez compiler Epsilon sans KhICAS
\begin{verbatim}
git clone -b version-23 https://github.com/parisseb/epsilon
cd epsilon
make PLATFORM=simulator
\end{verbatim}
Si tout va bien, ajoutez les modifications permettant d'utiliser $\chi$CAS
\begin{verbatim}
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/ext.tar.bz2
tar xfj ext.tar.bz2
wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/nwsimu.tgz
tar xfz nwsimu.tgz
\end{verbatim}
Il faut ensuite
\begin{itemize}
\item soit compiler et installer 
\ahref{http://perso.ens-lyon.fr/nathalie.revol/softwares/mpfi-1.5.4.tar.bz2}{MPFI} 
dans \verb|/usr/lib|, on le désarchive
\verb|tar xfj /chemin/vers/mpfi-1.5.4.tar.bz2|
on le configure avec \verb|./configure --prefix=/usr|
puis \verb|make| puis \verb|make install|,
\item soit enlever \verb|-lmpfi| dans le script \verb|mkwin|
\end{itemize}
puis on exécute le script \\
\verb|./mkwin|\\
(au lieu de \verb|mk|).
\end{enumerate}
Cf. la section \ref{sec:install} pour une rapide description
de l'utilisation du simulateur.

% Pour automatiser le lancement du simulateur sur Mac depuis
% un terminal, vous pouvez cr\'eer
% un fichier \verb|nwemu| contenant
% \begin{verbatim}
% #! /bin/bash
% open path_to/epsilon.app
% \end{verbatim}
% ex\'ecutez \verb|chmod 755 nwemu|, d\'eplacez-le dans votre PATH,
% par exemple
% \verb|mv nwemu /opt/homebrew/bin|. Ensuite \verb|nwemu|
% lancera le simulateur depuis un terminal.

Pour pouvoir utiliser le débugger, il faut échanger les \verb|#|
lignes 22 et 23 de \verb|build/defaults.mak|.
Attention, Python ne fonctionne pas avec la compilation
en mode debug (\verb|-g|), il faut compiler les fichiers \verb|nlr*|
sans ce flag (par exemple on compile tout en mode debug,
puis on change \verb|defaults.mak|, on fait 
\verb|touch pypthon/port/mpconfigport.h|, et on compile).

Le code source pour la {\bf calculatrice physique} est disponible 
dans les deux archives
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/lanceur.zip}{version lanceur indépendante}
(ou \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/launch.tgz}{version lanceur NWA})
et \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/khib.tgz}{version de $\chi$CAS}.
\begin{enumerate}
\item
Normalement il n'y a pas de raison de modifier le lanceur
d'application externe.
Si n\'ecessaire, il faut lire la section \ref{sec:indep} si 
on utilise le lanceur indépendant ou sinon
installer l'EADK de Numworks et compiler avec \verb|make|
et génère un fichier \verb|output/khicas.nwa| qui 
s'installe depuis le site des 
\ahref{https://my.numworks.com/apps}{applications externes de Numworks}.
Il est lié à l'EADK de Numworks, avec quelques ajouts pour les fonctions
manquantes, afin de donner accès à la même API que l'application External
des N0110 non verrouillées. 
\begin{verbatim}
  extern "C" void (* const apiPointers[])(void) = {
    (void (*)(void)) extapp_millis,
    (void (*)(void)) extapp_msleep,
    (void (*)(void)) extapp_scanKeyboard,
    (void (*)(void)) extapp_pushRect,
    (void (*)(void)) extapp_pushRectUniform, // 4
    (void (*)(void)) extapp_pullRect,
    (void (*)(void)) extapp_drawTextLarge,
    (void (*)(void)) extapp_drawTextSmall,
    (void (*)(void)) extapp_waitForVBlank, // 8
    (void (*)(void)) extapp_clipboardStore,
    (void (*)(void)) extapp_clipboardText,
    (void (*)(void)) extapp_fileListWithExtension,
    (void (*)(void)) extapp_fileExists, // 12
    (void (*)(void)) extapp_fileErase,
    (void (*)(void)) extapp_fileRead,
    (void (*)(void)) extapp_fileWrite,
    (void (*)(void)) extapp_lockAlpha, // 16
    (void (*)(void)) extapp_resetKeyboard,
    (void (*)(void)) extapp_getKey,
    (void (*)(void)) extapp_restorebackup,
    (void (*)(void)) extapp_erasesector, // 20
    (void (*)(void)) extapp_writememory,
    (void (*)(void)) extapp_inexammode,
    (void (*)(void)) extapp_isalphaactive, 
    (void (*)(void)) extapp_kbdstatus,  // 24
    (void (*)(void)) nullptr,
  };
\end{verbatim} 
L'adresse de ce tableau est ensuite passé en paramètre à la fonction \verb|extapp_start| de \verb|khib/startup.c|\\
\verb|uint32_t _extapp_start(const uint32_t api_version, const void * api_base, void * heap, const uint32_t heap_size);|\\
qui va copier ces paramètres, en particulier le tableau apiPointers qui sert
à faire fonctionner le SDK C  dans \verb|khib/api.c|,
initialiser la RAM statique, puis appeler \verb|extapp_main|
dans \verb|khib/main.c|, qui
appelle \verb|ext_main| qui appelle \verb|caseval("*")| ce
qui est une convention de la librairie Giac/Xcas 
pour lancer le shell de $\chi$CAS.
\item
$\chi$CAS peut se compiler en deux versions: une version allégée sans
l'aide complète qui tient dans le 2ème slot Numworks
(commençant à 0x90400000) ou en version complète qui génère alors
deux fichiers binaires, un commençant en 0x90260000 et finissant en 0x903f0000
(les données read only), le deuxième commençant en 0x90400000, il 
se présente comme une archive tar à laquelle on peut ajouter des fichiers
de données/scripts qui seront accessibles en lecture seule sur la calculatrice.
On utilise l'une des commandes \verb|./mkb| ou \verb|./mkab|. 
On peut envoyer à la calculatrice une autre archive tar en 0x90200000
qui contient des données/scripts accessible en lecture/écriture depuis
la calculatrice.
Il y a donc 4 versions de fichiers de link (*.ld) selon 
le modèle de calculatrice
cible et la version allégée ou non de $\chi$CAS:
\verb|n01?0.ld, n01?0ab.ld|. On compile par paires, en choisissant
comme cible \verb|khi110b.tar khi120b.tar| ou 
\verb|khi110ab.tar khi120ab.tar| avec comme define
en ligne de compilation de g++ \verb|-DNUMWORKS_SLOTB| ou
\verb|-DNUMWORKS_SLOTAB|.
La RAM statique est située en début de RAM pour les apps externes
(236 octets sont utilisés actuellement), et le lanceur crée le tas
de $\chi$CAS par un malloc la RAM disponible pour les 
apps externes moins 13K pour ne pas
toucher la ram statique de $\chi$CAS
\item
Le modèle actuel est donc le suivant:
\begin{itemize}
\item RAM statique du lanceur (qui fait un peu plus de 200 octets)
au début de la ram des apps externes
\item le tas du lanceur commence juste après, l'appel à
malloc renvoie alors un 
pointeur vers une zone terminant avant la RAM statique de $\chi$CAS
\item
RAM statique de $\chi$CAS: \verb|0x2?034000| (12K, actuellement un peu
plus de 256 octets sont encore disponibles)
\item
flash tar file R/W:  \verb|0x90200000| (6*64K disponible)
\item
flash \verb|.rodata 0x90260000-0x903f0000|: fichier khia, pour
la version longue de $\chi$CAS
\item
flash \verb|.text 0x90400000-0x907f0000| (dont
environ 0.5M disponible pour tar file RO en version longue), fichier
khi1?0ab.tar, ou fichier khi1?0b.tar (version courte).
\end{itemize}
\item
Les commandes dfu pour flasher sans accès Internet
\begin{verbatim}
dfu-util -i 0 -a 0 -s 0x90400000 -D khi120b.tar
    (version courte) ou (version longue)
dfu-util -i 0 -a 0 -s 0x90400000 -D khi120ab.tar
dfu-util -i 0 -a 0 -s 0x90260000 -D khia
    exemples de scripts:
dfu-util -i 0 -a 0 -s 0x90200000 -D khi92
\end{verbatim}
Pour reflasher le secteur de lancement de l'application sans accès
Internet, commencer par récupérer une fois pour toutes
la version du secteur qui correspond à votre firmware/calculatrice
depuis 
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/nws.html#install}{ici}, sauvegardez-là sous un nom tel que {\tt sector} puis
\begin{verbatim}
#! /bin/bash
dfu-util -i 0 -a 0 -s 0x90190000:0x10000:force -U sector
\end{verbatim}
\end{enumerate}

{\bf Remarques~:}
\begin{itemize} 
\item $\chi$CAS peut se compiler en version courte en français uniquement en 
tapant \verb|./mkfr|, cette version occupe environ 4M-90K. On peut
alléger plus en supprimant le support de MicroPython (enlever
\verb|-DMICROPY_LIB| dans le Makefile).
\item
La compilation du lanceur pourrait sans doute
se faire avec un fichier ld ``universel'' qui utiliserait 
un secteur fixe pour la flash (\verb|0x90190000|)
et le fonds de la pile (stack) pour la RAM statique
(\verb|0x2?380000|) vu que la pile a pas mal de place disponible, 
il faudrait aussi remplacer les
appels à l'EADK par des appels SVC et ajouter le nécessaire
(headers) pour être reconnu comme app externe Numworks. 
\begin{verbatim}
ion/src/device/userland/drivers/external_apps.cpp
ion/include/ion/external_apps.h
  /* The ExternalApp start with its info layout as:
   * - 4 bytes: a magic code 0xBABECODE
   * - 4 bytes: the API level of the AppInfo layout
   * - 4 bytes: the address of the app name
   * - 4 bytes: the size of the compressed icon
   * - 4 bytes: the address of the compressed icon data
   * - 4 bytes: the address of the entry point
   * - 4 bytes: the size of the external app including the AppInfo header
   * - 4 bytes: the same magic code 0xBABECODE
   */
apps/home/controller.cpp: affichage et lancement par switchToExternalApp
apps/apps_container.cpp:void AppsContainer::switchToExternalApp(Ion::ExternalApps::App app)
\end{verbatim}
\end{itemize}



%% \subsubsection{Avec le lanceur d'applications externes}
%% Damien Nicolet a impl\'ement\'e un syst\`eme de lancement
%% d'applications externes pour la Numworks, qui apporte des
%% am\'eliorations notables, dont une augmentation du tas disponible
%% pour les applications (128K, presque le double), et la possibilit\'e
%% de relancer une application avec un tas r\'einitialis\'e.

%% Pour compiler, faire~:
%% \begin{verbatim}
%% git clone -b external https://github.com/Delta-NumWorks/delta
%% cd delta 
%% make epsilon.dfu
%% cd  ..
%% git clone https://github.com/Delta-NumWorks/nw-external-apps
%% cd nw-external-apps
%% make apps.tar
%% cd ..
%% \end{verbatim}

%% Pour flasher la calculatrice
%% \begin{verbatim}
%% dfu-util -i0 -a0 -D delta/output/device/release/n0110/epsilon.dfu
%% dfu-util -i 0 -a 0 -s 0x90200000 -D external-apps/apps.tar
%% \end{verbatim}
%% ou \verb|sudo apt-get install chromium-browser| puis
%% \verb|chromium-browser index.html|.

%% Pour mettre \`a jour \verb|libgiac.a|, il faut la recompiler comme expliqu\'e
%% dans les sections pr\'ec\'edentes, puis la recopier dans
%% \verb|nw-external-apps/apps/khicas|.

%% Dans cette version, la taille maximale des donn\'ees initialis\'ees
%% (data) et non initialis\'ees (bss) est fix\'ee \`a 16K (elle utilise
%% la zone dite ITCM-RAM à l'adresse 0), la taille de la pile (partag\'ee
%% avec Epsilon) est de 32K et le tas pour les applications externes
%% est de 128K.

%% \subsubsection{Epsilon 11}
%% Attention, ici on va g\'en\'erer un firmware monolithique
%% donc non redistribuable. Mais on gagne 4K de RAM, environ 10\% de
%% plus de m\'emoire.
%% On r\'ecup\`ere
%% les sources de giac et epsilon/delta, et on compile pour la Numworks
%% \begin{verbatim}
%% cd
%% mkdir numworks
%% cd numworks
%% wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/gmpfri_numworks.tgz
%% tar xvfz gmpfri_numworks.tgz
%% wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/giac/giac_unstable.tgz
%% tar xvfz giac_unstable.tgz
%% cd giac-1.5.0/src
%% /bin/cp config.h.numworks.gmp config.h
%% /bin/cp Makefile.numworks.gmp Makefile
%% /bin/cp static_lexer_numworks.h static_lexer.h
%% /bin/cp static_lexer__numworks.h static_lexer_.h
%% make
%% \end{verbatim}
%% Si vous voyez des messages tels que \verb|... switch -mcpu=cortex-m7 conflicts...|, c'est que le cross-compilateur ARM de votre distribution
%% Linux est trop ancien. Allez sur le site du
%% \ahref{https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads}{ARM SDK}, descendez
%% jusqu'\`a faire apparaitre la version 7 (vous pouvez essayer une version
%% plus r\'ecente mais les binaires risquent de ne pas fonctionner
%% sur votre distribution Linux), t\'el\'echargez
%% pour Linux x64 et ex\'ecutez la commande\\
%% \verb|cd && tar xvfj Downloads/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2|\\
%% puis ajoutez dans votre fichier \verb|~/.bashrc| la ligne\\
%% \verb|export PATH=~/gcc-arm-none-eabi-7-2018-q2-update/bin:$PATH|\\
%% sauvegardez, puis tapez les commandes\\
%% \verb|source ~/.bashrc|\\
%% \verb|cd numworks/giac-1.5.0/src|\\
%% \verb|make clean|\\
%% \verb|make|\\
%% Il ne devrait plus y avoir d'avertissements. Lorsque la compilation de
%% giac est termin\'ee, tapez~:
%% \begin{verbatim}
%% cp libgiac.a ../../lib
%% cd ~/numworks
%% #git clone -b n110-giac https://github.com/zardam/epsilon
%% wget https://www-fourier.univ-grenoble-alpes.fr/~parisse/numworks/delta11.tgz
%% tar xvfz delta11.tgz
%% cd epsilon
%% #/bin/rm build/device/n0110/epsilon.elf
%% make V=1 USE_LIBA=0 EPSILON_DEVICE_BENCH=0 EPSILON_USB_DFU_XIP=0 EPSILON_ONBOARDING_APP=1 EPSILON_BOOT_PROMPT=update build/device/n0110/epsilon_two_binaries #-j
%% arm-none-eabi-objdump -t build/device/n0110/epsilon.elf > dump_t
%% \end{verbatim}
%% La derni\`ere commande cr\'ee un fichier avec la liste des symboles, ce qui
%% permet de v\'erifier qu'on n'a pas cr\'e\'e par exemple une grosse
%% variable qui prend trop de place en m\'emoire RAM.

%% Attention, ce firmware n'est pas redistribuable!

%% Pour compiler pour le simulateur (et pouvoir mettre au point),
%% %% installez gcc version 8 si n\'ecessaire\\
%% %% \verb|sudo apt-get install gcc-8 g++-8|\\
%% %% \verb|sudo ln -sf /usr/bin/gcc-8 /usr/bin/gcc|\\
%% %% \verb|sudo ln -sf /usr/bin/g++-8 /usr/bin/g++|\\
%% %% choisir une des deux m\'ethodes ci-dessous
%% \begin{enumerate}
%%   \item Installation plus simple mais sans pouvoir utiliser Xcas~:
%% \begin{verbatim}
%% cd
%% mkdir amd64
%% cd amd64
%% tar xvfz ../numworks/giac_unstable.tgz
%% cd giac-1.5.0/
%% export CXXFLAGS='-g -DNUMWORKS'
%% ./configure --prefix=/usr --disable-gui
%% unset CXXFLAGS
%% \end{verbatim}
%% Ouvrir \verb|src/config.h| avec un \'editeur texte et commentez
%% vers la ligne 100~:\\
%% \verb|/* #define HAVE_GETTEXT 1 */|\\
%% Puis tapez~:
%% \begin{verbatim}
%% make 
%% sudo make install
%% cd ~/numworks/epsilon
%% make V=1 DEBUG=1 PLATFORM=simulator
%% ln -s build/simulator/epsilon.elf simu
%% \end{verbatim}
%% Attention, ceci est incompatible avec une installation de Giac/Xcas.
%% \item Installation moins simple mais permettant d'avoir Xcas simultan\'ement.
%% \begin{verbatim}
%% cd
%% mkdir amd64
%% cd amd64
%% tar xvfz ../numworks/giac_unstable.tgz
%% cd giac-1.5.0
%% ./mkdebian
%% sudo dpkg -i ../giac*deb*
%% export CXXFLAGS='-g -DNUMWORKS'
%% ./configure --prefix=/home/username/amd64 --disable-gui
%% \end{verbatim}
%%   {\bf Atttention}, ci-dessus remplacer \verb|username| par votre
%%   nom d'utilisateur.
%%   Ouvrir \verb|src/config.h| avec un \'editeur texte et commentez vers
%%   la ligne 100 l'utilisation de gettext~:\\
%% \verb|/* #define HAVE_GETTEXT 1 */|\\
%% Puis tapez~:
%% \begin{verbatim}
%% unset CXXFLAGS
%% make 
%% make install
%% export LD_LIBRARY_PATH=~/amd64/lib
%% cd ~/numworks/epsilon
%% make V=1 DEBUG=1 PLATFORM=simulator
%% ln -sf build/simulator/epsilon.elf simu
%% \end{verbatim}
%% Essayez mantenant de taper \verb|./simu| puis de lancer $\chi$CAS sur
%% le simulateur. Si une erreur de link ou une erreur de symbole non
%% d\'efini apparait, vous pouvez essayer de linker avec la librairie
%% statique \verb|libgiac.a|, pour cela v\'erifiez avec un \'editeur
%% de texte le shell script \verb|mkstat1| puis lancez la commande\\
%% \verb|sh mkstat1|\\

%% Pour pouvoir utiliser Xcas, il faut le lancer depuis un autre shell
%% ou faire \verb|unset LD_LIBRARY_PATH|. Pour pouvoir linker Epsilon+giac
%% (avec la librairie giac dynamique)
%% ou pour le d\'ebugguer au simulateur, il faut s'assurer d'avoir fait la
%% commande\\
%% \verb|export LD_LIBRARY_PATH=~/amd64/lib|
%% \end{enumerate}
%% L'ex\'ecutable du simulateur se lance par la commande \verb|./simu|
%% depuis le r\'epertoire \verb|numworks/epsilon|,

\subsection{Utilisation du d\'ebuggueur}
Le simulateur peut se lancer avec le d\'ebuggueur en tapant
\verb|gdb ./simu| ou
depuis votre \'editeur de texte ou votre environnement de d\'eveloppement.
Par exemple si vous utilisez
\verb|emacs|, tapez \verb|Esc x gdb|, valider, mettre \verb|simu|
comme nom d'ex\'ecutable, valider. Voir par exemple
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/info/gdb.pdf}{ici}
un guide de prise en main d'utilisation du d\'ebuggueur avec emacs.
Vous pouvez ex\'ecuter la commande\\
\verb|cp delta/ext/giac-1.6.0/src/.gdbinit delta|\\
ou télécharger le fichier \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/giac/.gdbinit}{.gdbinit}
pour d\'efinir la macro \verb|v| de \verb|gdb| qui vous permettra
de visualiser les variables de type \verb|giac::gen| de mani\`ere
plus parlante qu'avec la commande \verb|p|.

Par exemple, si vous faites dans la console \verb|gdb| la commande
\verb|b khicas_addins_menu| (breakpoint, i.e. point d'arr\^et
\`a cette fonction), puis \verb|r| pour lancer
le programme, il s'interrompra
dans le menu d'affichage des applications tierces (shift-Ans),
vous pouvez alors ex\'ecuter ligne apr\`es ligne avec la
commande \verb|n|, en visualisant le contenu des variables
avec la commande \verb|p| ou \verb|v| pour des variables Xcas de type gen.

\subsection{Int\'egration avec le shell $\chi$CAS}
Pour ajouter une application au menu \verb|shift-Ans| des
applications ajout\'ees dans $\chi$CAS,
il faut modifier la fonction \verb|khicas_addins_menu()|
dans \verb|kadd.cc|. 
Incr\'ementez \verb|smallmenu.numitems|,
d\'efinissez \verb|smallmenuitems[j].text| pour
la premi\`ere valeur de \verb|j| disponible, puis dans
la boucle \verb|while(1) {...}|, ajoutez
la d\'efinition de votre fonction ou un appel vers votre fonction
avec \verb|if (smallmenu.selection==j+1)|.
Pour compiler et tester, cf. la fin de la section \ref{sec:epsilon12}.

L'exemple
de la suite de Syracuse vous montre comment faire entrer une valeur,
afficher un graphique rep\'er\'e,
et entrer quelque chose en ligne de commande.
L'exemple de la fractale de Mandelbrot montre comment afficher un
graphique pixelis\'e pixel par pixel.
L'exemple du jeu de Mastermind montre
comment afficher un graphique pixelis\'e avec des formes plus complexes
et interagir avec l'utilisateur lorsqu'il appuie sur une touche.

Conseils~:
\begin{itemize}
  \item Pour commencer \`a programmer votre propre version de $\chi$CAS,
    vous pouvez modifier un de ces exemples. Par exemple,
    demander des param\`etres pour la fractale. Ou changer
    le nombre de couleurs disponibles ou le nombre d'essais
    dans le Mastermind.
    Puis ajouter une application de votre cru, par exemple
    faire un \'ecran de saisie puis afficher une courbe.
  \item Si vous utilisez des donn\'ees constantes,
    n'oubliez pas de mettre le modificateur \verb|const| pour \'economiser
    la m\'emoire RAM.
  \item Pour travailler avec des chaines de caract\`eres
    sans vous soucier des allocations m\'emoires,
    vous pouvez utiliser \verb|string|, pour
    des tableaux de taille dynamique \verb|vector<>|
    (voir par exemple le site \ahref{cplusplus.com}{cplusplus.com}
    pour la description des fonctions de la librairie standard C++)
  \item Il faut \^etre \'econome en m\'emoire,
    la disponibilit\'e sur le tas est faible (un peu plus de 100 kilo-octets si
    aucune variable $\chi$CAS n'est stock\'ee en m\'emoire, que le tas
    Micro-Python n'est pas actif et qu'il n'y a pas de tableur).
\end{itemize}

Les paragraphes qui suivent d\'ecrivent bri\`evement le SDK.
Pour plus de d\'etails, il faut ensuite se r\'ef\'erer \`a
\verb|k_csdk.h| et \verb|kdisplay.h/kdisplay.cc| pour l'interface
et aux fichiers headers de \verb|giac| pour
toutes les fonctions de \verb|giac|.  

\subsection{Fonctions de base de l'OS.} \label{sec:os}
Les fonctions de bas niveau de Epsilon sont d\'eclar\'ees
dans \verb|k_csdk.h|
et sont utilisables depuis un programme C et tout langage
qui s'interface avec C (donc quasiment tout langage).

Si vous voulez cr\'eer une extension
ind\'ependante de $\chi$CAS, vous pouvez vous inspirer
d'une des applications de \verb|final/nw-external-apps|,
d\'efinissez votre propre fonction \verb|int main()|
et linkez avec votre fichier objet \`a la place de
\verb|-lgiac|, dans ce cas vous
pouvez choisir n'importe quelle licence de logiciel qui peut
se lier avec une licence d'OS propri\'etaire.

Le clavier~:
\begin{itemize}
\item \verb|int getkey(int allow_suspend);|\\
  renvoie un code touche, \verb|allow_suspend| est non nul
  si on autorise l'utilisateur \`a \'eteindre la calculatrice
  (attention dans ce cas \`a g\'erer l'affichage).
  Les touches sont d\'efinies comme suit, la 2i\`eme ligne correspond
  aux touches Home (jaune) et Power (noire), avec 4 codes
  de touches inexistantes,
  les lignes \`a partir de la 6i\`eme ont un code de touche inexistant sur le
  clavier.
  
\begin{verbatim}
const short int translated_keys[]=
  {
   // non shifted
   KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
   KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
   KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_XTT,KEY_CTRL_VARS,KEY_CTRL_CATALOG,KEY_CTRL_DEL,
   KEY_CHAR_EXPN,KEY_CHAR_LN,KEY_CHAR_LOG,KEY_CHAR_IMGNRY,',',KEY_CHAR_POW,
   KEY_CHAR_SIN,KEY_CHAR_COS,KEY_CHAR_TAN,KEY_CHAR_PI,KEY_CHAR_ROOT,KEY_CHAR_SQUARE,
   '7','8','9','(',')',-1,
   '4','5','6','*','/',-1,
   '1','2','3','+','-',-1,
   '0','.',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
   // shifted
   KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
   KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
   KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,KEY_CTRL_CUT,KEY_CTRL_CLIP,KEY_CTRL_PASTE,KEY_CTRL_AC,
   KEY_CHAR_LBRCKT,KEY_CHAR_RBRCKT,KEY_CHAR_LBRACE,KEY_CHAR_RBRACE,'_',KEY_CHAR_STORE,
   KEY_CHAR_ASIN,KEY_CHAR_ACOS,KEY_CHAR_ATAN,'=','<','>',
   KEY_CTRL_F7,KEY_CTRL_F8,KEY_CTRL_F9,KEY_CTRL_F13,KEY_CTRL_F14,-1,
   KEY_CTRL_F4,KEY_CTRL_F5,KEY_CTRL_F6,KEY_CTRL_INS,'%',-1,
   KEY_CTRL_F1,KEY_CTRL_F2,KEY_CTRL_F3,'\t','\\',-1,
   KEY_CTRL_F10,KEY_CTRL_F11,KEY_CTRL_F12,KEY_SHIFT_ANS,KEY_CTRL_EXE,-1,
   // alpha
   KEY_CTRL_LEFT,KEY_CTRL_UP,KEY_CTRL_DOWN,KEY_CTRL_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
   KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
   KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','"',KEY_CTRL_DEL,
   'a','b','c','d','e','f',
   'g','h','i','j','k','l',
   'm','n','o','p','q',-1,
   'r','s','t','u','v',-1,
   'w','x','y','z',' ',-1,
   '?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
   // alpha shifted
   KEY_SHIFT_LEFT,KEY_CTRL_PAGEUP,KEY_CTRL_PAGEDOWN,KEY_SHIFT_RIGHT,KEY_CTRL_OK,KEY_CTRL_EXIT,
   KEY_CTRL_MENU,KEY_PRGM_ACON,KEY_PRGM_ACON,9,10,11,
   KEY_CTRL_SHIFT,KEY_CTRL_ALPHA,':',';','\'','%',
   'A','B','C','D','E','F',
   'G','H','I','J','K','L',
   'M','N','O','P','Q',-1,
   'R','S','T','U','V',-1,
   'W','X','Y','Z',' ',-1,
   '?','!',KEY_CHAR_EXPN10,KEY_CHAR_ANS,KEY_CTRL_EXE,-1,
  };
\end{verbatim}
\item \verb|int getkey_raw(bool allow_suspend);|\\
  renvoie le scan code de Numworks,
  de 0 \`a 53 pour le clavier non shift\'e, ajouter 54 pour shift\'e,
  ajouter 108 pour alpha, 162 pour alpha shift\'e
\item \verb|void GetKey(int * key);|\\
  renvoie une touche au clavier, en utilisant le m\^eme prototype
  que le SDK pour calculatrices Casio.
\item \verb|bool os_set_angle_unit(int mode);|
  change l'unit\'e d'angle (0 radians, 1 degr\'es)
\item \verb|int os_get_angle_unit();|
  renvoie l'unit\'e d'angle
\item \verb|bool isalphaactive();|\\
  renvoie vrai si le mode alpha est actif.
\item \verb|bool alphawasactive();|\\
  renvoie vrai si le mode alpha \'etait actif avant la derni\`ere
  frappe de touche
\item \verb|void lock_alpha();|\\
  verrouille le mode alpha
\item \verb|bool back_key_pressed();|\\
  renvoie vrai en cas d'appui sur la touche Back. Utile pour
  permettre d'interrompre un programme. Ceci n\'ecessite de tester
  souvent l'appui sur Back. Attention, pour \'eviter des probl\`emes
  lors de l'initialisation, les 400 premiers appels \`a cette
  fonction renvoient faux.
  \item \verb|bool is_keydown(int key);|
\item \verb|void reset_kbd();|\\
  enl\`eve les modes shift et alpha s'ils \'etaient actifs.
\end{itemize}

{\bf Les affichages.}\\
Notez que $y=0$  correspond \`a
la premi\`ere ligne en-dessous de la ligne d'\'etat (18 pixels de hauteur),
on a donc $0 \leq y<222$  et $0\leq x <320$\\
Les couleurs utilisent un entier 16 bits au format RGB 565, on peut
convertir depuis RGB888 par
\begin{verbatim}
int rgb888to565(int c){
  int r=(c>>16)&0xff,g=(c>>8)&0xff,b=c&0xff;
  return (((r*32)/256)<<11) | (((g*64)/256)<<5) | (b*32/256);
}
\end{verbatim}
\begin{itemize}
\item \verb|void statusline(int mode=0);|\\
  affiche la ligne d'\'etat standard
\item \verb|void statuslinemsg(const char * msg);|\\
  affiche une chaine de caract\`eres dans la ligne d'\'etat
\item \verb|void os_fill_rect(int x,int y,int w,int h,int c);|\\
  remplit un rectangle avec une couleur de couleur \verb|c| donn\'e
  en rgb565, 
  \item \verb|void os_set_pixel(int x,int y,int c);|\\
    affiche un pixel de couleur \verb|c| donn\'e en rgb565
  \item \verb|int os_get_pixel(int x,int y);|\\
    renvoie la couleur rgb565 d'un pixel.
  \item \verb|int os_draw_string(int x,int y,int c,int bg,const char * s,bool fake=false);|\\
    \verb|int os_draw_string_small(int x,int y,int c,int bg,const char * s,bool fake=false);|\\
    \'ecrit une chaine de caract\`ere avec la fonte de taille normale
    ou petite \`a
    partir du pixel $x,y$ en couleur \verb|c| (rgb565 ), avec une couleur de
    fonds \verb|bg|. Renvoie la position finale de $x$.
    Si \verb|fake| est \verb|true|, il n'y a pas d\'ecriture, juste
    le calcul de la position finale de $x$.
  \item \verb|bool waitforvblank()|\\
    synchronisation \'ecran, \`a appeler juste avant de faire
    des op\'erations de trac\'e pour \'eviter le scintillement.
  \item \verb|void os_redraw();|\\
    signale \`a l'OS Numworks qu'il doit retracer l'\'ecran en entier
\end{itemize}

Le syst\`eme de fichiers.
\begin{itemize}
\item \verb|bool file_exists(const char * filename);|
\item \verb|bool erase_file(const char * filename);|
\item \verb|const char * read_file(const char * filename);|
\item \verb|bool write_file(const char * filename,const char * s,size_t len=0);|
\item \verb|int os_filebrowser(const char ** filenames,int maxrecords,const char * extension);|\\
  Place dans \verb|filenames| la liste des noms de fichiers d'extension
  \verb|extension|  
\end{itemize}

Gestion du temps
\begin{itemize}
\item \verb|void os_wait_1ms(int ms);|\\
  attend \verb|ms| millisecondes.
\item \verb|double millis();|\\
  renvoie un nombre de millisecondes depuis le dernier d\'emarrage.
  Attention, l'horloge syst\`eme ne tourne pas \`a la bonne vitesse
  lorsque la calculatrice est \'eteinte, il n'est donc pas possible
  de s'en servir pour afficher l'heure.
\end{itemize}

\subsection{Commandes graphiques compl\'ementaires}
\begin{itemize}
\item \verb|void xcas::draw_line(int x1, int y1, int x2, int y2, int color);|\\
  segment de droite
\item \verb|void xcas::draw_rectangle(int x, int y, int width, int height, int color);|\\
  rectangle rempli
\item \verb|void xcas::draw_polygon(std::vector< std::vector<int> > & v1,int color)|\\
  polygone de sommets dans la matrice de $n$ lignes \verb|v|, une ligne
  par sommet, chaque ligne est un vecteur de 2 entiers
  (coordonn\'ees en pixels). 
\item \verb|void xcas::draw_filled_polygon(std::vector< std::vector<int> > &L,int xmin,int xmax,int ymin,int ymax,int color);|\\
  polygone de sommets dans la matrice de $n$ lignes \verb|v|, une ligne
  par sommet, chaque ligne est un vecteur de 2 entiers
  (coordonn\'ees en pixels). Le polygone rempli est trac\'e
  avec ``clipping'' dans le rectangle d\'efini par \verb|x1,y1,x2,y2|.
\item \verb|void xcas::draw_circle(int xc,int yc,int r,int color);|\\
  cercle de centre \verb|(xc,yc)| et rayon \verb|r|
\item  \verb|void xcas::draw_filled_circle(int xc,int yc,int r,int color);|\\
  disque  de centre \verb|(xc,yc)| et rayon \verb|r|
\item   \verb|void xcas::draw_arc(int xc,int yc,int rx,int ry,int color,double theta1, double theta2);|\\
  arc d'ellipse.
\item  \verb|void xcas::draw_filled_arc(int x,int y,int rx,int ry,int theta1_deg,int theta2_deg,int color,int xmin,int xmax,int ymin,int ymax,bool segment);|\\
  arc d'ellipse rempli, ou segment de cercle rempli avec clipping.

\end{itemize}

\subsection{Interaction avec l'UI $\chi$CAS}
Certaines fonctions utilisent un pointeur vers le contexte
du moteur de calcul (qui contient les variables assign\'ees, le mode
radian/degr\'e, etc.), de type
\verb|giac::context *|, et dont
la valeur est en g\'en\'eral stock\'ee dans la variable \verb|contextptr|
dans les fonctions d'interface de $\chi$CAS de \verb|kdisplay.cc|
(on peut aussi passer un pointeur nul).
\begin{itemize}
\item \verb|int inputline(const char * msg1,const char * msg2,std::string & s,bool numeric,int ypos=65,const giac::context *contextptr=0);|
  permet d'entrer une chaine de caract\`eres en affichant le
  message \verb|msg1| et en pr\'eremplissant la chaine \`a entrer avec
  \verb|msg2|. Seuls les caract\`eres utilisables pour un nombre
  sont accept\'es si \verb|numeric| est \verb|true|. La position
  verticale de la ligne de commande est ajustable en changeant la
  valeur de \verb|ypos|. Renvoie 0 si l'utilisateur a annul\'e en tapant
  sur Back.
\item \verb|bool inputdouble(const char * msg1,double & d,const giac::context *contextptr)|\\
  permet d'entrer un nombre flottant en affichant le message \verb|msg1|,
  renvoir \verb|false| si l'utilisateur a annul\'e en tapant sur Back.
  \verb|int select_item(const char ** ptr,const char * title);|\\
  affiche un menu \`a choix et renvoie le choix de l'utilisateur.
\item \verb|int confirm(const char * msg1,const char * msg2,bool acexit=false,int y=40);|\\
  affiche une boite de dialogue de type OK/Annuler, avec 2 lignes
  d'affichage. Si \verb|acexit| est \verb|true|, l'appui sur Back
  renvoie -1. Sinon, l'appui sur Back renvoie l'entier
  \verb|KEY_CTRL_F6|. L'appui
  sur \verb|OK| ou \verb|EXE| renvoie l'entier \verb|KEY_CTRL_F1|.
  \item \verb|int giac_filebrowser(char * filename,const char * extension,const char * title);|\\
  affiche un menu de s\'election parmi les fichiers dont l'extension
  est \verb|extension|. Si l'utilisateur s\'electionne un fichier,
  renvoie 1 et met le nom de fichier dans \verb|filename|, qui doit
  avoir une taille suffisante.

\item \verb|void displaygraph(const giac::gen & ge, const giac::context * contextptr);|\\
  affiche un \verb|gen| de type graphique (si \verb|ge.is_symb_of_sommet(at_pnt)|)
\item \verb|void displaylogo();|\\
  affiche la tortue logo
\item \verb|giac::gen eqw(const giac::gen & ge,bool editable,const giac::context * contextptr);|\\
  affiche une expression dans l'\'editeur 2d.
\item \verb|void add(textArea *edptr,const std::string & s);|\\
  \'ecrit la chaine C++ \verb|s| vers le buffer texte point\'e
  par \verb|edptr| (dans \verb|edptr->elements|)
\item \verb|int doTextArea(textArea* text,const giac::context * contextptr); |\\
  ouvre l'\'editeur de texte,
  renvoie 0 si l'utilisateur quitte avec la touche Back,
  1 si \verb|text->allowEXE| est \`a \verb|true| et si l'utilisateur
  appuie sur \verb|EXE|, 2 si \verb|text->allowF1| est \`a \verb|true|
  et l'utilisateur appuie sur F1.
\item \verb|std::string merge_area(const std::vector<textElement> & v);|\\
  renvoie la chaine C++ correspondant \`a \verb|v|, si \verb|edptr| est
  un pointeur sur \verb|textArea|, on prendra pour \verb|v|
  \verb|edptr->elements|.
\end{itemize}
L'internationalisation est g\'er\'ee par la commande\\
\verb|const char * gettext(const char *)|\\
Pour ajouter une chaine en plusieurs langues, par exemple Hello,
mettez dans votre code \verb|gettext("Hello")|, et ajoutez
au fichier \verb|numworks_translate.h|, {\em dans l'ordre alphab\'etique}
une ligne du type\\
\verb|{"Hello",0,0/* zt */,"Bonjour" /* fr */,"Guten Tag" /* de */,0 /* es */,0 /* nl */,0 /* pt */,0},|
\\
Attention, l'utilisation du fichier \verb|numworks_translate.h|
ne peut se faire qu'avec du code GPL qui est link\'e avec $\chi$CAS
(mais rien ne vous emp\^eche d'utiliser \verb|gettext| dans
un programme compatible avec la GPL
avec un autre fichier de traductions en repartant de z\'ero).

\subsection{Interaction avec giac}
Le type \verb|giac::gen| permet de travailler avec tous les types
de Xcas~: entier, flottant, fraction, nom de variable, expression,
fonction...
On peut construire un gen avec les types de base C
\begin{verbatim}
gen g(1.2),h(3);
\end{verbatim}
ou avec
l'interpr\'eteur (avec une chaine de caract\`eres), dans ce dernier
cas il faut \'evaluer le gen avec un appel \`a \verb|eval|,
par exemple
\begin{verbatim}
gen g("x^4-1",contextptr);
g=eval(g,1,contextptr);
\end{verbatim}

En g\'en\'eral
une fonction de Xcas a un \'equivalent C++ avec le m\^eme nom pr\'ec\'ed\'e
par \verb|_|,
et deux arguments, un de type \verb|giac::gen|
et un deuxi\`eme
qui est un pointeur sur le contexte d'\'evaluation.
Lorsqu'une commande Xcas prend plusieurs arguments, il faut les grouper
en un gen de type vecteur, en utilisant une commande \verb|makesequence|.
Par exemple \verb|_randNorm(makesequence(0.0,2.0),contextptr)|
\'equivaut \`a la commande \verb|randNorm(0.0,2.0)| de Xcas.
Notez que les fonctions usuelles n'ont pas de pr\'efixe \verb|_|.

\subsection{Sauvegardes et restauration (N0110 non verrouillée)}
Il est possible de sauvegarder l'ensemble des donn\'ees de votre
calculatrice en local sur votre PC, i.e. sans connexion Internet.
Xcas le permet depuis le menu Numworks. On peut aussi 
appeler \verb|dfu-util| directement, cf. la section
\ref{sec:install}. Il faut ensuite r\'ecup\'erer les informations sur
la calculatrice avec la commande\\
\verb|dfu-util -i0 -a0 -s 0x080001c4:0x20 -U platform.info|\\
ce qui place dans le fichier binaire \verb|platform.info| (de taille
32 octets) des informations sur la Numworks
(cf. \verb|ion/src/shared/platform_info.cpp|)
\begin{itemize}
\item offset 0 0xDEC00DF0
\item offset 4 la version (8 caract\`eres)
\item offset 12 le num\'ero de patch (8 caract\`eres)
\item offset 20 (0x14) l'adresse A de l'espace de stockage de la Numworks
\item offset 24 (0x18) la taille T de l'espace de stockage
\item offset 28 (0x1C) 0xDEC00DF0
\end{itemize}
Ensuite en rempla\c{c}ant A et T par leur valeur dans la commande\\
\verb|dfu-util -i0 -a0 -s A:T:force -U numworks.storage|\\
vous pouvez archiver l'ensemble des donn\'ees de votre calculatrice
dans le fichier \verb|numworks.storage|. A devrait valoir
\verb|0x20000b60|, et T \verb|0x8014| (dont 4 octets valant
\verb|0xEE0BDDBA| puis 32K de data puis \`a
nouveau les 4 octets du d\'ebut, et 3 pointeurs) ce qui donne la
commande\\
\verb|rm -f numworks.storage &&dfu-util -i0 -a0 -s 0x20000b60:0x8014:force -U numworks.storage|

Vous pourrez ensuite restaurer l'archive par la commande\\
 \verb|dfu-util -i0 -a0 -s A:T:force -D numworks.storage|\\
avec Khi\\
\verb|dfu-util -i0 -a0 -s 0x20000b60:0x8014:force -D numworks.storage|\\

\section{Développement indépendant sur Numworks verrouillées.} \label{sec:indep}
Lors du verrouillage des Numworks en 2021, Numworks en a discuté
avec la communauté Numworks,
principalement avec les développeurs du firmware tiers Omega, 
mais en me laissant délibérement à l'écart
(j'ai appris le verrouillage sur tiplanet lors de la sortie de la 
version 16 beta d'Epsilon).
Ces discussions n'ont 
probablement pas servi à grand chose, Numworks semble n'avoir 
tenu aucun compte des suggestions faites, si on lit les messages
du \ahref{https://tiplanet.org/forum/viewtopic.php?f=97&t=24968}{sujet sur tiplanet}. 

L'environnement de développement sur Numworks est aujourd'hui hostile, comme
on a pu le voir à la section \ref{sec:optimal}. 
Il y a 8M de flash externe découpé
en 2 slots de 4M chacun, un des slots doit commencer par un firmware
officiel Numworks, il n'y a pas de système de fichiers, il y a peu de RAM
disponible~: sur 256K, 36K sont réservés pour le noyau et la pile, 42K pour le
scriptstore, il ne reste qu'un peu plus de 128K pour une application
externe. La N0120 a m\^eme des zones de RAM suppl\'ementaires 
actuellement inutilis\'ees,
mais qui sont rendues inaccessibles par le kernel (\`a date du
3/11/2025). Ce dernier point semble bien \^etre 
une cons\'equence de la politique commerciale 
de Numworks, il s'agissait de vendre 
\ahref{https://tiplanet.org/forum/viewtopic.php?f=97&t=26390&start=20#p273427}{au m\^eme moment et au
m\^eme prix} que les N0120 des N0110 ou N0115
\ahref{https://tiplanet.org/forum/viewtopic.php?p=269215}{moins
  puissantes} sans que cela ne se voit pour ce qui concerne la RAM 
disponible.
On verra si cela \'evolue prochainement.

On peut soit développer un firmware tiers qui sera 
placé dans l'autre slot, soit développer une application externe
dans le même slot que le firmware officiel. 
\begin{itemize}
\item Dans le premier cas, un seul firmware tiers
est installable, il doit être réactivé par un PC à chaque reset/crash, 
et s'il est basé sur Epsilon, il est uniquement
redistribuable au format source sur github alors qu'avant
le verrouillage, on pouvait redistribuer les firmwares tiers
au format binaire, beaucoup plus simple à installer pour
un utilisateur normal.\\
Ces limitations font qu'aucun 
firmware tiers tel que Upsilon ou Omega n'a jamais été
développé, cette méthode ne sert en fait qu'à tester des variations
mineures de versions d'Epsilon, pour les personnes qui veulent
proposer un PR.\\
 On pourrait s'en servir pour
installer plusieurs applications externes sur le firmware tiers
en désactivant l'écrasement du 1er octet de chaque application externe,
on peut alors réactiver le firmware tiers et toutes ses applications
externes. Mais cela diminue considérablement la taille mémoire
contigüe libre, ce qui compliquerait inutilement la compilation de $\chi$CAS.
\item Dans le deuxième cas,
plusieurs applications externes peuvent être installées simultanément,
mais l'interaction avec le firmware qui lance l'application
externe dépend de la version du firmware, si l'application externe
est linkée normalement, elle ne pourra s'exécuter qu'avec une version
précise de firmware.\\
Numworks a alors imaginé une méthode d'édition de liens
à l'installation sur la calculatrice cible, qui permet de s'affranchir
de cette contrainte, mais cela rend le développeur complètement
dépendant de Numworks, il faut passer par le site de Numworks
pour installer une application externe. Si ce site est inaccessible
(par exemple pas de connection Internet), ou si Numworks décide
brusquement de supprimer le support des applications externes,
tout le travail de développement est perdu, même si on ne fait
pas de mise à jour de la calculatrice, y compris pour le
développeur lui-même!
\end{itemize}

Dans cette section, on va voir qu'il est possible de développer,
des applications externes sans dépendre du site web de Numworks. 
Il suffit en effet de créer
un fichier d'édition de lien \verb|ram.ld| (inclus
par \verb|app.ld|) adapté à la calculatrice
cible et au firmware qui y tourne. La compilation et les tests sont
 alors plus rapides et peuvent se faire sans être connecté à Internet.
L'indépendance a toutefois un prix~:
il faudra une version
de l'application externe pour chaque version de firmware ciblée
(c'est ce que je fais pour le lanceur de $\chi$CAS pour une sélection
de versions de firmware)
ou il faudra la recompiler pour la calculatrice cible.

Les informations nécessaires pour constituer le fichier \verb|ram.ld|
sont contenues dans le header du userland~:
\begin{itemize}
\item offset 0x14 et 0x18 début et fin des apps externes
\item offset 0x1c et 0x20 début et fin de la RAM utilisable
\item à partir de l'offset 0x20, chercher les 4 octets 0xfe 0xed 0xc0 0xde,
par exemple offset 0x2c, ajouter 12, par exemple offset 0x38, 
on trouve l'adresse du ``trampoline'' du userland, qui contient
pour l'instant une seule adresse de fonction, celle
de \verb|eadk_display_draw_string|.
\end{itemize}
Exemple avec le header du userland 23.2.3 (dernière version dont le
source est public au 2/11/2025) pour N0120:
\begin{verbatim}
00020000   FE ED C0 DE  32 33 2E 32  2E 33 00 00  9C 77 00 24  ....23.2.3...w.$
00020010   00 A8 00 00  00 00 19 90  00 00 3F 90  40 2A 01 24  ..........?.@*.$
00020020   00 70 03 24  00 00 3F 90  00 04 3F 90  FE ED C0 DE  .p.$..?...?.....
00020030   F8 EF 03 24  61 6D 08 90  55 96 10 90  00 00 00 00  ...$am..U.......
\end{verbatim}
et le fichier \verb|ram.ld| associé~:
\begin{verbatim}
MEMORY {
  FLASH (rx) : ORIGIN = 0x90190000, LENGTH = 0x260000
  RAM (rwx) : ORIGIN = 0x24012a40, LENGTH = 0x245c0
}

_userland_trampoline_address = 0x90109655;
\end{verbatim}
Pour la version 22.2.1, on obtient un début de RAM en 0x240129a8,
le fichier pour la 23.2.3 conviendrait donc pour la 22.2.1, il est
tr\`es l\'eg\`erement sous-optimal d'une centaine d'octets. On peut donc
mutualiser les lanceurs, sous r\'eserve que le 1er secteur des
applications flash soit identique et qu'on n'utilise pas la variable
\verb|_userland_trampoline_address|, mais qu'on code la recherche,
ce qui est fait dans le fichier \verb|eadk_userland.c|.

Voici une liste de secteurs, adresse de début de RAM et longueurs~:
\begin{itemize}
\item N0110/115~:
\begin{itemize}
\item $\varepsilon$19: secteur 15, ORIGIN = 0x20014a9c, LENGTH = 0x22564
\item $\varepsilon$20: secteur 17, ORIGIN = 0x200148b4, LENGTH = 0x2274c
\item $\varepsilon$21 : secteur 18, ORIGIN = 0x20014798, LENGTH = 0x22868
\item $\varepsilon$22 : secteur 18, ORIGIN = 0x200129a8, LENGTH = 0x24658
\item $\varepsilon$23: secteur 19, ORIGIN = 0x20012a40, LENGTH = 0x245c0
\item $\varepsilon$24.5 à 24.8: secteur 17, ORIGIN = 0x20012804, LENGTH = 0x247fc (attention la 24.1 laisse beaucoup moins de place~:LENGTH = 0x1fbc8)
\end{itemize}
\item N0120~:
\begin{itemize}
\item $\varepsilon$20: secteur 18, ORIGIN = 0x2401490c, LENGTH = 0x226f4
\item $\varepsilon$21: secteur 19, ORIGIN = 0x24014798, LENGTH = 0x22868
\item $\varepsilon$22: secteur 19, ORIGIN = 0x240129a8, LENGTH = 0x24658
\item $\varepsilon$23: secteur 19, ORIGIN = 0x20012a40, LENGTH = 0x245c0
\item $\varepsilon$24: secteur 17, ORIGIN = 0x24012804, LENGTH = 0x247fc
(attention la 24.1 laisse beaucoup moins de place~:LENGTH = 0x1fbc8)
\end{itemize}
\end{itemize}
Si on n'a pas besoin de toute la mémoire disponible,
on peut utiliser une configuration mémoire RAM
\verb|ram120.ld| quasi-universelle (jusqu'à présent), 
et juste changer l'origine~: 
\begin{verbatim}
MEMORY {
  FLASH (rx) : ORIGIN = 0x90180000, LENGTH = 0x270000
  RAM (rwx) : ORIGIN = 0x2401490c, LENGTH = 0x226f4
}
\end{verbatim}
et pour les n0110/n0115
\begin{verbatim}
MEMORY {
  FLASH (rx) : ORIGIN = 0x90150000, LENGTH = 0x2a0000
  RAM (rwx) : ORIGIN = 0x20014a9c, LENGTH = 0x22564
}
\end{verbatim}
On observe au passage que la version 24 \'economise 2 secteurs de
flash par rapport \`a la version 23, le moteur de calcul a \'et\'e
recod\'e pour tenir dans la ROM de la Numworks scientifique coll\`ege, 
en gagnant environ 140K de code.

Et pour finir trois exemples~:
\begin{itemize}
\item
L'\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/simple.zip}{archive simple} contient un exemple d'application externe très simple
et deux programmes pour constituer ce fichier
\verb|ram.ld|, le premier \verb|addr.cc| s'utilise en connectant
la calculatrice cible, le second \verb|binaddr.cc| s'utilise
avec une image binaire du firmware en slot A. Utilisez l'un des
deux, puis faites \verb|make clean| et \verb|make|
pour compiler puis \verb|./sendapp|
pour envoyer l'application sur la calculatrice avec dfu-utils.
\item
L'application externe
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/run.zip}{run}
permet d'exécuter un firmware tiers dans le même slot que
le firmware officiel Numworks,
ce qui laisse plus de place contigüe pour un gros programme comme 
$\chi$CAS (qui occupe tout le slot B) 
\item l'application externe
\ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/numworks/lanceur.zip}{lanceur de $\chi$CAS}
illustre la possibilit\'e d'utiliser une API compatible avec les
applications externes des Numworks d\'everrouill\'ees. 
Cette application donne le controle au point d'entr\'ee lu \`a
l'adresse 0x90400200 (d\'ebut du slot B apr\`es le tar header), 
en passant en param\`etres
le m\^eme tableau de pointeurs, ainsi que l'adresse de d\'ebut
pour le tas m\'emoire et la taille du tas.
Elle montre \'egalement la possibilit\'e d'authentifier le slot B en 
testant une signature RSA
2048 bits, que l'on peut inscrire en filigrane dans le tar header
au d\'ebut du slot B.
\end{itemize}

\appendix

\section{Opinions}
\subsection{Quelques mots sur les calculatrices.}
La calculatrice est devenue incontournable dans les enseignements
de math\'ematique
au lyc\'ee, avec trop souvent une utilisation presse-boutons,
alors qu'elle est sous-utilis\'ee dans les \'etudes
scientifiques, partiellement en r\'eaction. De ce fait,
les constructeurs mettent l'accent sur le d\'eveloppement
de fonctionnalit\'es pour le lyc\'ee, en faisant apprendre
des s\'equences de touches \`a effectuer pour certaines
taches bien pr\'ecises, plutot qu'une m\'ethode
plus g\'en\'erale, un peu moins conviviale pour ces taches,
mais plus adaptable.
C'est par exemple ce qu'on retrouve dans la philosophie
des applications de Numworks, si on veut effectuer une tache
pour laquelle elles sont pr\'evues, c'est facile et en g\'en\'eral
intuitif, mais il
devient vite difficile de faire quelque chose qui n'est pas pr\'evu
(par exemple simuler des donn\'ees avec un programme et les utiliser
dans une des applis de statistiques, repr\'esenter graphiquement
une fonction d\'efinie par un programme, utiliser dans Calculs ou
dans Python
certaines fonctions des applications probabilit\'e ou statistiques, ...).

Je pense que ce n'est pas adapt\'e pour
les \'el\`eves qui doivent pouvoir exp\'erimenter
des choses que le constructeur n'a pas impl\'ement\'e parce
que cela ne correspond pas aux programmes (c'est particuli\`erement
vrai pour les bons \'el\`eves si on ne veut pas qu'ils s'ennuient!).
\`A court terme,
c'est plus facile pour enseigner d'utiliser une application
comme Fonctions, mais \`a long terme, c'est plus formateur
pour de futurs \'etudiants (au moins en sciences et en maths)
d'apprendre \`a utiliser un shell puissant en y tapant des 
commandes (N.B.~: on peut d'ailleurs s\'erieusement se demander 
\`a quoi cela rime d'apprendre un peu de programmation en Python
sans avoir au pr\'ealable un minimum de maitrise dans l'\'ecriture 
d'une ligne de commande simple).
Bien sur, les deux approches doivent se compl\'eter.
Or les \'el\`eves sont souvent tributaires du choix de mod\`ele
demand\'e par leur enseignant de seconde, ils n'ont pas encore
de recul pour choisir un autre mod\`ele que celui
demand\'e par l'enseignant et comprendre toutes
les cons\'equences du choix, en particulier si la calculatrice
ne permet pas d'y installer ou/et utiliser un shell puissant.
Il est donc important de pouvoir proposer pour le plus possible
de mod\`eles populaires une alternative \`a la calculatrice
officielle, permettant aussi aux bons \'el\`eves d'exploiter
toutes les possibilit\'es de leur calculatrice et
de favoriser leur curiosit\'e. Pour moi, une calculatrice qui
fait aimer les maths, c'est une calculatrice qui va donner envie \`a un
\'el\`eve d'exp\'erimenter sur sa calculatrice des questions
en prolongement du programme scolaire. \`A cot\'e 
d'applications intuitives, il faut un espace de libert\'e
qui ne soit pas limit\'e aux quelques fonctionnalit\'es d'une
interface d'application. C'est le
sens de $\chi$CAS, pour Numworks ici, disponible \'egalement
pour d'autres mod\`eles
(Casio Graph 90/35eii, TI Nspire).

Il faut aussi que les enseignants qui 
conseillent un mod\`ele de calculatrices en seconde prennent bien
conscience que le choix ne se limite pas \`a une utilisation pendant
une ann\'ee ou m\^eme pendant les 3 ann\'ees de lyc\'ee mais 
impacte toutes les ann\'ees d'\'etudes, en particulier pour les
\'el\`eves bons en sciences et en maths. La Numworks non verrouill\'ee
r\'ealise d'une certaine mani\`ere un bon \'equilibre 
entre la facilit\'e d'utilisation pour tous en seconde
(Epsilon 15 ici) et les
possibilit\'es ensuite pour les bons \'el\`eves qui auront des maths
ensuite ($\chi$CAS ici). Mais le passage \`a une version plus
r\'ecente d'Espilon casse cet \'equilibre, un enseignant soucieux de ses
bons \'el\`eves devrait les mettre en garde pour qu'ils ne mettent
pas \`a jour!

\subsection{Mes relations compliquées avec Numworks.}
C'est en mai 2016 que j'ai entendu parler pour la premi\`ere fois de
Numworks. Romain Goyet, qui d\'emarrait son projet, m'a contact\'e
pour me sonder un peu dans le domaine des calculatrices. La
recommandation principale que je lui avais faite \'etait la suivante~:
il ne faut pas chercher \`a faire des \'economies sur la m\'emoire,
car on le regrette. Ensuite, je n'ai plus eu aucune nouvelle
avant d'apprendre par tiplanet le lancement de la calculatrice en aout
2017, en particulier je n'ai pas particip\'e au programme de
beta-tests. Cette attitude a
sans doute contribu\'e \`a ce que j'exprime sans retenue 
mon scepticisme vis-\`a-vis
de la Numworks dans plusieurs posts sur tiplanet~: \`a propos
de la m\'emoire, des fonctionnalit\'es et de la communication
\`a mon avis trompeuse sur le caract\`ere open-source. Ce qui m'a sans doute
valu d'\^etre consid\'er\'e comme un anti-Numworks par Goyet, alors
que l'accueil du reste de la communaut\'e \'etait \`a l'\'epoque
tr\`es (trop?) enthousiaste. Mais
je ne regrette pas du tout d'avoir exprim\'e publiquement mes
r\'eserves, si tout le monde \'etait rest\'e sans rien dire, il n'y
aurait pas eu de changement dans la licence d'Epsilon, et les firmwares
Omega, Upsilon, Delta (et Khi leur h\'eritier direct) n'auraient pas pu exister.

Je ne sais pas si ma recommandation de 2016 sur la m\'emoire a eu un quelconque effet,
peut-\^etre que sans elle, les premi\`eres Numworks auraient encore
eu moins de m\'emoire. En tout cas, la m\'emoire disponible
\'etait et reste encore vraiment tr\`es limit\'ee, m\^eme s'il y a eu
un progr\`es pour le stockage en flash avec le passage de 1M \`a 8M
en 2019, probablement parce que Numworks s'est rendu compte que la taille
des firmwares successifs atteindrait plus vite que pr\'evu la taille
de 1M. Il me semble qu'il y aurait des marges de progression peu
on\'ereuses sur la RAM. Et je continue \`a penser que Numworks a perdu et perd
toujours beaucoup de temps de d\'eveloppement avec la gestion de la
tr\`es faible quantit\'e de RAM (256K).

 Les relations avec
Numworks se sont ensuite am\'elior\'ees en 2018, lors
d'une rencontre \`a l'APMEP de Bordeaux,
o\`u je leur avais montr\'e mon module de tortue logo sur les
calculatrices Casio (J.B. Boric avait aussi implement\'e un module
turtle pour la Numworks). Numworks comprend alors l'int\'er\^et d'avoir
un module officiellement support\'e pour faire la transition
avec le coll\`ege. \`A cette occasion, ils me donnent une
N0100. J'appr\'ecie le geste, m\^eme si je n'en ai pas l'usage
pour y porter Giac (\`a cette \'epoque, 
Damien Nicolet, alias zardam, avait r\'eussi \`a porter Giac 
sur sa Numworks N0100 mais en modifiant le hardware ce dont
je suis personnellement incapable).
En mai 2019, Numworks me contacte
pour me proposer de signer un accord de confidentialit\'e, ce que
j'interpr\`ete comme le signe qu'un nouveau mod\`ele allait sortir
permettant de porter Giac (sans modification hardware). Mais certaines
clauses de l'accord ne me convenaient pas~: je voulais m'assurer que
rien n'entrave le d\'eveloppement de Giac/Xcas. Numworks refusant de
modifier les clauses en question, je ne signe pas l'accord de
confidentialit\'e. Le nouveau mod\`ele de Numworks (N0110) est annonc\'e
deux mois plus tard, et j'en ach\`ete un. \`A la rentr\'ee 2019, avec
l'aide de J.B. Boric et Damien Nicolet,
j'arrive \`a faire tourner sur ma N0110
un prototype logiciel qui permet d'utilise le moteur de calcul de Giac dans l'appli
Calculs. Se pose alors la question de l'incompatibilit\'e des licences
entre Giac sous licence GPL et Epsilon, qui n'est pas un logiciel
libre. Mais Numworks est inflexible sur la licence d'Epsilon. Ce qui
conduit Damien Nicolet \`a d\'evelopper un syst\`eme permettant
de compiler deux firmwares \`a installer s\'epar\'ement, l'un
d\'eriv\'e d'Epsilon (sous sa licence) et l'autre sous licence
GPL (le deuxi\`eme sera remplac\'e plus tard par la gestion des
applications externes dans Delta/Omega/Upsilon/Khi). En novembre 2019,
nous informons Numworks de ce succ\`es et leur demandons
s'ils voient encore des probl\`emes juridiques. Fin 2019, n'ayant pas re\c{c}u de r\'eponse,
nous publions alors la premi\`ere version de Delta/$\chi$CAS.
Je n'ai pas de statistiques du nombre de personnes qui ont install\'e
$\chi$CAS sur leur Numworks, j'ai par contre le nombre de personnes qui
ont consult\'e la documentation, pour l'ann\'ee 2020/21 cela d\'epasse
un peu les 5000 et pour 2021/22 on d\'epasse les 9000, 
ce qui n'est pas n\'egligeable du tout compar\'e aux
chiffres de ventes estim\'es. Pour l'année 2023, on est encore
un peu au-dessus de 8000, alors qu'il devient de plus en plus
difficile de se procurer une Numworks non verrouillée.

En 2017/2018, les ventes de calculatrices Numworks en France
ont du \^etre confidentielles~: avec une sortie fin aout 2017, ce ne
sont pas des scolaires qui ont achet\'e, uniquement des
passion\'es et des profs (avec le soutien de L. Ch\'eno de l'inspection
g\'en\'erale). En 2018/19, quelques profs 
enthousiastes (en particulier par le module de programmation en Python)
ont commenc\'e \`a recommander la Numworks \`a
leurs \'el\`eves, mais les ventes \'etaient certainement encore
faibles (j'estime \`a quelques milliers d'unit\'es). Le succ\`es en France s'est dessin\'e \`a la
rentr\'ee 2019 (j'estime qu'ils ont vendu 10 \`a 15 000 calculatrices en
2019/20) et encore plus en 2020 (probablement le double).
\`A la rentr\'ee 2022, j'estime que Numworks poss\`ede environ la moiti\'e
du march\'e des calculatrices couleurs avec de l'ordre de
40 000 calculatrices vendues par an.
Je pense que c'est en voyant
les ventes d\'ecoller \`a la rentr\'ee 2019, que Numworks a d\'ecid\'e de
tourner le dos  au calcul formel sur leurs
calculatrices, par crainte de ne pas pouvoir se d\'evelopper \`a
l'\'etranger, alors qu'en mai 2019, ils envisagaient encore la chose
en se disant que cela pouvait aider \`a booster les ventes en France
(sinon ils ne m'auraient pas propos\'e de signer un accord de
confidentialit\'e). Ils ont d\^u \^etre tr\`es d\'esagr\'eablement
surpris de la solution technique r\'ealis\'ee par zardam (et qui est
sans \'equivalent de leur cot\'e \`a ce jour!), alors qu'ils
esp\'eraient sans doute pouvoir bloquer la diffusion par des questions de licence.
La suite n'a fait que confirmer cette tendance~: ils ont commenc\'e par
cacher les
(maigres) capacit\'es de calcul symbolique d'Epsilon (on peut
les retrouver dans Omega et Khi), puis d\'ecid\'e de verrouiller
leurs calculatrices et modifi\'e la licence d'Epsilon. 

En 2023, les chiffres de vente d'amazon sont disponibles, on peut estimer
les ventes (probablement mondiales) à 30 000 unités via ce distributeur.
Pas d'estimations aussi précise sur les autres canaux de vente, 
on sait juste qu'à la rentrée 2023 la TI83
et la Numworks se disputaient la 1ère place à la fnac. Probablement
un peu plus de 80 000 unités vendues dans le monde en 2023, dont au moins
4/5èmes en France, 
et des parts de marché qui continuent à progresser en France, précipitant
l'annonce par Casio de nouveaux modèles de calculatrices graphiques
pour la rentrée 2024 en France. 

L'objectif de Numworks,
c'est maintenant le march\'e am\'ericain. 
On verra si ils r\'eussissent aussi bien
qu'en France, o\`u les conditions \'etaient bien plus favorables~:
maintenant ils ne peuvent plus communiquer sur l'open-source,
le chauvinisme ne va pas dans le bon sens (vis-\`a-vis de Texas
Instruments en particulier) et il n'y a probablement pas
d'\'equivalent \`a un inspecteur g\'en\'eral
qui vous soutient parce que vous allez dans le sens de sa r\'eforme Python.
Pour le moment, le décollage aux US semble plus lent qu'anticipé par Numworks.
C'est un pari pour Numworks, sans compter que TI est sans doute vaccin\'e par ce
qui s'est pass\'e en France. Le choix fait par Numworks
risque d'\^etre perdant-perdant~: malgr\'e sa faible m\'emoire, la
N0110 est (je devrais plut\^ot dire \'etait) une calculatrice avec un excellent
rapport qualit\'e-prix pour installer $\chi$CAS (avec Xcas en
parall\`ele), et cot\'e Numworks, $\chi$CAS ouvrait le march\'e
fran\c{c}ais des BTS et pr\'epas scientifiques, et aux USA des tests
autorisant le calcul formel.

En conclusion, c'est quand m\^eme dommage de ne pas chercher
une solution qui permette aux élèves français équipés de Numworks
de ne pas être défavorisés par rapport à ceux équipés de modèles
CAS haut de gamme (TI Nspire CX2, HP Prime ou Casio Classpad), 
il y a pas mal de possibilités techniques (par
exemple avoir deux mod\`eles de calculatrices, avoir plusieurs modes
examens, signer $\chi$CAS pour la France...). Il est
d'ailleurs assez
symptomatique que Numworks ait discut\'e du verrouillage pendant plusieurs mois
avec beaucoup de monde dans la communaut\'e ... mais jamais avec moi!

\subsection{D\'evelopper pour Epsilon/Omega/Upsilon vs Giac/$\chi$CAS~: une querelle ancien-moderne?}
Epsilon (et ses d\'eriv\'es) est \'ecrit en C++ 
en utilisant des fonctionnalit\'es
avanc\'ees du langage, il est difficile de naviguer dans le code
source avec des \'editeurs comme emacs (il y a beaucoup de petits
fichiers sources avec des arborescences profondes et des espaces
de noms imbriqu\'es) et pour compiler il faut une version
r\'ecente de gcc (9). Giac est aussi \'ecrit en C++ mais en fait c'est un
style tr\`es proche du C, imp\'eratif, avec des noms de fonction
courts, peu de fichiers sources dans un m\^eme r\'epertoire
et on peut compiler avec des versions anciennes de gcc (4).

Epsilon n'utilise pas les librairies standards (libc, libstdc++) 
contrairement \`a Giac. Il n'y a pratiquement pas de m\'emoire
sur le tas pour allouer des structures de donn\'ees avec malloc ou
new. Je pense que ce choix, li\'e aux faibles capacit\'es m\'emoire
de la calculatrice, a fait et fait perdre pas mal de temps de
d\'eveloppement, d'abord parce que dans les premi\`eres versions
 Epsilon utilisait le tas, ils a fallu r\'e\'ecrire ensuite autrement,
 ensuite parce qu'ils doivent rajouter manuellement des algorithmes
standard des librairies standards lorsqu'ils en ont besoin, enfin
parce que l'architecture du syst\`eme est beaucoup plus complexe. 

La complexit\'e est parfois n\'ecessaire, mais si on se laisse
fasciner, on risque d'oublier l'objectif ou/et coder de mani\`ere
inefficace ou renoncer devant des objectifs plus difficiles. 
Et surtout la marche est haute pour commencer \`a 
d\'evelopper~: ici il faut s'approprier une architecture
complexe et compiler un firmware complet,
voir par exemple
\ahref{https://www.codingame.com/playgrounds/55846/reader-faire-une-application-pour-omega-sur-numworks/introduction}{un
  tutoriel ici}. Tr\`es bien fait, mais on est d\'ej\`a bien fatigu\'e
avant d'avoir pu \'ecrire un algorithme un peu original! Pas \'etonnant
finalement qu'il n'y ait que deux applications Omega (RPN et Atomic)
qui ne sont pas de Numworks (trois si on y ajoute External qui permet
d'utiliser $\chi$CAS, un \'editeur hexa, des jeux), alors
que les sources de l'OS sont disponibles depuis 5 ans.
Upsilon, un fork du projet Omega, est de mon point de vue
un peu meilleur sur cet aspect de développement original, avec
une application liseuse de fichiers texte (support partiel de commandes
LaTeX) et un support de MicroPython plus récent que celui
de Numworks et avec des modules scientifiques complémentaires.
On peut aussi observer que ni Epsilon ni ses forks ne proposent de tableur,
plus de 5 ans apr\`es la sortie de la premi\`ere version d'Epsilon.
(alors qu'il existait plusieurs tableurs d\'evelopp\'es par la
communaut\'e pour
les HP48 il y a 25 ans, bien sur, avec une interface plus rudimentaire,
mais fonctionnels). Il y a des centaines de programmes disponibles
pour les calculatrices concurrentes avec des communautés assez actives,
on ne peut pas dire que c'est le cas pour la Numworks, l'activité
récente de Omega et Upsilon consiste essentiellement à rester compatible
avec les protections des dernières versions d'Epsilon.

On verra s'il y a d'autres d\'eveloppeurs qui se
lancent pour cr\'eer des applications externes avec ce que propose Epsilon
16 ou supérieur,
mais le squelette d'application exemple est aussi relativement complexe,
cf. \ahref{https://github.com/numworks/epsilon-sample-app-cpp}{l'exemple},
avec 21 fichiers sources pour 773 lignes de code.
On peut comparer avec les exemples d'applications additionnelles
dans $\chi$CAS de complexit\'e croissante, allant de la suite de
Syracuse (25 lignes) \`a la fractale de
Mandelbrot (29 lignes), au mastermind (132 lignes) ou au tableau
p\'eriodique (environ 400 lignes) jusqu'au tableur (un peu plus de
1000 lignes), le tout dans un ou deux fichiers source (kadd.cc, 
kdisplay.cc pour le tableau p\'eriodique).

Comme je l'\'ecrivais en titre, c'est peut-\^etre une querelle
ancien-moderne. Mais peut-\^etre aussi une question de culture.
Le matheux que je suis voit vraiment l'informatique comme un outil
pour calculer, et \'ecrire des algorithmes, en g\'en\'eral en lien
avec les maths. \'Ecrire du code d'interface ne m'int\'eresse pas, je
le fais par obligation. L'inverse est certainement vrai pour beaucoup
de passion\'es d'informatique, en tout cas c'est mon impression
quand j'enseigne les maths en parcours informatique ou quand 
j'\'echange sur les forums. Lorsque Numworks dit que sa calculatrice
va faire aimer les maths, cela n'a absolument pas le m\^eme sens
pour eux que pour moi. Pour eux, cela veut visiblement dire proposer
une belle interface qui donne aux \'el\`eves avec le moins d'effort
possible les r\'eponses aux probl\`emes types de maths donn\'es au lyc\'ee.
Alors que moi je souhaite rendre les \'el\`eves autonomes pour
\^etre capable de r\'esoudre des probl\`emes en-dehors des exercices
types de lyc\'ee, et 
donner aux \'el\`eves motiv\'es l'envie d'aller
au-del\`a des programmes scolaires en utilisant toute la puissance
de calcul \`a leur disposition sur la calculatrice pour explorer.
Malheureusement, j'ai l'impression que de moins en moins
de gens sont de mon avis, y compris chez certains profs de maths.
La principale raison \`a mon avis, c'est le d\'eclassement
du m\'etier de prof, qui a conduit \`a une crise de recrutement,
et un niveau moyen en maths des \'etudiants au capes de plus en plus
faible. Parall\`element, le mauvais usage des outils de calcul (en
presse-boutons) conduit \`a une contre-r\'eaction hostile parmi
les profs de maths qui sont bons dans leur discipline.

Il y a aussi une controverse sur les outils de d\'eveloppement et collaboration.
L'outil de synchronisation \`a la mode aujourd'hui est \verb|git| avec un 
h\'ebergement sur \verb|github| et les jeunes ne jurent que par
Discord. Personnellement,
je travaille essentiellement seul et j'ai l'habitude d'utiliser des 
archives tar pour mes sauvegardes.
Pour collaborer, j'ai l'habitude d'utiliser \verb|svn|, que je trouve
plus simple pour faire un commit que \verb|git| (une \'etape et pas
deux). Je n'aime pas du tout l'id\'ee d'h\'eberger des projets sur
\verb|github|, cela donne trop de controle \`a l'h\'ebergeur
(Microsoft ici) et c'est aussi bien trop centralis\'e \`a mon gout
(le contraire
de ce qui a donn\'e naissance \`a Internet), sans compter
que le cout en ressources doit \^etre gigantesque.
Si d'autres d\'eveloppeurs le font, je respecte leur choix, 
et je consulte ou utilise du code source ind\'ependamment de
la fa\c{c}on dont il est produit et publié, ce qui importe c'est le code
lui-m\^eme.
Je n'ai jamais essay\'e Discord et je n'ai pas
l'intention d'essayer, c'est peut-\^etre
tr\`es convivial en particulier pour de la communication synchrone, 
mais c'est du logiciel propri\'etaire sur
lequel on n'a aucun controle alors qu'il y a des logiciels libres 
qui permettent de g\'erer des forums, o\`u on discute
de mani\`ere asynchrone  ce qui de plus me convient mieux.
Bref, je ne vois pas au nom de quoi github+discord devrait \^etre la seule et
unique fa\c{c}on de d\'evelopper et collaborer, surtout que cela pourrait
\^etre remplac\'e par d'autres outils dans quelques ann\'ees
(comme cvs par svn puis git, ou SourceForge). Il y a une forme
d'int\'egrisme dans l'usage de l'outil informatique chez certains
(y compris au plus haut niveau de l'\'education nationale avec
l'imposition de Python comme unique langage de programmation 
au lyc\'ee),
qui devient un peu comme une religion. 
Il serait souhaitable je pense qu'il y ait plus
de tol\'erance, la diversit\'e est une richesse.

Je travaille depuis 24 ans
sur Giac et je programme du calcul formel depuis 30 ans,
au d\'ebut le web n'existait m\^eme pas, les \'echanges se faisaient
via des newsgroup et des serveurs ftp. Je ne suis sur aucun r\'eseau
social, ni sur des syst\`emes d'\'echange synchrones 
et je n'en vois pas trop l'int\'er\^et, la consultation
asynchrone de forums et d'emails me semble bien plus appropri\'e, on
est dans sa bulle quand on code et on ne se laisse pas distraire 
par des notifications. Je ne me pr\'ecipite pas sur la derni\`ere
mise \`a jour ou la derni\`ere nouveaut\'e, j'ai appris \`a mes d\'epens 
que quand quelque chose marche, il faut y r\'efl\'echir \`a deux
fois avant de le modifier (et bien conserver une sauvegarde de 
ce qui marchait). J'ai aussi appris que le monde est complexe, il m'a fallu
parfois plusieurs mois pour porter Giac et ses d\'ependances 
sur une calculatrice. Les
erreurs de compilation ou d'\'edition de liens lors d'un nouveau portage 
sont normales et se comptent souvent par centaines. Si on ne travaille
que sur des petits projets ou des projets r\'ecents, on risque de prendre
des habitudes de confort o\`u tout marche du premier coup et 
de renoncer \`a la premi\`ere difficult\'e.


%% \section{Si vous avez mis \`a jour vers Epsilon 16 sans en connaitre
%%   les cons\'equences.}
%% \label{sec:appendix}

%% Une faille du syst\`eme de verrouillage a \'et\'e d\'ecouverte par
%% M4x1m3,
%% {\bf il est donc temporairement possible \`a la date du 27 mars 2022
%% de d\'everrouiller votre calculatrice si elle est verrouill\'ee,
%% rendez-vous \ahref{https://phi.getomega.dev/}{ici}}. Numworks a combl\'e
%% cette faille le 28 mars, si vous avez mis \`a jour apr\`es, 
%% la faille ne fonctionnera plus pour vous, je vous invite \`a lire le reste de cette section.

%% Remarque pr\'eliminaire~: je ne suis pas juriste, et de toutes
%% fa\c{c}ons le droit est soumis \`a des interpr\'etations, contrairement
%% \`a la preuve d'un th\'eor\`eme math\'ematique. N\'eanmoins, j'ai pas mal
%% \'etudi\'e les questions juridiques li\'ees aux logiciels, j'en ai
%% discut\'e et jusqu'\`a pr\'esent personne n'a contest\'e
%% s\'erieusement cette analyse. Si vous y voyez des erreurs, merci de me
%% les signaler.

%% Si vous avez mis \`a jour vers Epsilon 16 sans en r\'ealiser toutes
%%   les cons\'equences\footnote{Attention, vous n'\^etes pas concern\'e
%%   si vous avez achet\'e une calculatrice qui \'etait pr\'echarg\'ee
%%   avec Epsilon 16}, il vous reste  un recours~: contacter rapidement
%% Numworks et leur demander un moyen
%% technique permettant
%% l'effacement complet de leurs logiciels, i.e. le retour au bootloader de
%% ST (ensuite vous pourrez installer au choix Khi, Omega ou Epsilon 15). Je pense
%% qu'ils n'ont l\'egalement pas le droit de refuser, car pour le moment
%% ils n'affichent aucun avertissement sur le changement de licence du
%% logiciel lors de la mise \`a jour et n'en demandent pas
%% l'approbation. 
%% Voici un argumentaire juridique. 


%% L'utilisation du logiciel de
%% la calculatrice se fait selon un contrat de licence qui lie
%% l'utilisateur \`a l'\'editeur (Numworks). En l'absence d'autre
%% indication\footnote{Contrairement \`a d'autres constructeurs. Par
%%   exemple lors de l'achat d'une TI Nspire CX, j'ai trouv\'e dans le
%%   boitier un contrat de licence imprim\'e intitul\'e ``Les unit\'es Nomades
%%   d'Apprentissage des Math\'ematiques et des Sciences TI-Nspire 3.x,
%%   Licence Individuelle d'Utilisation'' qui reprend des extraits de
%%   lois du code de la propri\'et\'e intellectuelle},
%%  c'est
%% la licence indiqu\'ee sur le site github d'Epsilon qui fait foi, 
%% pour la version 15.5 d'Epsilon ou pour Omega ou Delta 
%% ``NumWorks Epsilon is released under a 
%% \ahref{https://github.com/numworks/epsilon/blob/version-15/LICENSE}{[CC
%%   BY-NC-SA License]}''
%% Pour la version 16, la mention a \'et\'e chang\'ee en ``All rights
%% reserved'' (commit f06b642 le 30 Juillet 2021 par EmilieNumworks). 

%% C'est une diff\'erence fondementale en droit avec les mises \`a jour
%% pr\'ec\'edentes d'Epsilon (ou celles propos\'ees par les constructeurs concurrents).
%% car ce changement de licence logicielle est une modification unilat\'erale
%% du contrat de licence. 
%% \ahref{https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000032041314}{L'article
%%  1193} du code civil stipule que
%% ``Les contrats ne peuvent être modifiés ou révoqués que du
%% consentement mutuel des parties, ou pour les causes que la loi
%% autorise''. Comme il ne s'agit pas ici d'un cas particulier autoris\'e
%% par la loi, Numworks aurait du vous avertir du changement de licence
%% et vous demander d'approuver la modification du contrat (et pour un
%% \'el\`eve mineur, je pense que c'est
%% un repr\'esentant l\'egal qui doit approuver la nouvelle licence). 

%% Or cela n'est pas fait me semble-t-il sur le site de Numworks lors de la
%% mise \`a jour (je n'ai \'evidemment pas test\'e toute la proc\'edure
%% en risquant de voir ma calculatrice mise \`a jour). Rien n'est
%% explicitement indiqu\'e
%% dans la lettre d'information Numletter du 1er Septembre incitant \`a
%% faire cette mise \`a jour 
%% ``Nous vous invitons à installer la dernière mise à jour disponible
%% (version 16) sur votre calculatrice pour profiter de nos
%% nouveautés. Léo vous enverra très prochainement un email pour vous les
%% détailler.'' et dans la lettre du 6 octobre de L\'eo, on a d\'ej\`a \'et\'e
%% invit\'e par trois fois \`a faire la mise \`a jour avant d'avoir un
%% lien sur les changements li\'es \`a la s\'ecurisation.

%% Si Numworks refuse de vous permettre de d\'everrouiller votre calculatrice,
%% en argumentant sur une exigence de s\'ecurit\'e aux examens, vous
%% pouvez contrer l'argument en indiquant que la r\'eglementation
%% n'a pas \'evolu\'e en France\footnote{Et m\^eme si la r\'eglementation
%%   \'evolue,  il y a une hi\'erachie en droit, une loi est prioritaire sur une
%%   r\'eglementation}.
%% De plus, si vous avez install\'e $\chi$CAS,
%% vous pouvez certifier sur
%% \ahref{https://www-fourier.univ-grenoble-alpes.fr/\home{parisse}/nws.html}{cette
%% page} que le firmware install\'e est conforme \`a la r\'eglementation en vigueur en France.

%% Agissez vite, plus le temps passe, plus votre absence de r\'eaction
%% risque d'\^etre interpr\'et\'ee comme une acceptation tacite de la
%% nouvelle licence. Par comparaison, la modification unilatérale par 
%% le fournisseur d’un service de communications est possible dès lors 
%% que l’abonné est informé d’une telle modification et qu’il a la
%% liberté de sortir du contrat, mais il y a un d\'elai pour sortir du
%% contrat. La sortie du contrat de licence signifie ici que l'on doit
%% pouvoir effacer tous les logiciels sous licence avec Numworks, y compris
%% le logiciel de verrouillage, et revenir au bootloader de ST. Pour cela
%% Numworks pourrait publier un mini-firmware sign\'e qui repasse la protection
%% de niveau 1 au niveau 0, ce qui a pour effet d'ex\'ecuter un
%% effacement complet (il est d'ailleurs fort possible que ce
%% mini-firmware existe d\'ej\`a en usage interne chez Numworks).

%% Il ne faut probablement pas s'attendre \`a une r\'eponse positive de
%% Numworks sur un simple email du type ``Je veux retourner en version 15.5'',
%% il faut bien motiver votre courrier. Il faudra peut-\^etre
%% une pression plus importante, \c{c}a peut \^etre un nombre
%% important de courriers (surtout si ce sont des profs qui les
%% \'ecrivent), ou ayant un aspect plus officiel (par exemple
%% courrier d'une association de consommateurs,
%% lettre recommand\'ee avec accus\'e de r\'eception...).
%% Si la pression est suffisamment importante, j'esp\`ere que Numworks
%% r\'ealisera que sa meilleure strat\'egie\footnote{Certainement
%% meilleure que de finir comme
%% \ahref{https://www.playstationlifestyle.net/2016/06/21/sony-closing-in-on-settlement-for-ps3-linux-debacle/}{le
%%   cas de la console PS3/linux}.
%% Si on compare avec ce cas, on peut quantifier la perte de
%% fonctionnalit\'e CAS du verrouillage d'Epsilon 16 en
%% regardant la diff\'erence de prix entre calculatrice
%% non CAS et CAS qui est d'environ 50 euros.
%% } est de permettre aux
%% possesseurs de Numworks N0110 de d\'everrouiller leurs calculatrices,
%% et de vendre \`a destination des USA (et autres march\'es dont
%% ils envisagent la conqu\^ete) un nouveau mod\`ele (disons une N0120)
%% verrouill\'ee d\`es le d\'epart. D'autant plus que du point de vue
%% s\'ecurit\'e c'est une solution bien plus sure. En effet, rien
%% n'emp\^eche un possesseur de Numworks N0110 non verrouill\'ee
%% de simuler ce qu'un surveillant pourra raisonnablement v\'erifier,
%% par exemple le num\'ero de version dans les Param\`etres. Avec un
%% mod\`ele diff\'erent et facile \`a distinguer, il suffit aux pays
%% qui le souhaitent d'autoriser la N0120 et interdire la N0110.

\section{\'Equivalents dans $\chi$CAS de fonctionnalit\'es math\'ematiques
d'Epsilon $\geq$ 16.} \label{sec:eps18}
Dans cette section on explique comment faire avec $\chi$CAS
pour retrouver les fonctionnalit\'es math\'ematiques r\'ecemment
introduites par Numworks dans Epsilon.
En effet $\chi$CAS s'utilise conjointement avec la version 15.5 d'Epsilon
et il n'est pas commode ou pas possible d'installer une version plus 
r\'ecente d'Epsilon en parall\`ele.

\begin{itemize}
\item Epsilon 16: R\'esolution exacte d'\'equations polynomiales de degr\'e 3.\\
Utiliser la commande \verb|solve| (menu rapide shift-2). Par exemple\\
\giacinputmath{solve(x^3-x^2+x-1=0)}\\
Le solveur de $\chi$CAS d\'etermine les solutions rationnelles 
pour toutes les \'equations polynomiales. Il g\`ere aussi certaines
autres \'equations, parfois \`a l'aide de fonctions sp\'eciales,
par exemple\\
\giacinputmath{solve(x-2=ln(x))}
\item Epsilon 17: Coniques.\\
Vous pouvez tracer n'importe quelle conique avec la commande \verb|plot|
(menu rapide shift-3), par exemple\\
\giacinput{plot(x^2+y^2+x*y=4)}\\
Y compris des formes pourtant simples qu'Epsilon ne reconnait pas\\
\giacinput{plot(x^2+x*y=5)}\\
Pour tracer plusieurs graphes simultan\'ement, s\'eparez les commandes de
trac\'e par \verb|;|. Pour donner une couleur \`a un trac\'e, utilisez
un argument optionnel en fin de commande, par exemple\\
\giacinput{p=plot(x^2+y^2+x*y=4,color=red)}\\
Pour d\'eterminer le centre, un foyer et un point sur le grand axe 
de cette ellipse, on peut utiliser la commande
\verb|centre| qui se trouve dans le menu principal (touche Toolbox),
sous-menu G\'eom\'etrie (raccourci $x^2$)\\
\giacinput{centre(p),0}\\
(le \verb|,0| a \'et\'e ajout\'e pour voir les coordonn\'ees des points,
sinon les points sont affich\'es dans un graphique).
La commande \verb|rayon| affiche les valeurs des param\`etres $a,b,c,e$ 
de l'ellipse.
\item Epsilon 17, in\'equations.\\
Pour tracer un graphe d'in\'equation, on utilise aussi la commande
\verb|plot|, par exemple\\
\giacinput{plot(4>x^2+y^2+x*y)}\\
Il est possible de combiner plusieurs in\'equations\\
\giacinput{plot(4>x^2+y^2+x*y and x>y)}\\
On peut bien sur combiner des trac\'es d'in\'equations avec d'autres
trac\'es de graphes (menu Toolbox Courbes) ou g\'eom\'etriques 
(menu Toolbox G\'eom\'etrie), il suffit de taper 
les commandes correspondantes dans une m\^eme ligne
de commande en les s\'eparant par un \verb|;|.
\item Epsilon 17: Pente, \'equation d'une droite\\
Utiliser la commande \verb|slope| ou \verb|equation| ou \verb|parameq|, 
par exemple\\
\giacinput{slope(droite(point(1,2),point(-1,1)))}
\item Epsilon 17: tests statistiques, intervalles de confiance\\
Test du $\chi^2$: \verb|chisquaret|. Taper \verb|chi| puis la touche
fl\`eche vers le bas, puis s\'electionner la commande, vous avez une
description et deux exemples.\\
Autres tests:  Kolmogorov-Smirnov \verb|kolmogorovt| (taper \verb|k|
puis fl\`eche vers le bas, etc.), test Z de la loi normale \verb|normalt|,
test de Student \verb|studentt|.\\
Pour les intervalles de confiance, on peut utiliser les distributions
inverses, le nom de commande est le nom de la loi suivi du suffixe
\verb|_icdf| par exemple \verb|normald_icdf| pour la loi normale\\
\giacinput{normald_icdf(0.975)}
\item Epsilon 18, finances\\
$\chi$CAS dispose d'une application finance, depuis le menu des applications
shift Ans 
\end{itemize}

\end{giacjshere}
\end{document}
