Assembleur

Warning/TODO Renommer ou déplacer cette page. Ce n'est pas l'assembleur lui-même qui est décrit ici, mais le module d'encodage/décodage du source. —YG

Infos

On appelle 'codec' le module qui stocke chaque ligne de texte saisie par l'éditeur et lui les restitue à la demande.
Dans le cas Orgams, c'est la partie qui pré-assemble à la volée. A l'instar de DAMS et autre, cela réduit la place prise par le source et permet de signaler les erreurs de syntaxe (et plus si affinité).
Cela explique que le texte affiché puisse différer de celui saisi (indentation, casse,…).

Le codec doit maintenir son état :

  • house keeping (aka popotte interne) : mémoire utilisée, éventuels index, …

On décrit maintenant les points d'entrées que doit offrir un codec.

Les routines

#ORG = Adresse de chargement du codec. Le saut #ORG+0 est réservé pour usage interne (NRT).

codec_init

Adresse : #ORG+3

In : N/A
Out : N/A

TODO : Mini protocol hand-shake (vérification version, passage de call-backs pour signaux).

Initialise codec : réservation mémoire, initialisation de ses variables et des éventuels index…

codec_get_nb_lines

Adresse : #ORG+6

Non documenté (A FAIRE!)

codec_get_line

Adresse : #ORG+9

Renvoie la ligne demandée sous forme texte (nul-terminated).

In : B = max size (not counting \0, ie B = total max size - 1). Here passing 0 is useless.
DE = line number (from 1 to 65535)
HL = address output buffer
Out:
NC : Si erreur fatale et Carry sinon.
A : status code (Liste des codes d'erreurs)
HL : points on last character (ie \0).
Zero (Z) if no more line (DE_in > # lines)
BC, DE erased.
From HL_in to HL_out (included) : Nul-terminated string.

//Internal state codec updated (must point to next line. Cf codec_get_next_nt_line)

Motivations :

  • max size :
    • évite buffer overflow.
    • évite génération superflue (caractères non affichés quand fenêtre trop étroite)
  • nul-terminated : un \0 sentinel permet des routines d'affichages plus rapides (par économie d'un compteur).
  • client fournissant l'adresse du buffer : le codec devant typiquement générer le texte, autant le faire à un endroit adéquat pour le client (plutôt que d'avoir à effectuer une copie superflue).
  • bad line : indique les lignes qui n'ont pas pu être encodées comme attendu, et qui ont donc été stockées en l'état. A l'éditeur de surligner ces lignes (en grisant ou avec un

========YAGNI YET =============
codec_get_nt_line_from

Renvoie la ligne demandée sous forme texte, à partir du caractère indiqué.
Permet de gérer les lignes trop longues par morceaux.
[pas nécessaire maintenant]

========FIN YAGNI YET =========

codec_set_line

Adresse : #ORG+12

Change une ligne déjà existante.

In :
DE = numéro ligne (de 1 à 65535)
HL = pointe sur ligne à encoder (terminée par \0)
Out :
NC : Si erreur fatale et Carry sinon.
A : status_code (Liste des codes d'erreurs)
HL : points on last character (ie \0).
A, BC, DE erased.

codec_insert_line

Adresse : #ORG+15

Insert une nouvelle ligne "par dessus" celle indiquée : si on indique la ligne n, l'actuelle ligne n passera en n+1 (Choix nécessaire pour insérer des lignes en tête).

In :
DE = numéro ligne (de 1 à 65535)
HL = pointe sur ligne à encoder (terminée par \0)
Out :
NC : Si erreur fatale et Carry sinon.
A : status_code (Liste des codes d'erreurs)
HL : points on last character (ie \0).
A, BC, DE erased.

codec_del_line

Adresse : #ORG+18

Supprime une ligne dans le source.

In :
DE = le numéro de la ligne à supprimer
Out :
NC : Si erreur fatale et Carry sinon.
A : status_code (Liste des codes d'erreurs) ?? TODO à vérifier !
DE erased. TODO à vérifier !!

codec_get_status_message

Adresse : #ORG+??

In :
DE = numéro ligne (de 1 à 65535)
Out :
HL = pointe sur message (\0 terminated). Multi-lignes ?

Motivation :

  • Pourquoi une routine à part ?
    • Plus efficace : le codec ne générera un status que s'il est explicitement demandé (typiquement : lors de la saisie, mais pas lors de l'affichage d'une page)
    • Cela décompose un dialogue qui serait lourd à interfacer en opérations plus élémentaires.
  • Pourquoi repréciser le numéro de ligne plutôt que de pendre implicitement la dernière ligne encodée/décodée ?
    • Permet d'obtenir le statut sans avoir à re-décoder ! Par exemple, si on se balade sur les lignes affichées, l'éditeur dispose déjà de la version texte, mais redemande le statut pour la ligne courante.
    • Idéa ?

TODO : Gestion de plusieurs erreurs sur une même ligne ?

codec_cut_bloc [YAGNI]

Adresse : N/A

Pas besoin, se baser sur codec_delete_line.

Enlève n lignes.

Facultatif : le codec garde aux chauds ces n lignes pour un éventuel "copié" subséquent.

TODO : On doit pouvoir demander au codec s'il supporte cette fonctionnalité. Dans le cas contraire, à l'éditeur d'utiliser un coupé/collé générique.

In :
DE = numéro 1ère ligne à effacer (de 1 à 65535)
HL = numéro dernière ligne à effacer (de 1 à 65535)
Out :
A : Status (Liste des codes d'erreurs)

codec_paste_bloc [YAGNI]

Adresse : #ORG+??

Falcultatif pour l'instant

codec_open

Adresse : #ORG+21

Charge une version encodée.

In :
A = ID fichier (pour multi-édition), en commençant par 0.
HL = nom fichier (\0 terminated)
Out :
A : status_code (Liste des codes d'erreurs)
BC, DE, HL erased.

NB :

  • Réutiliser un ID fichier implique la fermeture inconditionnelle de l'ancien. A l'éditeur de prévenir de la perte possible des modifications.
  • Si l'éditeur ne sait gérer qu'un fichier, toujours appeler avec A=0.

codec_save

Adresse : #ORG+24

Sauvegarde la version encodée.

In :
A = ID fichier (pour multi-édition)
HL = nom fichier (\0 terminated)
Out :
A : status_code (Liste des codes d'erreurs)
BC, DE, HL erased.

NB : On doit repréciser le nom du fichier au codec. Cela ne signifie pas que l'utilisateur doive le rentrer à chaque fois (comme sous Dams), mais que la charge de retenir le nom de fichier est confiée à l'éditeur. Il s'agit en effet d'une commodité qui ne dépend pas du codec.

codec_close

Adresse : #ORG+??

Ferme le fichier en cours.

In :
A = numéro fichier (pour multi-édition)
Out :
A : status_code (Liste des codes d'erreurs)

NB : A l'éditeur de prévenir de la perte possible des modifications.

codec_seek_next_label_from_prefix

Adresse : #ORG+36

Renvoi la ligne à laquelle est défini le label décrit par ses premières lettres (case insensitive).
NB : Permet d'implémenter CONTROL-L.

in

  • HL=buffer vers début nom label (Nul Terminated).
  • DE=ligne début recherche.

out

  • Carry, DE = ligne si trouvé
  • Carry, DE = 0 si non trouvé
  • NC si erreur grave (source corrumpu…), A contient code d'erreur.

Utilisation :
La recherche se fait en commençant à la ligne commençant par DE. Pour chercher le prochain label commençant par la même chaîne, l'éditeur devra incrémenter DE !
Le retour NC traduit une confusion totale dans le source. L'éditeur peut alors avertir l'utilisateur ("Source corruption/Orgams bug, try to export and save file") ou faire comme si 0 était renvoyé.

codec_seek_label_from_line

Adresse : #ORG+39

Renvoi la ligne à laquelle est défini le label "sous le curseur". La recherche ici est stricte : si la casse est invalide, le label ne sera pas trouvé.
NB1 : Pour l'instant, si plusieurs labels sur la ligne, ne prend que le dernier quelque soit la position du curseur.
NB2 : Permet d'implémenter CONTROL-ENTER.

in DE=numéro ligne "source" (typiquement : ligne courante)
L=pos X dans ligne.
out comme précédent.

codec_get_label_next_occurence

Renvoi la ligne de prochaine occurence du label "sous le curseur".
NB1 : Pour l'instant, si plusieurs labels sur la ligne, ne prend que le premier quelque soit la position du curseur.
NB2 : Permet d'implémenter CONTROL-*.

in comme codec_get_label_def_from_line
out comme précédemment.

TODO

TODO !!
Mécanisme de signal.
Cas d'usage :

  1. L'assembleur envoi une erreur sur une ligne N à cause d'un label non défini.
  2. L'éditeur signale cette ligne graphiquement (en la grisant, ou via un signe en colonne gauche).
  3. Dix lignes saisies plus tard, on définit le label.

-> Le codec doit donc informer l'éditeur que la ligne N n'est plus affectée d'une erreur.

TODO : codec_get_free_memory, codec_get_main_status ?

Liste des codes d'erreurs

status_code (severity of status_message)
0 : Ok, nothing to say.
1 : Info
2 : Warning
3 : Error : témoigne d'une erreur dans la ligne saisie, qui n'a pas pu être validée et encodée. Elle sera donc stockée en l'état.
4 : Fatal : témoigne d'un problème au run-time (Eg : mémoire pleine -> la ligne n'a pas pu être stockée du tout. Ou encore : erreur chargement fichier)
5 : Assertion Failure : témoigne d'une erreur de programmation (Eg : l'éditeur demande à fermer un fichier qui n'a jamais ouvert)

Ainsi :

  • le niveau 0 ne s'accompagnera d'aucun message.
  • les niveaux 1 à 3 s'accompagneront d'une information (status_message) concernant la ligne entrée (eg, "invalid opcode" dans le cas de l'assembleur).
  • les niveaux 4 et 5 s'accompagneront d'une information concernant l'opération elle-même.

Cette liste ne décrit pas les erreurs d'assemblage, mais les causes possible d'échec d'une opération.

  • 255 Cannot open file.
  • 254 Dos error.
  • 253 Unknown filetype.
  • 252 Unexpected end of file.
  • 251 Memory full. Try Export+Import.
  • 250 Labels table full. Try Export+Import.
  • 249 Checksum mismatch : source corrupted.
  • 248 Unknown token : make sure Orgams is up-to-date.
  • 247 Unexpected mess (memory corruption or bug in Orgams).
  • 246 Buffer overflow.
  • 245 Stack overflow.
  • 244 Invalid line number.
  • 243 Assertion failure.
  • 242 Bad version.
  • 241 No bloc defiined.
  • 240 Cannot copy here.
  • 239 Too many labels. (768 labels max for now)
  • 238 No space left for labels.
  • 237 Empty label (memory corruption or bug in Orgams).
  • 236 Update not supported (memory corruption or bug in Orgams).

Other : Unknown error.

[à compléter]

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License