Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : C - Sectorise
(Article écrit par Jean-Pierre Vitulli et extrait d'Amiga News Tech - novembre 1989)
|
|
Après Microïds et son Eagle's Rider, c'est au tour de Loriciel
de dévoiler l'un de ses secrets. Il ne s'agit pas d'une routine utilisée dans un jeu quelconque, mais d'un
utilitaire permettant d'écrire n'importe quel fichier AmigaDOS (programme exécutable, image, musique, etc.)
sur une suite de secteurs de la disquette.
Les avantages sont évidents : le chargement par lecture directe de secteurs est de toute manière
beaucoup plus rapide que par l'appel de fonctions DOS évoluées, donc lourdes. Ce critère de
rapidité de chargement est l'un des points auxquels Loriciel s'attache tout particulièrement lors
de la réalisation de ses jeux.
Le programme sectorise.c a été écrit par Jean-Pierre Vitulli, programmeur professionnel
chez Loriciel. Toutes les explications quant à son utilisation sont incluses.
Il vous donnera en outre un exemple d'utilisation du trackdisk.device en C.
Ce programme est écrit pour le Lattice version 4.0 ou supérieure. Pour compiler,
utilisez le Script cc, et pour lier, le Script bl. Lors de la compilation,
ignorez les messages d'avertissement ("pointers do not point to same object").
Fichier Script cc :
.key file
.bra {
.ket }
lc -csuw -d -v -r -b {file}
|
Fichier Script bl :
Fichier de lien avec :
FROM LIB:c.o
sectorise.o
LIBRARY LIB:lc.lib,LIB:amiga.lib
NODEBUG
SHALLCODE
SMALLDATA
TO sector
VERBOSE
|
Programme sectoriae.c :
Exemple d'utilisation du trackdisk.device en C pour Amiga News Tech. Ce programme lit un fichier
(sur un autre lecteur ou en RAM:) et l'installe sur une suite de secteurs d'une disquette
formatée en DF0:. Il s'utilise à partir du CLI en lui donnant sur la ligne de commande le "path"
(chemin) et nom du fichier et le numéro du tel secteur à utiliser (0-1759).
Exemple : "sector DF1:toto 50" place le fichier "toto" sur la disquette se trouvant dans "DF1:"
à partir du secteur "50".
/*
Programmation : C - Sectorise
Article écrit par Jean-Pierre Vitulli et extrait d'Amiga News Tech - novembre 1989
http://obligement.free.fr/articles/c_sectorise.php
Adapté à VBCC par Tygre, 2020/09/20
*/
/**********************************************************/
/* Includes standard */
/* pas tous utiles, mieux vaut plus que pas assez */
#include "exec/types.h"
#include "exec/libraries.h"
#include "exec/memory.h"
#include "exec/devices.h"
#include "devices/trackdisk.h"
#include "libraries/dos.h"
#include "stdio.h"
/**********************************************************/
/* Uniquement Lattice à partir de la version 4.0 */
/* permet l'appel des routines ROM avec passage des */
/* paramètres par les registres au lieu de la pile : */
#include "proto/dos.h"
#include "proto/exec.h"
/* et pour VBCC : */
#include <clib/alib_protos.h>
/**********************************************************/
/* Variables pour trackdisk.device */
struct MsgPort *diskport;
struct IOStdReq *diskreq;
/**********************************************************/
/* Variables globales */
int error; /* Pour retour code erreur device */
char *buffer; /* Buffer de travail */
int secteur_depart; /* No du secteur de depart extrait de la ligne de commande */
struct FileHandle *fichier; /* handle fichier */
void end_prog();
/**********************************************************/
/* MAIN */
main(argc, argv)
int argc;
char *argv[];
{
register int origine;
/******************************************************/
/* Allocation buffer de travail */
if ((buffer = AllocMem(1000, MEMF_CHIP|MEMF_CLEAR)) == NULL)
{
printf("Impossible d'allouer le buffer\nAbort\n\n");
end_prog();
}
/******************************************************/
/* Usage is mauvaise ligne de commande */
if (argc != 3)
{
printf("USAGE : %s <fichier> <secteur de départ>\n", argv[0]);
printf("Ce programme place le fichier sur une disquette\n");
printf("depuis <secteur de départ> (0-1759).\n");
printf("La disquette destination DOIT être dans DF0:.\n");
printf("Le bloc BitMap n'est pas mis à jour.\n");
end_prog();
}
/******************************************************/
/* Détermine No du secteur de départ */
secteur_depart = atoi(argv[2]);
if ((secteur_depart < 0) || (secteur_depart > 1759))
{
printf("Secteur de départ %d invalide.\n", secteur_depart);
end_prog();
}
/******************************************************/
/* Ouverture fichier source */
if ((fichier = (struct FileHandle *)Open(argv[1], MODE_OLDFILE)) == 0)
{
printf("Impossible d'ouvrir le fichier %s.\n", argv[1]);
end_prog();
}
/******************************************************/
/* Ouverture port de communication avec trackdisk */
diskport = CreatePort(NULL, 0);
diskreq = CreateStdIO(diskport);
/******************************************************/
/* Ouverture trackdisk.device */
error = OpenDevice("trackdisk.device", 0, (struct IORequest *)diskreq, 0);
if (error > 0)
{
printf("Impossible d'ouvrir trackdisk.device.\n");
end_prog();
}
/******************************************************/
/* Vérifie protection en écriture disque */
diskreq->io_Command = TD_PROTSTATUS;
DoIO((struct IORequest *)diskreq);
if (diskreq->io_Actual != 0)
{
printf("Disque protégé en écriture.\n");
end_prog();
}
/******************************************************/
/* Vérification de sécurité */
printf("Placer la disquette destination dans le lecteur DF0:\n");
printf("puis taper <RETURN>.\n");
getchar(); /* Attend un retour chariot */
origine = secteur_depart;
while(Read((BPTR)fichier, buffer, 512)) /* Lecture par 512 octets */
{
diskreq->io_Length = 512;
diskreq->io_Data = buffer;
diskreq->io_Command = CMD_WRITE;
diskreq->io_Offset = (long) (secteur_depart++ * 512);
DoIO((struct IORequest *)diskreq);
if (secteur_depart > 1759) /* Dépasse capacité disquette */
{
printf("Dépassement du secteur 1759.\n");
printf("Plus de place sur la disquette.\n");
break;
}
}
/******************************************************/
/* Quelques infos utiles */
printf("Dernier secteur : %d\nTotal transfert : %d secteurs.\n", secteur_depart - 1, secteur_depart - origine);
printf("Total : %d octets.\n", (secteur_depart - origine) * 512);
/******************************************************/
/* Flush buffer disque par sécurité */
diskreq->io_Command = CMD_UPDATE;
DoIO((struct IORequest *)diskreq);
error = diskreq->io_Error;
/******************************************************/
/* Arrêt moteur disquette */
diskreq->io_Length = 0;
diskreq->io_Command = ETD_MOTOR;
DoIO((struct IORequest *)diskreq);
/******************************************************/
/* On signale une erreur éventuelle */
if (error > 19)
{
printf("Erreur trackdisk, code %d.\n", error);
}
else
{
printf("trackdisk.device fermé sans problème.\n");
}
end_prog();
}
/**********************************************************/
/* Dé-allocations et fermetures */
void end_prog()
{
if (fichier)
Close((BPTR)fichier); /* On ferme le fichier s'il a été ouvert */
if (buffer)
FreeMem(buffer, 1000); /* et dé-alloue le buffer si alloué */
/* Fermeture trackdisk */
if (diskport)
DeletePort(diskport);
if (diskreq)
{
CloseDevice((struct IORequest *)diskreq);
DeleteStdIO(diskreq);
}
exit();
}
|
Boucle lecture fichier/écriture disque si vous n'avez qu'un lecteur, il vaut mieux mettre
le fichier en RAM: sinon il faut augmenter la taille du tampon mémoire et lire tout le
fichier avant de l'écrire dans les secteurs. Cette version présente l'avantage de
fonctionner quelle que soit la taille du fichier à transférer.
Évidement, les données placées sur disquette de cette façon n'apparaissent pas dans
le répertoire... De plus, le bloc "BitMap" n'étant pas mis à jour, vous risquez d'effacer ces
données en inscrivant un fichier sur la disquette. De même, vous pouvez détruire une
disquette DOS en écrivant dans n'importe quel secteur (exemple : bloc 550 = racine du répertoire).
D'un autre côté, rien ne vous empêche de stocker vos données dans un format qui vous est
propre.
Mise à jour de septembre 2020 : une archive contenant le listing adapté à vbcc, et avec l'exécutable
compilé par VBCC, a été réalisée par Yann-Gaël Guéhéneuc et est disponible sur
obligement.free.fr/files/antsectoriser.lha.
Petit exercice
Comment relire ces données ? Remplacez le "CMD_WRITE" par un "CMD_READ". L'élément de structure
"io_Length" doit être multiple de 512 puisque vous devez lire par secteurs entiers. "io_Offset"
donne la position du premier secteur.
Exemple :
diskreq->io_Length = 512*2; (taille à lire)
diskreq->io_Data = buffer;
diskreq->io_Command = CMD_READ;
diskreq->io_Offset = (long) (0*512); (secteur de départ)
DoIO(diskreq);
|
On va lire deux secteurs à partir du secteur 0 (donc le bloc d'amorce en entier). Le tout est
stocké dans le tampon mémoire nommée "buffer".
Voilà, c'est tout simple. Bonne chance !
|