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:13812
    Visiteurs aujourd'hui:5
     
     
    Me contacter
    Donnez votre avis
     
    Le site de Steph : Le CPC

    Swaper 2 écrans


    Comme vous devez peut être le savoir, sur CPC l'écran affiche la zone mémoire &C000, mais on peut faire en sorte que le CPC utilise d'autre zone mémoire pour l'affichage, c'est ce que fait se programme.
    Pour savoir comment cela fonctionne exactement, rechercher sur cpcrulez ...

    Vous trouverez 3 fonctions en fait, 2 qui swap deux écran entre C000 et 4000, et une autre qui swape entre l'adresse qui lui est fournie (0000, 4000, 8000 et C000).
    SwapScr_s et SwapScr font la même chose, une (SwapScr_s) utilise les fonction du système, l'autre (SwapScr) attaque directement les composants du CPC.
    Pour bien voire que l'on a bien changé d'écran, on charge avant une image pour chaque écran. Il vous suffit pour changer les écrans d'appuyer sur une touche
    Ha oui, le fichier comp.bat est modifier pour ajouter les deux images sur la disquette, cela se fait avec ces lignes :
    CPCDiskXP -File C000.SCR -AddToExistingDsk %1.dsk
    CPCDiskXP -File 4000.SCR -AddToExistingDsk %1.dsk

    #include 
    #include 
    
    
    #define KM_WAIT_CHAR_s \
    __asm \
    call #0xBB06 \
    __endasm
    
    #define  SCR_SET_MODE1_s \
    __asm	ld a,#1 \
    call #0xBC0E \
    __endasm;
    
    unsigned int CurentSCR = 49152; //0xc000;
    
    
    // IL FAUT UTILISER "--oldralloc" POUR COMPILER !
    // code retout :
    // 0 Ok
    // -1 Erreur
    int ReadFileBin(char* filename, char* readbuffer)
    {
    
    __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 lecture
    	call #0xbc77
    
    	;; 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 charger 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)
    
    	;; Lecture du fichier
    	call #0xbc83
    
    	;; fonction du firmware pour fermer un fichier ouvert en lecture
    	call #0xbc7a
    	
    	jp asmFin
    
    ERRDRIV:
    	;LD (FLGERR),A  ;Sort ici si erreur drive
    	CALL #0xBC7D
    	; 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;
    
     return 0;
    }
    
    
    
    // swap entre le scr C000 et 4000 (si l'ecrans n'est pas en 4000 on repasse en C000)
    // Sans utilisation de fonction systeme
    // On attaque directement le CRTC
    void SwapScr()
    {
    	if ( CurentSCR == 49152 )
    	{
    		// on passe l'ecran en 4000
    		//Ecran en &4000 : OUT &BC00,12:0UT &BD00,&X 00010000
    		__asm
    			ld  bc,#0xBC0C
    			out (c),c
    			ld  bc,#0xBD00+16 ;write a value
    			out (c),c
    		__endasm;
    		CurentSCR = 16384 ;//0x4000;
    	}
    	else
    	{
    		// on passe l'ecran en C000
    		// Ecran en &C000 : OUT &BC00,12:0UT &BD00,&X 00110000 (standard du système)
    		__asm
    			ld  bc,#0xBC0C
    			out (c),c
    			ld  bc,#0xBD00+48 ;write a value
    			out (c),c
    		__endasm;
    	
    		CurentSCR = 49152; // 0xC000;
    	}
    }
    
    // swap entre le scr C000 et 4000 (si l'ecrans n'est pas en 4000 on repasse en C000)
    // Utilise les fonctions système
    void SwapScr_s()
    {
    	if ( CurentSCR == 49152 )
    	{
    		__asm
    			LD   A,#0x40
    			CALL #0xBC08
    		__endasm;
    		
    		CurentSCR = 16384; //0x4000;
    	}
    	else
    	{
    		__asm
    			LD	 A,#0xC0
    			CALL #0xBC08
    		__endasm;
    	
    		CurentSCR = 49152; //0xC000;
    	}
    }
    
    // swap entre le scr 0000, 4000, 8000 et C000
    // Sans utilisation de fonction systeme
    // On attaque directement le CRTC
    // retourne :
    // 0 Ok
    // -1 Erreur d'adresse
    int SwapAllScr( unsigned int adrscr )
    {
    	if ( adrscr == 0xC000 )
    	{
    		// on passe l'ecran en 4000
    		//Ecran en &4000 : OUT &BC00,12:0UT &BD00,&X00010000
    		__asm
    			ld  bc,#0xBC0C
    			out (c),c
    			ld  bc,#0xBD00+48 ;write a value
    			out (c),c
    		__endasm;
    		CurentSCR = 16384 ;//0x4000;
    	}
    	else if ( adrscr == 0x4000 )
    	{
    		// on passe l'ecran en C000
    		// Ecran en &C000 : OUT &BC00,12:0UT &BD00,&X00110000 (standard du système)
    		__asm
    			ld  bc,#0xBC0C
    			out (c),c
    			ld  bc,#0xBD00+16 ;write a value
    			out (c),c
    		__endasm;
    	
    		CurentSCR = 49152; // 0xC000;
    	}
    	else if ( adrscr == 0x0000 )
    	{
    		// on passe l'ecran en 0000
    		//Ecran en &0000 : OUT &BC00,12:0UT &BD00,&X00000000
    		__asm
    			ld  bc,#0xBC0C
    			out (c),c
    			ld  bc,#0xBD00+0 ;write a value
    			out (c),c
    		__endasm;
    		
    		CurentSCR = 0; // 0x0000;
    	}
    	else if ( adrscr == 0x8000 )
    	{
    		// on passe l'ecran en 8000
    		//Ecran en &8000 : OUT &BC00,12:0UT &BD00,&X00100000
    		__asm
    			ld  bc,#0xBC0C
    			out (c),c
    			ld  bc,#0xBD00+32 ;write a value
    			out (c),c
    		__endasm;
    		
    		CurentSCR = 32768; // 0x8000;
    	}
    	else
    	{
    		return -1;
    	}
    	
    	return 0;
    }
    
    
    void main()
    {
    	unsigned char *pScreenC = (unsigned char *)0xC000;
    	unsigned char *pScreen4 = (unsigned char *)0x4000;
    	unsigned int nByte = 0;
    
    	CurentSCR = 49152;
    
    	SCR_SET_MODE1_s
    	
    	ReadFileBin("4000.SCR", 0x4000);
    	ReadFileBin("C000.SCR", 0xC000);
    
    	KM_WAIT_CHAR_s;
    	SwapScr();
    
    	KM_WAIT_CHAR_s;
    	SwapScr();
    
    	KM_WAIT_CHAR_s;
    	SwapScr_s();
    
    	KM_WAIT_CHAR_s;
    	SwapScr_s();
    
    	printf("une touche pour finir");
    	KM_WAIT_CHAR_s;
    }
    
    

    Voila, comme d'hab, le tout se trouve dans se ZIP, bon swap ;-)