Central Input/Output utility

 

 

Le CIO est un utilitaire gérant les accès en INPUT/OUTPUT sur les différents périphériques.

Les commandes BASIC comme PRINT, INPUT, GRAPHICS, LPRINT, ... ne sont en fait que des commandes simplifiées pour appeler le CIO. Basic se débrouillant alors pour passer tous les paramètres comme il faut.

Il est cependant possible de déclencher les routines du CIO grâce à d'autres commandes BASIC: Comme OPEN, GET, PRINT et XIO. Cependant, il faudra gérer soit même tous les codes attendus par le CIO.

De même, il est possible de déclencher ces routines en assembleur. Là aussi, il faudra passer les bons codes, mais ce n'est pas aussi compliqué que cela.

 

Les canaux du CIO:

Le CIO utilise 8 canaux pour accéder aux devices. Des canaux que l'on numérotera de 0 à 7.

Le Basic se réserve 3 canaux:

- 0 utilisé en permanence pour l'éditeur.

- 6 Utilisé pour les opérations graphiques (inutilisé si pas d'opération graphique).

- 7 Utilisé pour les accès cassette, disquette et imprimante (inutilisé si pas d'accès à l'un de ces périphériques nommés).

 

En assembleur, on fait tout ce que l'on veut, tous les canaux sont libres (à moins que vous n'utilisiez encore le basic avec votre code).

 

Les différentes étapes d'utilisation des routines du CIO:

Pour utiliser les routines du CIO, il faut:

- Fermer le canal (Pas forcément nécessaire, mais un autre programme a pu l'ouvrir et ne pas le fermer ! Dans ce cas, l'ouverture ne pourrait pas ensuite se (re)faire.)

- Ouvrir le canal (et ne pas refaire l'ouverture si déjà ouvert !)

- Lire/Ecrire un/plusieurs octets.

- Fermer le canal à partir du moment où l'on ne s'en sert plus !

Bien entendu, pour ouvrir, lire/écrire et enfin fermer un périphérique, il faut passer des paramètres comme le nom du périphérique, le type d'accès, ...

Ces informations seront passées dans l'IOCB du canal utilisé.

 

La structure de l'IOCB:

La structure de l'IOCB ne sert que pour du code machine. En effet, en BASIC, ce sont les instructions qui stockeront automatiquement les bonnes valeurs dans la structure correspondant au canal choisi.

L'Input Output Control Block(IOCB) occupe une taille de 16 octets par canaux. Donc pour les 8 IOCB : 8 x 16 = 128 octets en tout.

L'IOCB du canal 0 démarre en $0340. Pour trouver le début de l'IOCB pour un canal précis, il suffit alors de multiplier ce canal par 16...

Image non trouvée !Marrant, pour le canal 1, on obtient 16 qui fait $10 en hexa. Pour le canal 2, on obtient 32 qui fait $20 en hexa. et ainsi de suite. Et en fait, plus besoin de faire des calculs: pour le canal 5 par exemple, il suffit d'écrire $50.

 

Offset (Adresse à partir du canal 0): Nom Explication
0 ($0340) ICHID Handler, à $FF si inutilisé
1 ($0341) ICDNO Numéro du device (pour les disquettes)
2 ($0342) ICCOM commande
3 ($0343) ICSTA status
4 ($0344) ICBAL Adresse buffer (partie basse)
5 ($0345) ICBAH Adresse buffer (partie haute)
6 ($0346) ICPTL Adresse routine PUT BYTE (utilisé par Basic) (partie basse)
7 ($0347) ICPTH Adresse routine PUT BYTE (utilisé par Basic) (partie haute)
8 ($0348) ICBLL Longueur du buffer (partie basse)
9 ($0349) ICBLH Longueur du buffer (partie haute)
$A ($034A) ICAX1 Information auxiliaire
$B ($034B) ICAX2 Information auxiliaire
$C ($034C) ICAX3 Information auxiliaire
$D ($034D) ICAX4 Information auxiliaire
$E ($034E) ICAX5 Information auxiliaire
$F ($034F) ICAX6 Information auxiliaire

 

ICHID

Lorsqu'un canal est ouvert, ICHID est un index vers une table de handlers qui pointe sur les routines du device. à $FF si fermé.

ICDNO

Numéro du device dans le cas où il existe plusieurs devices de même nom (D0, D1, D2 en Basic: D pour Disquette et 0 pour le premier lecteur, 1 pour le second, ...)

ICCOM

Commande que le CIO doit exécuter:

Commande Valeur (en hexa)
Open $03
Close $0C
Get $07
Put $0B
Input $05
Print $09
Status Request $0D
... > $0D, ces commandes dépendent du device

Image non trouvée ! Open, Close et Status peuvent être lancées sur des canaux déjà (ou encore) fermés.

ICSTA

Contient un code erreur si problème. Si le bit 7 est à 0, c'est qu'il n'y a pas d'erreur.

ICBAL et ICBAH

Avant l'ouverture d'un canal, ce pointeur est positionné sur un buffer contenant le nom de device (Cette chaîne doit se terminer par 0 ou $9B).

Avant un INPUT ou OUTPUT, buffer qui contiendra les données à lire ou à écrire.

ICPTL et ICPTH

Réservé au Basic...

ICBLL et ICBLH

Doit contenir la longueur maximum du buffer définie dans ICBAL ou ICBAH. Cette valeur peut être modifiée par le CIO en lecture sur un device si le nombre d'octets reçu est inférieur. La valeur sera alors égale aux nombres d'octets effectivement lus.

ICAX1 à ICAX6

Informations auxiliaires.

 

Ouvrir un canal du CIO

Avant tout, il faut ouvrir un canal. Mais pour cela, il faut indiquer dans l'IOCB correspondant les informations suivantes:

Paramètre Valeur
ICCOM OPEN ($03)
ICBAL Adresse sur le nom du périphérique (partie basse)
ICBAH Adresse sur le nom du périphérique (partie haute)
ICAX1 En général Lecture/Ecriture mais aussi CLEAR et PLOT/DRAWTO si périphérique S:
ICAX2 En général 0, ou mode écran pour le périphérique S:

 

ICBAL et ICBAH pointent sur un buffer contenant le device (RAPPEL 0 ou $9B en fin de chaîne !).

Format d'écriture ICAX1:

 

128 64 32 16 8 4 2 1
    C S W R   A

Ce sont essentiellement les bits R et W qui sont utilisés. Les bits suivants sont plus spécifiques au device S:.

A : pour Append, A TESTER !!!

R : pour Read, afin de permettre un accès en lecture sur le périphérique.

W : pour Write, afin d'accéder en écriture sur un périphérique.

S : Pour Split : Contrairement à la commande BASIC GRAPHICS, la valeur 16 permet d'avoir des lignes en mode texte en bas de l'écran.

C : Pour Clear : Lors de l'ouverture de l'écran, effacement de l'écran.

On peut bien évidemment combiner les différents bits: R + W permettant par exemple d'accéder en lecture et écriture à un périphérique (Remarque: cela ne change pas la taille du fichier sur une disquette).

 

En sortie:

Le registre P voit son bit N positionné si une erreur se produit.

Squelette d'appel "open" en assembleur:

Pour ouvrir un canal en BASIC, il faut utiliser la commande OPEN:

OPEN #canal,icax1,icax2,device:file name

 

Lecture/Ecriture sur un canal:

Lire une chaîne de caractères:

La lecture s'arrêtera sur un retour chariot ($9B) ou EOL ou enfin sur EOF.

Les paramètres à passer sont:

 

Paramètre Valeur
ICCOM INPUT ($05)
ICBAL Adresse d'un buffer qui contiendra l'enregistrement lu (partie basse)
ICBAH Adresse d'un buffer qui contiendra l'enregistrement lu (partie haute)
ICBLL Taille du buffer (Partie basse)
ICBLH Taille du buffer (Partie haute)

Remarque : Si le nombre de caractères reçus est inférieur à la taille du buffer, alors ICBLL et ICBLH contiennent le nombre de caractères effectivement lus.

Squelette d'appel "input" en assembleur, voir code plus bas.

En BASIC, la commande équivalente est INPUT:

INPUT #canal,Variable de type caractère

INPUT #canal,Variable arithmétique Dans ce cas, on ne pourra saisir que des chiffres et .

La commande s'arrête sur EOL (touche return si clavier K:).

 

Envoyer une chaîne de caractères:

L'écriture de la chaîne s'arrêtera à la taille/nombre de caractères. Remarque, la commande EOL est ignorée dans la chaîne. Par contre, un caractère EOL est systématiquement envoyé à la fin de la chaîne.

Les paramètres à passer sont:

 

Paramètre Valeur
ICCOM PRINT ($09)
ICBAL Adresse d'un buffer les données à envoyer (partie basse)
ICBAH Adresse d'un buffer les données à envoyer (partie haute)
ICBLL Taille du buffer/nombre de caractères (Partie basse)
ICBLH Taille du buffer/nombre de caractères (Partie haute)

Squelette d'appel "PRINT" en assembleur, voir code plus bas.

En BASIC, la commande équivalente est PRINT:

avec ;

PRINT #canal;OUT$

ou PRINT #canal;"TEXTE"

ou , dans ce cas, affichage d'espace devant la chaîne de caractères.

ou PRINT #canal,OUT$

ou enfin PRINT #canal,"TEXTE"

La réutilisation de PRINT sans fermeture au préalable du canal ajoute le texte à la suite.

 

Pour lire n octets:

Cette commande va lire des octets. Elle ne gère donc pas le code EOL. C'est un caractère comme un autre...

Ce sera donc cette commande qu'il faudra utiliser pour lire un fichier autre qu'un fichier texte. (image, binaire, ... dans lesquels il n'y a effectivement pas de code EOL).

Cette commande s'arrête sur EOF, ICBLL et ICBLH. Contient alors la taille réellement lue.

Les paramètres à passer sont:

 

Paramètre Valeur
ICCOM GET ($07)
ICBAL Adresse d'un buffer qui contiendra l'enregistrement lu (partie basse)
ICBAH Adresse d'un buffer qui contiendra l'enregistrement lu (partie haute)
ICBLL Taille du buffer (Partie basse)
ICBLH Taille du buffer (Partie haute)

Squelette d'appel "GET" en assembleur, voir code plus bas.

En basic, la commande équivalente et GET.

GET #canal,var

Ou var est une variable numérique.

Image non trouvée !La commande get lit un octet et un seul. Il faudra donc boucler pour lire tout un fichier par exemple. Dans ce cas, l'instruction TRAP s'avèrera indispensable si l'on ne connait pas la taille du fichier.

EXAMPLE:

 

Pour écrire n octets:

Cette commande va écrire des octets. Elle ne gère donc pas le code EOL. C'est un caractère comme un autre...

Ce sera donc cette commande qu'il faudra utiliser pour écrire un fichier autre qu'un fichier texte. (image, binaire, ... dans lesquels il n'y a effectivement pas de code EOL).

Les paramètres à passer sont:

 

Paramètre Valeur
ICCOM PUT ($0B)
ICBAL Adresse d'un buffer contenant les données à écrire (partie basse)
ICBAH Adresse d'un buffer contenant les données à écrire (partie basse)
ICBLL Taille du buffer (Partie basse)
ICBLH Taille du buffer (Partie haute)

Squelette d'appel "PUT" en assembleur, voir code plus bas.

 

En BASIC, la commande équivalente est PUT

PUT #1,OUT
Où OUT est une variable numérique. On ne peut donc écrire qu'un octet à la fois.


Voici un exemple de squelette pour lire/écrire des données.

 

Clôturer un canal:

Cette fonction est indispensable, elle va libérer l'accès à un canal du CIO et permet ainsi aux autres programmes son utilisation.

Sur une disquette, le nom du fichier sera enregistré à ce moment là .

Les paramètres à passer sont:

 

Paramètre Valeur
ICCOM CLOSE ($0C)

Appel en assembleur:

En basic, la commande équivalente est CLOSE.

CLOSE #canal

Annexe

La table des périphériques