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:4
     
     
    Me contacter
    Donnez votre avis
     
    Le site de Steph : Le CPC

    Attaquer le CRTC


    On va s'attaquer directement au hard du CPC, on va voire comment directement programmer le CRTC, ce composent dans le CPC sert à générer le signal vidéo de l'Amstrad CPC
    Premier petit problème, sur les CPC il existe au moins 6 versions différente de se composent, elles sont presque identique mais on bien sur quelques différence. Je vous laisse chercher sur le net tout cela...

    Ce composent possède 17 registres, c'est avec eux que l'on vas le programmer, pour y accéder il faut passer par l'adresse 0xBC00 plus le No de registre, et pour la donnée c'est en 0xBD00 plus la valeur à mettre dans le registre.
    Pour savoir à quoi servent ces registres, une tit recherche sur CPCRULEZ vous donneras la réponse...
    On vas donc créer une fonction toute simple qui permettras en y passent le registre et la valeur d'attaquer le CRTC.
    J'ai aussi fait des define pour les No de registre, c'est simplement pour une meilleur lisibilité.

    Mais que faire avec le CRTC, comme exemple on vas changer la taille de l'écran, on vas faire de l'Overscan.
    Pour le moment ont va faire de l'Overscan mais sans changer la taille de l'image en mémoire, soit 16Ko, donc ce n'est pas un écran qui prendras tout l'écran, on verra cela plus tard...

    ////////////////////////////////////////////////////////////////////////
    // CRTC1.c
    // Changement de la taille de l'ecran sur CPC
    // VERSION 
    ////////////////////////////////////////////////////////////////////////
    #include "conio2.h"
    #include 
    
    
    #define KM_WAIT_CHAR_s \
    	__asm \
    	call #0xBB06 \
    	__endasm
    
    #define  SCR_SET_MODE1_s \
    	__asm	ld a,#1 \
    	call #0xBC0E \
    	__endasm;
    
    #define  SCR_CLS_s \
    	__asm \
    		call #0xBBDB \
    	__endasm; \
    	
    
    /*
    R0: Durée de balayage horizontal y compris le retour de rayon .
    R1: Nombre de caractères affichables sur une ligne .
    R2: Synchronisation de l'affichage horizontal .
    R3: Durée du signal de synchronisation .
    
    R4: Durée du balayage vertical y compris le retour de rayon .
    R5: Fréquence de renouvellement de l'image .
    R6: Nombre de lignes caractères affichables .
    R7: Synchronisation de l'affichage vertical .
    
    R8: Mode de fonctionnement du CRTC .
    R9: Scanning .
    
    R10: Aspect du curseur (Sans grand intérêt) .
    R11: Numéro de ligne ou finit le curseur (Sans intérêt).
    
    R12: Octet fort de l'adresse départ de la RAM écran .
    R13: Octet faible de l'adresse départ de la RAM écran .
    
    R14 & R15 : Position du curseur sans intérêt .
    R16 & R17 : Crayon optique débilum babus .
    */
    
    #define CRTC_R0 0
    #define CRTC_R1 1
    #define CRTC_R2 2
    #define CRTC_R3 3
    #define CRTC_R4 4
    #define CRTC_R5 5
    #define CRTC_R6 6
    #define CRTC_R7 7
    #define CRTC_R8 8
    #define CRTC_R9 9
    #define CRTC_R10 10
    #define CRTC_R11 11
    #define CRTC_R12 12
    #define CRTC_R13 13
    #define CRTC_R14 14
    #define CRTC_R15 15
    #define CRTC_R16 16
    #define CRTC_R17 17
    
    void CRTC(unsigned char reg, unsigned char val)
    {
    	__asm
    		ld  bc,#0xBC00 ; select le registre
    		ld  a, 4(IX)
    		out (c),a
    		ld  bc,#0xBD00 ;write a value
    		ld  a, 5(IX)
    		out (c),a
    	__endasm;
    }
    
    void renintSCR()
    {
    	// Valeurs par défaut des registres du CRTC :
    	// R1 = 40 (&28); R2 = 46 (&2E); R6 = 25 (&19); R7 = 30 (&1E); R12 = 48 (&30); R13 = 0 (&00)
    	CRTC( CRTC_R1, 40);
    	CRTC( CRTC_R2, 46);
    	CRTC( CRTC_R6, 25);
    	CRTC( CRTC_R7, 30);
    	CRTC( CRTC_R12, 48);
    	CRTC( CRTC_R13, 0);
    }
    
    void main()
    {
    	// on change la couleur du border...
    	bordercolor(2);
    
    	// Valeurs par défaut des registres du CRTC :
    	// R1 = 63 (&3F); R2 = 40 (&28); R6 = 25 (&19); R7 = 30 (&1E); R12 = 48 (&30); R13 = 0 (&00)
    
    	// passage en mode 1
    	SCR_SET_MODE1_s;
    	//gotoxy(1,1);cputs("                                       ");
    	gotoxy(1,1);cputs(" Modification de la taille de l ecran");
    	gotoxy(1,2);cputs("Ecran normale");
    	gotoxy(1,24);cputs("Une touche pour continuer...");
    	KM_WAIT_CHAR_s;
    	SCR_CLS_s;
    
    
    	// ecran de 16Ko
    	// On souhaite ne pas dépasser la taille d'un écran normal (16Ko)
    	// Il faudrat que R1*R6 soit inférieur ou égal a 1024 (40*25).
    	
    	
    	// --------------------------
    	//Overscan horizontal
    	// --------------------------
    	// voici les valeur passé au CRTC :
    	//R1 = 50 (&32) ; R2 = 50 (&32) ; R6 = 20 (&14) ; R7 = 28 (&1C)
    	CRTC( CRTC_R1, 50);
    	CRTC( CRTC_R2, 50);
    	CRTC( CRTC_R6, 20);
    	CRTC( CRTC_R7, 28);
    	gotoxy(1,1);cputs("Ecran Overscan horizontal");
    	gotoxy(1,2);cputs("l ecran fait toujour 16Ko en memoire");
    	gotoxy(1,24);cputs("Une touche pour continuer...");
    	KM_WAIT_CHAR_s;
    	//renintSCR();
    	SCR_CLS_s;
    
    	// --------------------------
    	//Overscan vertical
    	// --------------------------
    	// voici les valeur passé au CRTC :
    	//R1 = 30 (&32) ; R2 = 41 (&32) ; R6 = 33 (&14) ; R7 = 34 (&1C)
    	CRTC( CRTC_R1, 30);
    	CRTC( CRTC_R2, 41);
    	CRTC( CRTC_R6, 33);
    	CRTC( CRTC_R7, 34);
    	gotoxy(1,1);cputs("Ecran Overscan vertical");
    	gotoxy(1,2);cputs("l ecran fait toujour 16Ko en memoire");
    	gotoxy(1,24);cputs("Une touche pour continuer...");
    	KM_WAIT_CHAR_s;
    	renintSCR();
    	SCR_CLS_s;
    	
    	gotoxy(1,1);cputs("Et voila, fini...");
    	gotoxy(1,2);cputs("Ecran normale");
    	gotoxy(1,24);cputs("Une touche pour quiter...");
    	KM_WAIT_CHAR_s;
    	
    }
    

    Comme on a modifié la couleur de la bordure, on voir bien que l'écran à changer de taille.

        


    On peut s'appercevoir que les écritures ne sont pas vraimant bien possitioné, surtout pour la position 1,2, qui ne commance pas à la seconde ligne et au carctère 1.
    Mais c'est tout a fait normale, les fonctions sistèmes utilisé pour le positionnement ne save le faire qu'avec un écran normale, on a donc deux solution pour régler le problème :
    - Soit caculer nous même la bonne position, on sais que notre écran fait X*R1, et on cacule cela en programment.
    - Soit on refait les fonction de positionements ... la plus compliqué tout de même.

    On vas donc afficher une image, je vous propose une "mire" adapté au CPC par mes soint (et surtout par le fait que je soit un graphiste émérite (a prendre au second (voir second du second) degré)), voyons ce que cela donne, il suffit simplement au début du main de charger un fichier image de 16Ko
    Il faut bien sur ajouter la fonction de chargement d'un fichier...
    Voici le fichier modifié :

    ////////////////////////////////////////////////////////////////////////
    // CRTC1.c
    // Changement de la taille de l'ecran sur CPC
    // VERSION 
    //   - affichage d'une image 16Ko
    ////////////////////////////////////////////////////////////////////////
    #include "conio2.h"
    #include 
    
    
    #define KM_WAIT_CHAR_s \
    	__asm \
    	call #0xBB06 \
    	__endasm
    
    #define  SCR_SET_MODE1_s \
    	__asm	ld a,#1 \
    	call #0xBC0E \
    	__endasm;
    #define  SCR_SET_MODE0_s \
    	__asm	ld a,#0 \
    	call #0xBC0E \
    	__endasm;
    
    #define  SCR_CLS_s \
    	__asm \
    		call #0xBBDB \
    	__endasm; \
    
    
    /*
    R0: Durée de balayage horizontal y compris le retour de rayon .
    R1: Nombre de caractères affichables sur une ligne .
    R2: Synchronisation de l'affichage horizontal .
    R3: Durée du signal de synchronisation .
    
    R4: Durée du balayage vertical y compris le retour de rayon .
    R5: Fréquence de renouvellement de l'image .
    R6: Nombre de lignes caractères affichables .
    R7: Synchronisation de l'affichage vertical .
    
    R8: Mode de fonctionnement du CRTC .
    R9: Scanning .
    
    R10: Aspect du curseur (Sans grand intérêt) .
    R11: Numéro de ligne ou finit le curseur (Sans intérêt).
    
    R12: Octet fort de l'adresse départ de la RAM écran .
    R13: Octet faible de l'adresse départ de la RAM écran .
    
    R14 & R15 : Position du curseur sans intérêt .
    R16 & R17 : Crayon optique débilum babus .
    */
    
    #define CRTC_R0 0
    #define CRTC_R1 1
    #define CRTC_R2 2
    #define CRTC_R3 3
    #define CRTC_R4 4
    #define CRTC_R5 5
    #define CRTC_R6 6
    #define CRTC_R7 7
    #define CRTC_R8 8
    #define CRTC_R9 9
    #define CRTC_R10 10
    #define CRTC_R11 11
    #define CRTC_R12 12
    #define CRTC_R13 13
    #define CRTC_R14 14
    #define CRTC_R15 15
    #define CRTC_R16 16
    #define CRTC_R17 17
    
    void CRTC(unsigned char reg, unsigned char val)
    {
    	__asm
    		ld  bc,#0xBC00 ; select le registre
    		ld  a, 4(IX)
    		out (c),a
    		ld  bc,#0xBD00 ;write a value
    		ld  a, 5(IX)
    		out (c),a
    	__endasm;
    }
    
    // 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;
    }
    
    void SetColor_s(unsigned char NoEncre, unsigned char color)
    {
    	//A contient le numero de l'encre ; B est la premiere couleur, C la seconde, masi la = à la première
    	__asm
    		ld  a, 4(IX)
    		ld  b, 5(IX)
    		ld  c, 5(IX)
    		call #0xBC32
    	__endasm;
    }
    
    void renintSCR()
    {
    	// Valeurs par défaut des registres du CRTC :
    	// R1 = 40 (&28); R2 = 46 (&2E); R6 = 25 (&19); R7 = 30 (&1E); R12 = 48 (&30); R13 = 0 (&00)
    	// resolution en mode 1 est donc de :
    	// La on a 200 lignes (R6*8) et 160 colonnes pixel (R1*4)
    	CRTC( CRTC_R1, 40);
    	CRTC( CRTC_R2, 46);
    	CRTC( CRTC_R6, 25);
    	CRTC( CRTC_R7, 30);
    	CRTC( CRTC_R12, 48);
    	CRTC( CRTC_R13, 0);
    }
    
    void main()
    {
    	// on change la couleur du border...
    	bordercolor(2);
    
    	// Valeurs par défaut des registres du CRTC :
    	// R1 = 40 (&28); R2 = 46 (&2E); R6 = 25 (&19); R7 = 30 (&1E); R12 = 48 (&30); R13 = 0 (&00)
    	// resolution en mode 1 est donc de :
    	// La on a 200 lignes (R6*8) et 160 colonnes pixel (R1*4)
    	
    	// passage en mode 1
    	SCR_SET_MODE1_s;
    	
    	gotoxy(1,1);cputs("Modification de la taille de l ecran");
    	gotoxy(1,2);cputs("1 - Ecran normale en mode 0");
    	gotoxy(1,3);cputs("2 - Overscan horizontal");
    	gotoxy(1,4);cputs("3 - Overscan vertical en mode 1");
    	gotoxy(1,24);cputs("Une touche pour continuer...");
    	KM_WAIT_CHAR_s;
    	SCR_CLS_s;
    
    	// passage en mode 0
    	SCR_SET_MODE0_s;
    	
    	// on applique les couleurs pour cette image :
    	// image de 200 lignes et 80 colonnes
    	// couleur : 12,0,26,24,6,20,8,18,2,13,0
    	SetColor_s( 0, 12 );
    	SetColor_s( 1, 0 );
    	SetColor_s( 2, 26 );
    	SetColor_s( 3, 24 );
    	SetColor_s( 4, 6 );
    	SetColor_s( 5, 20 );
    	SetColor_s( 6, 8 );
    	SetColor_s( 7, 18 );
    	SetColor_s( 8, 2 );
    	SetColor_s( 9, 13 );
    	SetColor_s( 10, 0 );
    	SetColor_s( 11, 0 );
    	SetColor_s( 12, 0 );
    	SetColor_s( 13, 0 );
    	SetColor_s( 14, 0 );
    	SetColor_s( 15, 0 );
    	// chargement de l'image
    	ReadFileBin( "MIREM0.SCR", 49152);
    	KM_WAIT_CHAR_s;
    	SCR_CLS_s;
    	
    	
    	// ecran de 16Ko
    	// On souhaite ne pas dépasser la taille d'un écran normal (16Ko)
    	// Il faudrat que R1*R6 soit inférieur ou égal a 1024 (40*25).
    	
    	
    	// --------------------------
    	//Overscan horizontal
    	// --------------------------
    	// voici les valeur passé au CRTC :
    	//R1 = 50 (&32) ; R2 = 50 (&32) ; R6 = 20 (&14) ; R7 = 28 (&1C)
    	// resolution est donc de :
    	// La on a 160 lignes (R6*8) et 100 colonnes pixel (R1*2) pour le mode 0
    	// La on a 160 lignes (R6*8) et 200 colonnes pixel (R1*4) pour le mode 1
    	// La on a 160 lignes (R6*8) et 400 colonnes pixel (R1*8) pour le mode 2
    	//CRTC( CRTC_R1, 50);
    	CRTC( CRTC_R1, 48);
    	CRTC( CRTC_R2, 50);
    	CRTC( CRTC_R6, 20);
    	CRTC( CRTC_R7, 28);
    
    	// passage en mode 1
    	SCR_SET_MODE1_s;
    	
    	// on applique les couleurs pour cette image :
    	// couleur : 10,11,0,1
    	SetColor_s( 0, 10 );
    	SetColor_s( 1, 11 );
    	SetColor_s( 2, 0 );
    	SetColor_s( 3, 1 );
    	
    	
    	// chargement de l'image
    	ReadFileBin( "overh02.scr", 49152);	
    	
    	
    	KM_WAIT_CHAR_s;
    	//renintSCR();
    	SCR_CLS_s;
    
    	// --------------------------
    	//Overscan vertical
    	// --------------------------
    	// voici les valeur passé au CRTC :
    	//R1 = 30 (&32) ; R2 = 41 (&32) ; R6 = 33 (&14) ; R7 = 34 (&1C)
    	// resolution est donc de :
    	// La on a 264 lignes (R6*8) et 60 colonnes pixel (R1*2) pour le mode 0
    	// La on a 264 lignes (R6*8) et 120 colonnes pixel (R1*4) pour le mode 1
    	// La on a 264 lignes (R6*8) et 240 colonnes pixel (R1*8) pour le mode 2
    	
    	CRTC( CRTC_R1, 30);
    	CRTC( CRTC_R2, 41);
    	CRTC( CRTC_R6, 33);
    	CRTC( CRTC_R7, 34);
    	
    	// passage en mode 1
    	SCR_SET_MODE1_s;
    	
    	// on applique les couleurs pour cette image :
    	// image de 264 lignes et 60 colonne
    	// couleur : 26,16,13,25
    	SetColor_s( 0, 26 );
    	SetColor_s( 1, 16 );
    	SetColor_s( 2, 13 );
    	SetColor_s( 3, 25 );
    	// chargement de l'image
    	ReadFileBin( "overv03.scr", 49152);
    	
    	KM_WAIT_CHAR_s;
    	SCR_CLS_s;
    	renintSCR();
    
    	// on remet les couleurs de base :
    	// 1, 24, 20, 6
    	SetColor_s( 0, 1 );
    	SetColor_s( 1, 24 );
    	SetColor_s( 2, 20 );
    	SetColor_s( 3, 6 );
    
    	
    	gotoxy(1,1);cputs("Et voila, fini...");
    	gotoxy(1,2);cputs("Ecran normale");
    	gotoxy(1,24);cputs("Une touche pour quiter...");
    	KM_WAIT_CHAR_s;
    	
    }
    
    

    Cela donne ceci :
        


    On voie bien que dans le cas d'un écran ou la taille à été modifier, on ne peut plus afficher une images "normale", il faut également refaire les images pour votre taille d'écran.
    Pour faire ces images vous pouvez utiliser sous Windows un logiciel comme ConvImgCpc ou dans JavaCPC JavaPaint.
    Vous pouvez aussi utiliser d'autre logiciel...

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