Routines de l'UniDOS

Cette section s'adresse aux développeurs de programmes qui désirent ajouter du code spécifique à l'UniDOS dans leurs logiciels afin d'en améliorer l'ergonomie ou les fonctionnalités, sans nécessairement perdre la compatibilité AMSDOS.

De fait, l'UniDOS est conçu pour que les programmes prévus pour l'AMSDOS et normalement limités aux disquettes puissent tirer profit des nouveaux lecteurs et de la gestion des répertoires sans aucune modification.

Toutefois, les indirections traditionnelles « CAS » offrent certaines fonctionnalités supplémentaires que vous pouvez facilement exploiter. De plus, si certains programmes désirent offrir davantage lorsqu'ils sont utilisés avec l'UniDOS, il existe un nouveau vecteur BIOS qui permet de le faire avec un minimum de code additionnel. La détection de ce nouveau vecteur CTRL-J est d'ailleurs la méthode à utiliser pour savoir si votre programme tourne sous UniDOS ou non, et activer au besoin votre code dédié.

Note : le fichier « UniDOS.i » disponible dans l'archive du code source contient toutes les définitions des commandes et des codes d'erreurs dont vous aurez besoin dans vos programmes exploitant spécifiquement l'UniDOS.

Indirections « CAS »

Vous trouverez ci-après une description des nouvelles fonctionnalités disponibles lors de l'utilisation des indirections « CAS » de l'UniDOS.

CAS_IN_OPEN

Le vecteur se comporte comme celui de l'AMSDOS à l'exception des cas suivants :

  • Si un nom de répertoire est fourni en entrée, alors vous aurez en sortie :
    • Carry = 0,
    • Zero = 1,
    • A = DSK_ERR_DIRECTORY_FOUND (avec le bit 7 mis à 1),
    • Si la fonctionnalité n'est pas désactivée (voir cmd_disabled_directory) alors le lecteur logique courant sera assigné au nouveau répertoire.
  • Si un nom de répertoire explicite est fourni en entrée (chemin se terminant par un « / ») alors qu'il correspond à un fichier, une erreur DSK_ERR_NOT_A_DIRECTORY sera remontée.
  • Le tampon de 2 Kio pointé par DE n'est pas utilisé lorsque le fichier est accédé via cmd_cas_in_read1).

CAS_IN_CLOSE

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_IN_ABANDON

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_IN_CHAR

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_IN_DIRECT

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_RETURN

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_TEST_EOF

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_OUT_OPEN

Le vecteur se comporte comme celui de l'AMSDOS à l'exception des cas suivants :

  • Si un nom de répertoire explicite est fourni en entrée (chemin se terminant par un « / ») :
    • Carry = 0,
    • Zero = 1,
    • A = DSK_ERR_DIRECTORY_FOUND (avec le bit 7 mis à 1),
    • Un répertoire de ce nom est créé.

CAS_OUT_CLOSE

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_OUT_ABANDON

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_OUT_CHAR

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_OUT_DIRECT

Le vecteur se comporte comme celui de l'AMSDOS.

CAS_CATALOG

Le vecteur se comporte comme celui de l'AMSDOS à l'exception des cas suivants :

  • La taille disponible est renvoyée en 32 bits dans BCDE (l'AMSDOS renvoie une taille 16 bits dans DE seulement).
  • Dans le tampon, le marqueur présence de fichier sert aussi à stocker la taille des fichiers dépassant 65535 Kio2).
    • Si &00, alors la fin du tampon est atteinte (comme avec l'AMSDOS).
    • Si non nul, alors un fichier est présent (comme avec l'AMSDOS), mais en plus, les bits 0 à 5 contiennent, en valeur inversée, les 6 bits de poids fort de la taille du fichier exprimée en 24 bits. Par exemple :
      • Si &FF (comme l'AMSDOS) alors le fichier a une taille qui tient dans les 16 bits standard (les bits 0 à 5 inversés valent tous 0).
      • Si &FE alors 65536 Kio (&010000, les bits 0 à 5 inversés valent &01) doivent être ajoutés à la taille 16 bits pour avoir la véritable taille du fichier.
  • Dans le tampon, si un fichier est en lecture seule3) et avec une taille de 0 octets, alors il s'agit d'un répertoire.

Vecteurs BIOS

L'UniDOS implémente tous les vecteurs standards de l'AMSDOS. Certains offrent une compatibilité complète avec l'AMSDOS, tandis que d'autres seront inactifs lorsque l'UniDOS est activé4).

CTRL-A

Identique à celui de l'AMSDOS.

CTRL-B

Identique à celui de l'AMSDOS.

CTRL-C

Identique à celui de l'AMSDOS.

CTRL-D

Identique à celui de l'AMSDOS.

CTRL-E

Identique à celui de l'AMSDOS.

CTRL-F

Identique à celui de l'AMSDOS.

CTRL-G

Identique à celui de l'AMSDOS.

CTRL-H

Identique à celui de l'AMSDOS.

CTRL-I

Identique à celui de l'AMSDOS.

CTRL-J (nouveau)

En complément des vecteurs BIOS CTRL-A à CTRL-I offerts par l'AMSDOS, l'UniDOS met à disposition un nouveau vecteur BIOS CTRL-J. Tout programme désirant offrir des fonctionnalités supplémentaires en présence de l'UniDOS a simplement à détecter ce vecteur ; en cas d'absence le code standard dédié à l'AMSDOS pourra être utilisé normalement.

Le nouveau vecteur BIOS CTRL-J se détecte exactement comme les vecteurs BIOS de l'AMSDOS, via une recherche de RSX.

;
; Détecte le vecteur CTRL-J
; Entrée - N/A
; Sortie - Si Carry = 1 alors le vecteur a été trouvé et le « far call » associé est prêt à être appelé
;          Si Carry = 0 alors le vecteur n'a pas été trouvé
; Altéré - AF,BC,DE,HL

IsUniDOS
        LD HL,RSX_BIOS_CTRL_J
        CALL KL_FIND_COMMAND
        RET NC
; Ici HL = adresse du vecteur CTRL-J
; et C = numéro de la ROM où il se trouve
        LD (FARCALL_CTRL_J),HL
        LD A,C
        LD (FARCALL_CTRL_J+2),A
; On configure le « far call » associé
; Qu'on pourra invoquer simplement
; avec un RST 3,FALCALL_CTRL_J
        RET
RSX_BIOS_CTRL_J
        DB &8A
FARCALL_CTRL_J
        DS 3

Toutes les commandes disponibles via ce vecteur ont la même sémantique.

; Entrée - C = Identifiant de la commande
;          La valeur des autres registres en entrée dépend de la commande
; Sortie - Si Carry = 1 alors la commande a pu être exécutée
;             La valeur des autres registres en sortie dépend de la commande
;          Si Carry = 0 alors la commande est inconnue ou les valeurs en entrée sont invalides
; Altéré - Uniquement les registres de sortie de la commande

Vous trouverez ci-après la liste des commandes ainsi disponibles.

cmd_cat_faked_parent (0)

;       Activation de l'entrée "parent" (/) dans le tampon du catalogue
;           Entrée - A = statut, &FF=Non (par défaut), &00=Oui
;           Sortie - A = statut précédent

Si activé, le CAS_CATALOG ajoutera une entrée « / » représentant le répertoire parent en première position du tampon pointé par le registre DE.

À noter que cette entrée ne sera pas ajoutée si vous êtes déjà à la racine du média (dans ce cas, la répertoire parent n'existe pas).

cmd_device_list (1)

;       Renvoie la liste des lecteurs physiques
;           Entrée - DE = adresse du buffer de 64 octets où stocker la liste
;           Sortie - DE = adresse du buffer qui contient une liste des nom de lecteurs physiques
;                           Chaque nom est une chaîne de caractères terminée par la mise à 1 du bit 7
;                           Un 255 marque la fin de la liste

Cette commande est à utiliser par tout programme qui désire offrir un menu dynamique pour le choix du lecteur en cours.

cmd_device_info (2)

;       Renvoie les informations détaillées sur un lecteur physique donné
;           Entrée - HL = pointeur sur le nom du lecteur physique (chaîne terminée bit 7 à 1, stockée en RAM)
;                    DE = adresse du buffer de 64 octets où stocker les informations
;           Sortie - DE = adresse du buffer qui contient les informations
;                           Un octet avec les attributs du lecteur physique
;                               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)
;                               Bit5 = 1 si le média est accessible via les nouvelles API UniDOS
;                           Un octet avec l'identifiant du système de fichiers (toujours à 255, non géré pour le moment)
;                           Un mot 32 bits avec le nombre de kilo-octets libres
;                               &ffffffff si l'information est non disponible pour ce lecteur
;                           Un mot 32 bits avec la capacité totale en kilo-octets
;                               &ffffffff si l'information est non disponible pour ce lecteur
;                           La description sous la forme d'une chaîne de caractères terminée par la mise à 1 du bit 7
;       Désactivation de la gestion des liens symboliques lors du CAS IN OPEN
;           Entrée - A = statut, &FF=Non (par défaut), &00=Oui
;           Sortie - A = statut précédent

Si les liens sont désactivés, les liens symboliques seront traités comme des fichiers normaux lors du CAS_IN_OPEN et leur contenu pourra être analysé.

Les liens symboliques sont alors remontés comme des fichiers de type 8.

cmd_cas_in_read (5)

;       Lit sur le flux en entrée
;       Possible uniquement avec les lecteurs compatibles avec la nouvelle API UniDOS
;       Ne peut pas être utilisé en même temps que CAS IN DIRECT ou CAS IN CHAR
;       Le tampon de 2K fourni lors du CAS_IN_OPEN ne sera pas utilisé
;           Entrée - HL = adresse où stocker les données lues
;                    DE = nombre d'octets à lire
;           Sortie - Si Z alors des données ont pu être lues
;                       DE = nombre d'octets effectivement lus
;                       A est indéterminé
;                    Si NZ alors une erreur est survenue
;                       A = code d'erreur

Cette commande permet un accès moderne aux fichiers, sans les contraintes de CAS_IN_CHAR et CAS_IN_DIRECT.

cmd_cas_in_seek (6)

;       Change la position courante dans le flux en entrée
;       Possible uniquement avec les lecteurs compatibles avec la nouvelle API UniDOS
;       Ne peut pas être utilisé en même temps que CAS IN DIRECT ou CAS IN CHAR
;           Entrée - DEHL = nouvelle position dans le flux en entrée
;           Sortie - Si Z alors la nouvelle position a pu être atteinte
;                       A est indéterminé
;                    Si NZ alors une erreur est survenue
;                       A = code d'erreur

Cette commande permet un accès moderne aux fichiers, sans les contraintes de CAS_IN_CHAR et CAS_IN_DIRECT. Elle n'est toutefois pas disponible pour les lecteurs de type « flux » qui ne permettent pas la libre navigation dans les fichiers.

cmd_cas_out_write (7)

;       Écrit sur le flux en sortie
;       Possible uniquement avec les lecteurs compatibles avec la nouvelle API UniDOS
;       Ne peut pas être utilisé en même temps que CAS_OUT_DIRECT ou CAS OUT CHAR
;       Le tampon de 2K fourni lors du CAS OUT OPEN ne sera pas utilisé
;           Entrée - HL = adresse où se trouvent les données à écrire
;                    DE = nombre d'octets à écrire
;           Sortie - Si Z alors des données ont pu être écrites
;                       DE = nombre d'octets effectivement écrits
;                       A est indéterminé
;                    Si NZ alors une erreur est survenue
;                       A = code d'erreur

Cette commande permet un accès moderne aux fichiers, sans les contraintes de CAS_OUT_CHAR et CAS_OUT_DIRECT.

cmd_cas_out_seek (8)

;       Change la position courante dans le flux en sortie
;       Possible uniquement avec les lecteurs compatibles avec la nouvelle API UniDOS
;       Ne peut pas être utilisé en même temps que CAS OUT DIRECT ou CAS OUT CHAR
;           Entrée - DEHL = nouvelle position dans le flux en sortie
;           Sortie - Si Z alors la nouvelle position a pu être atteinte
;                       A est indéterminé
;                    Si NZ alors une erreur est survenue
;                       A = code d'erreur

Cette commande permet un accès moderne aux fichiers, sans les contraintes de CAS_IN_CHAR et CAS_IN_DIRECT. Elle n'est toutefois pas disponible pour les lecteurs de type « flux » qui ne permettent pas la libre navigation dans les fichiers.

cmd_disabled_directory (9)

;       Désactivation de la gestion des répertoires lors du CAS IN OPEN
;           Entrée - A = statut, &FF=Non (par défaut), &00=Oui
;           Sortie - A = statut précédent

Si la gestion des répertoires est désactivée, alors « CAS_IN_OPEN » ne permettra plus la navigation dans l'arborescence de fichiers. Ce peut être utile ponctuellement pour détecter un répertoire et faire un traitement spécifique (ce qui est le cas par exemple pour un copieur qui ne va pas faire la même opération de copie selon que la source soit un répertoire ou un fichier).

Dans tous les cas, l'erreur DSK_ERR_DIRECTORY_FOUND est remontée en cas d'ouverture de répertoire.

cmd_enabled_sort_dir_first (10)

;       Activation du tri des répertoires avant celui des fichiers lors du CAS IN CATALOG
;           Entrée - A = statut, &FF=Non (par défaut), &00=Oui
;           Sortie - A = statut précédent     

Cette commande fait en sorte que le CAS IN CATALOG trie d'abord les répertoires puis les fichiers.

cmd_is_active_dosnode (11)

;       Retourne l'état d'activation d'une ROM contenant un noeuds DOS
;           Entrée - A = numéro de la ROM
;           Sortie - Si Z alors la ROM correspond à un noeud DOS actif
;                    Si NZ la ROM correspond à un noeuds DOS inactif ou n'est pas un noeud DOS

cmd_examine (12)

;       Vérifie qu'un fichier ou un répertoire existe et retourne les informations associées
;           Entrée - HL = nom du fichier ou du répertoire à examiner
;                    B = longueur du nom du fichier ou du répertoire à examiner
;                    IX = tampon où copier l'heure et la date de dernière modification de l'entrée (7 octets)
;           Sortie - Si HL pointait vers un nom de fichier ou un nom de répertoire non explicite (nom non vide et ne se terminant pas par un '/')
;
;                        Si Z alors le fichier ou le répertoire existe
;                           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 du fichier
;                           IX = tampon où ont été copiées l'heure et la date de dernière modification de l'entrée
;                               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 pointait vers un nom de répertoire explicite (nom vide ou se terminant par un '/')
;                        Si Z alors le répertoire est prêt à être examiné via ExamineNext
;                        Si NZ alors une erreur est survenue
;                           A = code d'erreur

cmd_examine_next (13)

;       Récupère une entrée dans le répertoire en cours d'examen
;           Entrée - HL = pointeur vers la mémoire où stocker le 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 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
;                            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)
1)
il ne l'est pas non plus en mode CAS_IN_DIRECT, comme c'est déjà le cas avec l'AMSDOS.
2)
la taille de base est stockée en 16 bits seulement dans le tampon
3)
bit 7 mis à 1 dans le premier caractère de l'extension de fichier
4)
dans le cas où l'UniDOS est inactif, les vecteurs BIOS de l'AMSDOS sont toujours invoqués