L'UniDOS est facilement extensible grâce à l'adjonction de nœuds DOS ; la page qui suit vous explique comment développer vos propres nœuds DOS pour la prise en charge de nouvelles cartes d'extensions ou simplement l'ajout de lecteurs virtuels.
L'UniDOS prenant totalement en charge la gestion des chemins, la compatibilité AMSDOS et la gestion des erreurs, le nœuds DOS n'a à s'occuper que des routines de base permettant l'accès aux fichiers, ce qui réduit considérablement la quantité de code à écrire en plus de permettre une intégration complète de tous les périphériques au sein du même DOS.
Un nœud DOS est une ROM tout à fait standard ; vous pouvez vous référer aux documentations traitant du développement des ROMs pour CPC pour plus de détails.
Dès lors, un nœud DOS est donc une ROM de second plan (type 1) ou d'extension (type 2), mais dans laquelle une RSX nommée « DOS Node » doit être déclarée en &C009. De plus, cette RSX doit être suivie de 31 RSX CTRL+0 (&80) qui correspondent aux points d'entrée des diverses routines que le nœud DOS peut implémenter.
Voici donc à quoi doit ressembler l'entête d'une ROM de nœud DOS1) :
Org &c000 ROMType db 2 ; 1 (ROM de second plan) ou 2 (ROM d'extension) ROMMark db 1 ; L'usage veut que la version d'une ROM ROMVer db 4 ; soit affichée sous la forme : M.VR ROMRev db 1 ; (soit 1.41 ici) ROMRSX dw RSXTable jp InitROM jp DOSNode_Init jp DOSNode_CheckDrive jp DOSNode_GetStatus jp DOSNode_GetName jp DOSNode_GetDesc jp DOSNode_GetFreeSpace jp DOSNode_InOpenStream jp DOSNode_InReadStream jp DOSNode_InCloseStream jp DOSNode_InSeekStream jp DOSNode_OutOpenStream jp DOSNode_OutWriteStream jp DOSNode_OutCloseStream jp DOSNode_OutSeekStream jp DOSNode_Examine jp DOSNode_ExamineNext jp DOSNode_Rename jp DOSNode_Delete jp DOSNode_CreateDir jp DOSNode_SetProtection jp DOSNode_Format jp DOSNode_SetFileDate jp DOSNode_Void jp DOSNode_Void jp DOSNode_Void jp DOSNode_ReadRTC jp DOSNode_WriteRTC jp DOSNode_OpenNVRAM jp DOSNode_CloseNVRAM jp DOSNode_ReadNVRAM jp DOSNode_WriteNVRAM jp DOSNode_SeekNVRAM ; Vous pouvez ajouter ici vos RSX personnelles RSXTable str "Nom ROM " str "DOS Node" Repeat 31 db &80 REnd ; Vous pouvez ajouter ici vos RSX personnelles db 0 ; Fin de la table des RSX ; Le code effectif de la ROM commence ici InitROM cp a ret
En pratique, vous créerez une ROM de type 1 si vous souhaitez allouer de la mémoire additionnelle pour la gestion du nœud DOS2). Si vous n'avez pas besoin de mémoire additionnelle, une ROM de type 2 est suffisante3).
Chaque nœud DOS dispose donc de 32 routines (dont 6 sont actuellement non allouées). Libre à vous d'implémenter tout ou partie de ces routines selon vos besoins et les capacités de la carte d'extension pour laquelle vous désirez créer un nœud DOS.
Dans tous les cas, si votre routine est implémentée, elle doit mettre à la Carry à 1 en retour ; une Carry à 0 indique à l'UniDOS que la routine n'est pas implémentée.
N'hésitez pas à vous référer au code source du nœud « Zero » qui est extrêmement simple (il n'implémente que quelques routines de lecture), ou le nœud « Albireo » pour un exemple de nœud implémentant la quasi totalité des routines.
Vous trouverez ci-après une description des conditions d'entrée et de sortie de chacune des routines à implémenter, ainsi qu'une carte de la mémoire qu'elles ont le droit d'utiliser. Il est impératif que vous respectiez rigoureusement les conditions de sortie de chacune des routines du nœud DOS que vous décidez d'implémenter.
La liste des codes d'erreurs que vous pouvez utiliser ainsi que diverses autres constantes se trouvent dans le fichier « UniDOS.i » disponible dans les sources de l'UniDOS. Vous y trouverez également les fichiers « SystemCalls.i » et « SystemData.i » qui contiennent des définitions utiles (ces fichiers sont destinés à RASM mais devraient être facilement adaptables pour n'importe quel assembleur).
Dans toutes les descriptions qui suivent :
NNNNNNNNEEE
où :NNNNNNNN
est le nom en 8 caractères (éventuellement complétés par des espaces).EEE
est l'extension en 3 caractères (éventuellement complétés par des espaces).n
avec la profondeur du chemin (0 si le chemin est vide, 6 au maximum).n
noms normalisés.Il s'agit d'un jeu de routines que l'UniDOS utilise pour initialiser le nœud DOS et prendre en charge ses lecteurs additionnels. Il est recommandé de toutes les implémeter pour avoir une meilleur intégration de votre nœud DOS dans le système.
Chaque nœud DOS a à sa disposition les 2 octets à l'offset +&18E4). Le contenu de ces deux octets est préservé entre deux appels aux routines du nœud DOS et demeure donc toujours valide. Certaines routines disposent en outre de zones mémoire supplémentaires dédiées à leur gestion interne.
Cette routine est appelée durant la séquence d'initialisation de l'UniDOS, lors de la détection des nœuds DOS présents. C'est le bon endroit pour détecter la présence de la carte d'extension que votre nœud DOS doit gérer et répondre en conséquence.
C'est aussi ici que vous indiquez à l'UniDOS si votre nœud DOS implémente la fonctionnalité de mémoire non volatile ou non.
; ; Initialise le nœud DOS ; ; Entrée - A = options d'initialisation (voir les flags d'entrée de Init_*) ; Sortie - Si Carry = 1 alors le nœud a été initialisé ; A = indication des fonctionnalités présentes (voir les flags de sortie de Init_*) ; Si Carry = 0 alors le nœud n'a pas pu être initialisé ; Altéré - AF
Cette routine sera appelée par l'UniDOS à chaque fois qu'il cherchera à déterminer si un nom de lecteur existe ou pas. Le premier nœud DOS à répondre positivement s'en verra attribué la gestion.
Chaque nœud DOS a droit à 8 lecteurs au maximum, qu'il doit numéroter de 0 à 7.
; ; Vérifie si un nom de lecteur correspond à un lecteur géré par notre nœud DOS ; ; Entrée - HL = pointeur vers le nom de lecteur ; (si positionné sur certains caractères, le bit 7 doit être ignoré) ; C = longueur du nom de lecteur ; Sortie - Si Carry = 1 une correspondance a été trouvée ; A = numéro du lecteur physique ; Si Carry = 0 aucune correspondance n'a été trouvée ; Tous les registres sont préservés ; Altéré - AF
Cette routine est utilisée par l'UniDOS pour déterminer les possibilités liées à un lecteur. En fonction de la valeur retournée l'UniDOS fera des traitements différents. Par exemple, si un lecteur est du type « flux » alors l'UniDOS ne fera pas de gestion des fichiers BAK
et $$$
.
; ; Retourne le statut d'un lecteur ; ; Entrée - A = Numéro de lecteur ; Sortie - Si Carry = 1 un statut a pu être récupéré ; A = Statut du lecteur (voir les flags Media_*) ; Bit0 = 1 si un média est disponible sur ce lecteur ; Bit1 = 1 si le média gère les répertoires ; Bit2 = 1 si le média est protégé en écriture ; Bit3 = 1 si le média est amovible ; Bit4 = 1 si le média est un flux (lecture/écriture linéaire uniquement) ; La gestion des fichiers $$$ et BAK est alors désactivée ; Les autres bits ne sont pas utilisés ; Si Carry = 0 alors le lecteur est inconnu et aucun statut n'a pu être récupéré ; Tous les registres sont préservés ; Altéré - AF
Cette routine est en quelque sorte l'inverse DOSNode_CheckDrive. Elle permet à l'UniDOS de retrouver le nom d'un lecteur en fonction de son identifiant.
; ; Renvoie le nom correspondant à un lecteur physique ; ; Entrée - A = numéro du lecteur ; DE = adresse d'un tampon de 8 octets où copier le nom ; Sortie - Si Carry = 1 le nom a été trouvé ; DE pointe sur le premier caractère après la fin de la copie de la chaîne ; (la chaîne stockée est terminée par le bit 7 à 1) ; Si Carry = 0 le nom n'a pas été trouvé et le tampon n'a pas été modifié ; Tous les registres sont préservés ; Altéré - AF,DE
Cette routine doit retourner une description textuelle correspondant au numéro de lecteur demandé.
; ; Renvoie la description correspondant à un lecteur physique ; ; Entrée - A = numéro du lecteur physique ; DE = adresse d'un tampon de 32 octets où copier la description ; Sortie - Si Carry = 1 une description a été trouvée ; DE pointe sur le premier caractère après la fin de la copie de la chaîne ; (la chaîne stockée est terminée par le bit 7 à 1) ; Si Carry = 0 aucune description n'a pas été trouvée et le tampon n'a pas été modifié ; Tous les registres sont préservés ; Altéré - AF,DE
L'UniDOS appelle cette routine lorsqu'il a besoin de connaître l'espace libre sur un média.
; ; Renvoie l'espace libre sur un lecteur physique ; ; Entrée - A = numéro du lecteur ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors l'espace disponible a pu être obtenu ; BCDE = espace libre en kilo-octets ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF,BC,DE
Conformément à l'AMSDOS, un seul fichier à la fois peut-être ouvert en entrée.
Le nœud DOS dispose de 80 octets à l'offset +&3305) pour la gestion de ce fichier.
; ; Ouvre le flux en entrée ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; note : si le lecteur est de type flux alors ce nom peut ; contenir 11x&ff dans le cas où aucun nom de fichier n'a ; été fourni par l'utilisateur (utilisation de la référence ; de flux anonyme ".") ; la routine est alors censée ouvrir ; le premier fichier rencontré sur le flux et peut en option ; mettre à jour le nom si celui-ci a été obtenu depuis le flux ; DE = pointeur vers le chemin normalisé ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors un fichier a été ouvert ; Si NZ alors aucun fichier n'a été ouvert ; A = code d'erreur ; Dans tous les cas le chemin normalisé a éventuellement été tronqué au plus proche parent ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Lit depuis le flux en entrée ; ; Entrée - A = numéro du lecteur ; HL = adresse où stocker les données lues ; DE = nombre d'octets à lire ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors des données ont pu être lues ; DE = nombre d'octets effectivement lus ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF,DE
; ; Ferme le flux en entrée ; ; Entrée - A = numéro du lecteur ; Sortie - Si Carry = 1 le flux a été fermé ; Si Z alors le flux a été fermé correctement ; Si NZ alors le flix a été fermé avec une erreur ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Change la position dans le flux en entrée ; ; Entrée - A = numéro du lecteur ; DEHL = nouvelle position dans le flux de entrée ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors la nouvelle position a pu être atteinte ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
Conformément à l'AMSDOS, un seul fichier à la fois peut-être ouvert en sortie.
Le nœud DOS dispose de 80 octets à l'offset +&3806) pour la gestion de ce fichier.
; ; Ouvre le flux en sortie ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; DE = pointeur vers le chemin normalisé ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors un fichier a été créé ; Si NZ alors aucun fichier n'a été créé ; A = code d'erreur ; Dans tous les cas le chemin normalisé a éventuellement été tronqué au plus proche parent ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Écrit sur le flux en sortie ; ; Entrée - A = numéro du lecteur ; HL = adresse où se trouvent les données à écrire ; DE = nombre d'octets à écrire ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors des données ont pu être écrites ; DE = nombre d'octets effectivement écrits ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF,DE
; ; Ferme le flux en sortie ; ; Entrée - A = numéro du lecteur ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors le flux a été fermé correctement ; Si NZ alors le fuix a été fermé avec une erreur ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Change la position dans le flux en sortie ; ; Entrée - A = numéro du lecteur ; DEHL = nouvelle position dans le flux en sortie ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors la nouvelle position a pu être atteinte ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
Une seule analyse à la fois peut-être lancée.
Le nœud DOS dispose de 80 octets à l'offset +&3D07) pour la gestion d'analyse des fichiers et répertoires.
; ; Vérifie qu'un fichier ou un répertoire existe et retourne les informations associées ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé de l'entrée ; Si HL = 0 alors l'entrée est un répertoire et on veut analyser sont contenu, ; ExamineNext devra ensuite être appelé pour récupérer les entrées ; DE = pointeur vers le chemin normalisé où se trouve l'entrée ; IX = tampon où copier l'heure et la date de dernière modification de l'entrée (7 octets) ; (inutilisé si HL = 0 ou si l'horodatage n'est pas supporté) ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; ; Si HL ne valait pas 0 en entrée ; Si Z alors le fichier ou le répertoire existe ; A = bits de protection du fichier ; Bit 0 - Lecture seule ; Bit 1 - Caché ; Bit 2 - Système ; Bit 4 = Répertoire ; Bit 5 = Archivé ; BCDE = Taille du fichier ; IX = tampon où ont été copiées l'heure et la date de dernière modification de l'entrée ; (le contenu du tampon reste inchangé si l'horodatage n'est pas supporté) ; Un mot de 16 bits avec l'année (1978..9999) ; Un octet avec le numéro du mois (1..12) ; Un octet avec le numéro du jour dans le mois (1..28,29,30 ou 31) ; Un octet avec les heures (0..23) ; Un octet avec les minutes (0..59) ; Un octet avec les secondes (0..59) ; Si NZ alors le fichier ou le répertoire est introuvable ; A = code d'erreur ; ; Si HL valait 0 en entrée ; Si Z alors le répertoire est prêt à être examiné via ExamineNext ; Si NZ alors une erreur est survenue ; A = code d'erreur ; ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; RÈcupËre une entrÈe dans le rÈpertoire en cours d'examen ; ; Entrée - HL = pointeur vers la mémoire où stocker nom normalisé de l'entrée (11 octets) ; IX = tampon où copier l'heure et la date de dernière modification de l'entrée (7 octets) ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors une entrée a été récupérée ; HL = pointeur vers la mémoire mise à jour avec le nom de l'entrée ; A = bits de protection de l'entrée ; Bit 0 - Lecture seule ; Bit 1 - Caché ; Bit 2 - Système ; Bit 4 = Répertoire ; Bit 5 = Archivé ; BCDE = Taille de l'entrée (indéterminé si l'entrée est un répertoire) ; IX = tampon où ont été copiées l'heure et la date de dernière modification de l'entrée ; (le contenu du tampon reste inchangé si l'horodatage n'est pas supporté) ; Un mot de 16 bits avec l'année (1978..9999) ; Un octet avec le numéro du mois (1..12) ; Un octet avec le numéro du jour dans le mois (1..28,29,30 ou 31) ; Un octet avec les heures (0..23) ; Un octet avec les minutes (0..59) ; Un octet avec les secondes (0..59) ; Si NZ alors une erreur est survenue ; A = code d'erreur (dsk_err_file_not_found indique que toutes les entrées ont été lues) ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
Il s'agit d'un jeu de routines dédiées à renommer, effacer et modifier les fichiers et répertoires.
; ; Renome un fichier ou un répertoire ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; DE = pointeur vers le chemin normalisé ; IX = pointeur vers le nouveau nom normalisé ; BC = pointeur vers le nouveau chemin normalisé ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors le fichier ou le répertoire a été renommé ; Si NZ alors le renommage n'a pas eu lieu ; A = code d'erreur ; Dans tous les cas les chemins normalisés ont éventuellement été tronqué au plus proche parent ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Efface un fichier ou un répertoire ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; DE = pointeur vers le chemin normalisé ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors le fichier ou le répertoire a été supprimé ; Si NZ alors aucune suppression n'a eu lieu ; A = code d'erreur ; Dans tous les cas le chemin normalisé a éventuellement été tronqué au plus proche parent ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Crée un répertoire ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; DE = pointeur vers le chemin normalisé ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors un répertoire a été créé ; Si NZ alors aucun répertoire n'a été créé ; A = code d'erreur ; Dans tous les cas le chemin normalisé a éventuellement été tronqué au plus proche parent ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Change les bits de protection d'un fichier ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; DE = pointeur vers le chemin normalisé ; B = Protections à modifier ; C = Nouvelles protections ; Bit 0 - Lecture seule ; Bit 1 - Caché ; Bit 5 = Archivé ; Les autres bits sont ignorés ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors les protections ont été modifiées ; Si NZ alors les protections n'ont pas pu être modifiées ; A = code d'erreur ; Dans tous les cas le chemin normalisé a éventuellement été tronqué au plus proche parent ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Change la date et l'heure de dernière modification d'un fichier ou d'un répertoire ; ; Entrée - A = numéro du lecteur physique ; HL = pointeur vers le nom normalisé ; DE = pointeur vers le chemin normalisé ; IX = tampon qui contient les informations d'heure et de date à utiliser ; Un mot de 16 bits avec l'année (1978..9999) ; Un octet avec le numéro du mois (1..12) ; Un octet avec le numéro du jour dans le mois (1..28,29,30 ou 31) ; Un octet avec les heures (0..23) ; Un octet avec les minutes (0..59) ; Un octet avec les secondes (0..59) ; La mémoire pointée est dans l'espace ROM/RAM courant ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors l'heure et la date ont été modifiées ; Si NZ alors l'heure et la date n'ont pas pu être modifiées ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Formate un lecteur ; ; Entrée - A = numéro du lecteur physique ; Sortie - Si Carry = 1 la routine est supportée par ce lecteur ; Si Z alors le lecteur a été formaté ; Si NZ alors le formatage a échoue ; A = code d'erreur ; Si Carry = 0 alors la routine est invalide pour ce lecteur ; Tous les registres sont préservés ; Altéré - AF
; ; Lit le contenu de l'horloge temps réel ; ; Entrée - IX = tampon où copier l'heure et la date courantes (7 octets) ; Sortie - Si Carry = 1 alors le nœud DOS offre un service d'horloge temps réel ; IX = le tampon d'entrée où l'heure et la date ont été copiées ; Un mot de 16 bits avec l'année (1978..9999) ; Un octet avec le numéro du mois (1..12) ; Un octet avec le numéro du jour dans le mois (1..28,29,30 ou 31) ; Un octet avec les heures (0..23) ; Un octet avec les minutes (0..59) ; Un octet avec les secondes (0..59) ; A = numéro du jour dans la semaine (1..7, du lundi au dimanche) ; Si Carry = 0 alors le nœud DOS n'offre pas d'horloge temps réel ; Tous les registres sont préservés ; Altéré - AF
; ; Écrit le contenu de l'horloge temps réel ; ; Entrée - IX = tampon qui contient les informations d'heure et de date à utiliser (7 octets) ; Un mot de 16 bits avec l'année (1978..9999) ; Un octet avec le numéro du mois (1..12) ; Un octet avec le numéro du jour dans le mois (1..28,29,30 ou 31) ; Un octet avec les heures (0..23) ; Un octet avec les minutes (0..59) ; Un octet avec les secondes (0..59) ; Sortie - Si Carry = 1 alors le nœud DOS offre un service d'horloge temps réel ; Si Z alors le contenu de l'horloge temps réel a pu être mis à jour ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors le nœud DOS n'offre pas d'horloge temps réel ; Tous les registres sont préservés ; Altéré - AF
Ces routines ne sont à implémenter que si votre nœud DOS supporte la fonctionnalité de mémoire non volatile. Si c'est le cas, la totalité des routines qui suivent doivent être implémentées.
La taille minimale de la mémoire non volatile qu'il est nécessaire de gérer est de 2 Kio.
Le nœud DOS dispose de 6 octets à l'offset +&4F08) pour la gestion de la mémoire non volatile.
; ; Ouvre la mémoire non volative ; ; Entrée - C = mode d'ouverture ; Si 0 alors la mémoire non volatile avec son contenu courant doit être ouverte ; Si 1 alors la mémoire non volatile doit être remise à zéro avant ouverture ; Sortie - Si Carry = 1 alors le nœud DOS offre un service de mémoire non volatile ; Si Z alors la mémoire non volatile a été ouverte est est prête à être manipulée ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors le nœud DOS n'offre pas de mémoire non volatile ; Tous les registres sont préservés ; Altéré - AF
; ; Ferme et met à jour le contenu de la mémoire non volatile ; ; Entrée - Aucune ; Sortie - Si Carry = 1 alors le nœud DOS offre un service de mémoire non volatile ; Si Z alors la mémoire non volatile a été mise à jour ; Si NZ alors une erreur est survenue ; Si Carry = 0 alors le nœud DOS n'offre pas de mémoire non volatile ; Tous les registres sont préservés ; Altéré - AF
; ; Lit des données depuis la mémoire non volatile ; ; Entrée - HL = adresse où écrire les données lues ; DE = nombre d'octets à lire ; Sortie - Si Carry = 1 alors le nœud DOS offre un service de mémoire non volatile ; Si Z alors les données ont été lues ; DE = nombre d'octets effectivement lus ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors le nœud DOS n'offre pas de mémoire non volatile ; Tous les registres sont préservés ; Altéré - AF,DE
; ; Écrit des données dans la mémoire non volatile ; ; Entrée - HL = adresse où se trouvent les données à écrire ; DE = nombre d'octets à écrire ; Sortie - Si Carry = 1 alors le nœud DOS offre un service de mémoire non volatile ; Si Z alors les données ont été écrites ; DE = nombre d'octets effectivement écrits ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors le nœud DOS n'offre pas de mémoire non volatile ; Tous les registres sont préservés ; Altéré - AF,DE
; ; Change la position dans la mémoire non volatile ; ; Entrée - DEHL = nouvelle position ; Sortie - Si Carry = 1 alors le nœud DOS offre un service de mémoire non volatile ; Si Z alors la nouvelle position a pu être atteinte ; Si NZ alors une erreur est survenue ; A = code d'erreur ; Si Carry = 0 alors le nœud DOS n'offre pas de mémoire non volatile ; Tous les registres sont préservés ; Altéré - AF