Accueil

CPC


 Dev C sur CPC :

  • le C sur CPC
  • SDCC débuter
  • fichier BAT pour compiler
  • Dessiner Sur CPC
  • Optimiser le dessin
  • Ecrire du texte
  • Lire un fichier
  • Ecrire un fichier
  • Swap d'écran
  • CLS ultra rapide
  • H line
  • Attaquer le CRTC
  • Full Overscan
  • Put pixel très rapide
  • Afficher une image
  • Slide show 1
  • Bézier
  • faire un fichier pour Bézier

  • Quelque fonctions utile

  • Animation
  • 3D
  • Raster
  • Manche a balais

    Le plan du Site

  •  
      Ici les nouvelle du site  
     
    Recherche ?
    Saissisez un mot clé

     
      Quelques chiffres
    Visiteurs:11043
    Visiteurs aujourd'hui:21
     
     
    Me contacter
    Donnez votre avis
     
    Le site de Steph : Le CPC

    Ecrire un fichier sur une disquette


    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 ;-)