CODINGSDCC TUT'S PAR STEPHBB75 ★ Ecrire un fichier sur une disquette ★

Sdcc - 07 - Ecrire un Fichier sur une DisquetteCoding Sdcc Tut's Par Stephbb75

Après avoir vue comment lire un fichier on va voire comment écrire un fichier...
Une fonction qui écrit un fichier binaire. On sauve le contenue de la mémoire dans un fichier.
Cette fonction ne peut pas écrire un ficher ASCII, car celui ci n'a pas d'en-tête AMSDOS.
 En fait le principe est le même sauf que l'on vas utiliser les fonctions du système pour l'écriture et non la lecture, qui sont :
  • BC8C CAS OUT OPEN ouverture correcte d'un fichier de sortie.
  • BC8F CAS OUT CLOSE fermeture correcte d'un fichier de sortie.
  • BC92 CAS OUT ABANDON fermer immédiatement fichier de sortie.
  • BC98 CAS OUT DIRECT écrire zone mémoire définie sur cassette/disquette (pas à travers le buffer).

Je n'est pas mis toutes les fonctions existantes, seulement celle que l'on vas utiliser.
Comme pour la lecture, la fonction vas être en full assembleur, cela seras plus rapide...
Toujours comme pour la lecture, il faut savoir qu'il faut initialiser la ROM 7 pour pouvoir utiliser les disquettes, ce qui est fait dans la fonction de lecture.
ET pareil, avec la dernière version de SDCC 3.2.0a (quand j'ai écris cette page SDCC en était à la version 3.2a) il faut ajouter une option de compilation, c'est "--oldralloc", sinon la gestion de la pile ne se fait plus de la même façon...
La ce code vas aussi vous faire voire l'utilisation des pointeurs sur la mémoire, car ce code permet de sauver une table de sinus et cosinus sur le disque...

#include "conio2.h"
#include
#include
#include

#define KM_WAIT_CHAR_s
__asm
call #0xBB06
__endasm


// Tableaux precalcules de sinus et cosinus
// on utilise des pointeur directement sur la mémoire
// on les initalise dans le main
float *pSin;
float *pCos;


// IL FAUT UTILISER "--oldralloc" POUR COMPILER !
// code retout :
// 0 Ok
// -1 Erreur
int SaveFileBin(char* filename, char* readbuffer, int lenght)
{
__asm

; Initialisation de l amsdos (ROM 7) avant le changement d un fichier
ld hl,(#0xBE7D) ; adresse de la zone réservée AMSDOS
ld a,(hl) ; drive
push hl
push af
ld de,#0x40 ;DE-HL contient la plage dans laquelle la ROM doit être recherchée
ld hl,#0xABFF
ld c,#7 ;contient l'adresse de sélection de ROM à tester
call #0xBCCE ;initialisation d'une ROM de second plan
pop af
pop hl
ld (hl),a ; on remet le drive courant

; récupere le parametre char* filename
LD L, 4(IX)
LD H, 5(IX)
;LD B, 8(IX)

; calcule la longeur du nom de fichier
call getfilenamesize

; B = longueur du nom de fichier en caractères
; HL = l adresse de début du nom de fichier

;; DE = l adresse d'un tampon 2k
;; En mode disque: cette mémoire tampon n'est pas utilisé lorsque Fonction firmware
;; CAS EN DIRECT est utilisé, il est donc prudent de le mettre nulle (0)
;; Vous le souhaitez.
ld de,#0

;; fonction du firmware pour ouvrir un fichier en ecriture
call #0xBC8C

;; cas_in_open retour:
;; si le fichier a été ouvert avec succès:
;; - carry est vrais
;; - HL contient l adresse de l en-tête du fichier s AMSDOS
;; - DE contient l adresse de chargement du fichier (à partir de l en-tête)
;; - BC contient la longueur du fichier (à partir de l en-tete du fichier)
;; - A contient le type de fichier (2 pour les fichiers binaires)
; si une erreur on sort le la fonction
JR NC,ERRDRIV
JR Z,ERRDRIV

;; fonction du firmware pour sauver la mémoire dans le fichier en entier
;; cela fonctionne avec les fichiers qui ont un en-tête AMSDOS (les
;; fichiers ASCII n'ont pas un en-tête)

; récupere le parametres char* readbuffer
LD L, 6(IX)
LD H, 7(IX)

; récupere le parametres int lenght
LD E, 8(IX)
LD D, 9(IX)

LD A, #2 ; Type de fichier (binaire)

; BC l adresse du point d entree;
LD BC,#0

;; Ecriture du fichier
call #0xBC98

;; fonction du firmware pour fermer un fichier ouvert en ecriture
call #0xBC8F

jp asmFin

ERRDRIV:
;LD (FLGERR),A ;Sort ici si erreur drive
CALL #0xBC92
; il y a une erreur, on retourne cette erreur....
; enfin pour le moment juste la valeur -1
ld hl,#0xFFFF
pop ix
ret


getfilenamesize:
push de
push hl
ld e,#0
getfilenamesizeloop:
ld a, (hl)
or a
jp z, getfilenamesizeend
inc hl
inc e
jp getfilenamesizeloop
getfilenamesizeend:
pop hl
ld b, e
pop de
ret

asmFin:


__endasm;
}

void main()
{
int i;

// intalisation des deux pointeurs sur la mémoire
// le principe c'est 2 table de 360 valeurs en float
pSin = (float *)((unsigned int)0x8000);

// Second pointeur qui en fait est décalé de 1440 vis a vis du premier
// 1440 ? -> oui, un float c'est 4 octets, donc 360 x 4 = 1440
// en fait se pointeur n'est pas vraiment utilie, on aurais put se contanté que du 1er
// mais pour la lisibilité du code c'est un peut mieux.
pCos = (float *)((unsigned int)0x8000+1440);

gotoxy(1,1); printf("Calcule des sin et cos");
for(i=0;i<360;i++)
{
pSin[i] = (float)sinf( (i * 3.1415927 / 180) );
pCos[i] = (float)cosf( (i * 3.1415927 / 180) );
gotoxy(1,2);printf("%d", i);
}

gotoxy(1,1); printf("Calcule terminer ");
gotoxy(1,2); printf("une touche pour sauver ");
KM_WAIT_CHAR_s;

// la c'est la sauvegarde, on sauve à partir de l'adresse 8000, et on sauve d'une longeur de 1440 x 2.
SaveFileBin("sincos.dat", 0x8000, 1440*2);

gotoxy(1,1); printf("Sauvegarde fini ");
gotoxy(1,2); printf("une touche pour finir");
KM_WAIT_CHAR_s;
}

Voila, comme d'hab, le tout se trouve dans se ZIP, bonne écriture ;-)

stephbb75

Page précédente : Sdcc - 06 - Lire un Fichier

CPCrulez[Content Management System] v8.7-desktop/cache
Page créée en 086 millisecondes et consultée 758 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.