CODINGSDCC TUT'S PAR STEPHBB75 ★ Attaquer le CRTC ★

Sdcc - 11 - Attaquer le CrtcCoding Sdcc Tut's Par Stephbb75

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 écran");
gotoxy(1,2);cputs("Ecran normale");
gotoxy(1,24);cputs("Une touche pour continuer...");
KM_WAIT_CHAR_s;
SCR_CLS_s;


// écran 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 écran 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 écran 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 numéro 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 écran");
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;


// écran 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 ;-)

stephbb75

ANNÉE: 2013
★ AUTEUR: Stephbb75

Page précédente : Sdcc - 10 - H Line
★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tool:
» stephbb75-crtc1DATE: 2013-02-07
DL: 361
TYPE: ZIP
SiZE: 25Ko
NOTE: 40 Cyls
.HFE: Χ

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Sdcc - 22 - Afficher uneImage
» Coding » Sdcc - 14 - Animation Par Couleur
» Coding » Sdcc - 05 - Ecrire du Text
» Coding » Sdcc - 10 - H Line
» Coding » Sdcc - 19 - 3D - Optimisation
» Coding » Sdcc - 17 - 3D - Trace Points
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 159 millisecondes et consultée 2414 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.