En fait le Z80, dans la version utilisée avec les premiers TRS-80, n’est pas forcément un processeur très rapide, loin derrière les processeurs à architecture RISC il lui faut pas mal de µcycle pour exécuter une instruction. En plus, le TRS-80 Model I ne dispose que d’une horloge de 1,77MHz, alors qu'il est prévu pour 2MHz. Si l’on veut pouvoir créer des jeux, effacer 9ko de mémoire prends un temps fou si c'est effectué par le processeur et durant ce délai il ne fait rien d'autre.

Autant faire en sorte que la carte le fasse pour lui plus rapidement. Cela est possible si on se sert du temps d’accès à la mémoire pour « remplir » cette dernière d’un octet dont on a préalablement déterminé la valeur. Comme aucun accès de la mémoire n’est permis pendant cette opération, on se servira d’un drapeau dans un des registres afin de pouvoir vérifier la fin de l’opération.

Gestion des registres :

Nous avons déjà vu comment positionner le registre CTLR et CTLA qui gère les pages mémoires, voici pour les autres d’abord pour l’écriture dans ces registres.

CPLD DONNEES

CTRL_PL0.d = TRS_D0;                                                                             /* POIDS FAIBLE DU PLAN GRAPHIQUE */

CTRL_PL1.d = TRS_D1;                                                                             /* POIDS FORT DU PLAN GRAPHIQUE */

CTRL_PGE.d = TRS_D2;                                                                            /* PAGE GRAPHIQUE ACCESSIBLE PAR L’ORDINATEUR */

CTRL_PGL.d = TRS_D3;                                                                            /* PAGE GRAPHIQUE AFFICHEE */

CTRL_RRQ.d = TRS_D4;                                                                            /* REQUETE DE DEMANDE DE REMPLISSAGE */

CTRL_DT.d = TRS_D6;                                                                               /* ECHANTILLONNAGE VIDEO NATIVE*/

CTRL_TPR.d = TRS_D7;                                                                             /* RAZ COMPTEUR DE SYNCHRO */

CTRL_PL0.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;                 /* VALIDATION POUR LE REGISTRE BASE + 0b00 */

CTRL_PL1.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;

CTRL_PGE.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;

CTRL_PGL.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;

CTRL_RRQ.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;

CTRL_EVT.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;

CTRL_TPR.ck = MREQ & !RDWR & INOUT & !CSREG0 & !CSREG1;

 

CTLA_RG.d = TRS_D0;                                                                              /* COMPOSANTE ROUGE DE LA COULEUR DU PLAN 4 */

CTLA_VR.d = TRS_D1;                                                                               /* COMPOSANTE VERTE DE LA COULEUR DU PLAN 4 */

CTLA_BL.d = TRS_D2;                                                                               /* COMPOSANTE BLEU DE LA COULEUR DU PLAN 4 */

CTLA_DV.d = TRS_D3;                                                                              /* PLAN 4 EN L’AVANT DE L’IMAGE GRAPHIQUE */

CTLA_EVT.d = TRS_D4;                                                                              /* ACTIVATION VIDEO TRS-80 */

CTLA_M0.d = TRS_D5;                                                                             /* SELECTION DE LA PAGE MEMOIRE ETENDUE POIDS FAIBLE*/

CTLA_M1.d = TRS_D6;

CTLA_M2.d = TRS_D7;                                                                             /* SELECTION DE LA PAGE MEOIRE ETENDUE POIDS FORT */

CTLA_RG.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;          /* VALIDATION POUR LE REGISTRE BASE + 0b10 */

CTLA_VR.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

CTLA_BL.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

CTLA_DV.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

CTLA_GR.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

CTLA_M0.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

CTLA_M1.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

CTLA_M2.ck = MREQ & !RDWR & INOUT & CLK & !CSREG0 & CSREG1;

 

REMP_D0.d = TRS_D0 ;                                                                            /* OCTET DE REMPLISSAGE POIDS FAIBLE */

REMP_D7.d = TRS_D7 ;                                                                            /* OCTET DE REMPLISSAGE POIDS FORT */

 

REMP_D0.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;        /* VALIDATION POUR LE REGISTRE BASE + 0b01 */

REMP_D1.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

REMP_D2.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

REMP_D3.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

REMP_D4.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

REMP_D5.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

REMP_D6.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

REMP_D7.ck = MREQ & !RDWR & INOUT & CLK & CSREG0 & !CSREG1;

 

Et maintenant pour la lecture de l’état des registres :

CPLD DONNEES

TRS_D0.d = MEM_D0 & RDWR & !INOUT # (CTRL_PL0 & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D0 # !CSREG0 & CSREG1 & CTLA_RG # CSREG0 & CSREG1 & CTRL_TPS) & RDWR & INOUT ;

TRS_D1.d = MEM_D1 & RDWR & !INOUT # (CTRL_PL1 & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D1 # !CSREG0 & CSREG1 & CTLA_VR # CSREG0 & CSREG1 & TPS_D1) & RDWR & INOUT ;

TRS_D2.d = MEM_D2 & RDWR & !INOUT # (CTRL_PGE & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D2 # !CSREG0 & CSREG1 & CTLA_BL # CSREG0 & CSREG1 & TPS_D2) & RDWR & INOUT ;

TRS_D3.d = MEM_D3 & RDWR & !INOUT # (CTRL_PGL & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D3 # !CSREG0 & CSREG1 & CTLA_DV # CSREG0 & CSREG1 & TPS_D3) & RDWR & INOUT ;

TRS_D4.d = MEM_D4 & RDWR & !INOUT # (CTRL_RRQ & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D4 # !CSREG0 & CSREG1 & CTLA_GR # CSREG0 & CSREG1 & TPS_D4) & RDWR & INOUT ;

TRS_D5.d = MEM_D5 & RDWR & !INOUT # (CTRL_TPR & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D5 # !CSREG0 & CSREG1 & CTLA_M0 # CSREG0 & CSREG1 & TPS_D5) & RDWR & INOUT ;

TRS_D6.d = MEM_D6 & RDWR & !INOUT # (CTRL_EVT & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D6 # !CSREG0 & CSREG1 & CTLA_M1 # CSREG0 & CSREG1 & TPS_D6) & RDWR & INOUT ;

TRS_D7.d = MEM_D7 & RDWR & !INOUT # (CTRL_TPS & !CSREG0 & !CSREG1 # CSREG0 & !CSREG1 & REMP_D7 # !CSREG0 & CSREG1 & CTLA_M2 # CSREG0 & CSREG1 & TPS_D7) & RDWR & INOUT ;

 

TRS_D0.ck = MEMREQ & MCY2 & MCY1 & MCY0 ;

..

TRS_D7.ck = MEMREQ & MCY2 & MCY1 & MCY0 ;

 

TRS_D0.oe = RDWR & MREQ ;

TRS_D7.oe = RDWR & MREQ ;

 

Nous l’avons vu, un des gros avantages de la gestion des ports d’entrées sorties du Z80 c’est lors d’une écriture (OUT) la donnée transmise apparait sur les poids fort du bus d’adresse (A15-A8), ce qui permet de gérer les commandes transmises sans pour autant qu’il y ait besoin d’une communication entre les deux CPLD.

C’est très utile notamment pour le traitement des pages mémoire qui influent sur le CPLD ADRESSE.

CPLD ADRESSES

CTRL_PL0.d = TRS_A8;                                                                             /* PLAN COULEUR POIDS FAIBLE */

CTRL_PL0.ck = MREQ & INOUT & !RDWR & !TRS_A0 & !TRS_A1;

CTRL_PL1.d = TRS_A9;                                                                             /* PLAN COULEUR POIDS FORT */

CTRL_PL1.ck = MREQ & INOUT & !RDWR & !TRS_A0 & !TRS_A1;

CTRL_PGE.d = TRS_A10;                                                                           /* PAGE ACCESSIBLE PAR L’ORDINATEUR */

CTRL_PGE.ck = MREQ & INOUT & !RDWR & !TRS_A0 & !TRS_A1;

CTRL_PGL.d = TRS_A11;                                                                           /* PAGE AFFICHEE */

CTRL_PGL.ck = MREQ & INOUT & !RDWR & !TRS_A0 & !TRS_A1;

 

CTLA_M0.d = TRS_A13;                                                                            /* PLAN MEMOIRE D’EXTENSION POIDS FAIBLE*/

CTLA_M0.ck = MREQ & INOUT & !RDWR & TRS_A0 & !TRS_A1;

CTLA_M1.d = TRS_A14;

CTLA_M1.ck = MREQ & INOUT & !RDWR & TRS_A0 & !TRS_A1;

CTLA_M2.d = TRS_A15;                                                                            /* PLAN MEMOIRE D’EXYTENSION POIDS FORT */

CTLA_M2.ck = MREQ & INOUT & !RDWR & TRS_A0 & !TRS_A1;

 

OFFSET_D0.d = TRS_A8;                                                                           /* OFFSET D’AFFICHAGE DE L’ECRAN NATIF POIDS FAIBLE*/

OFFSET_D0.ck = MREQ & INOUT & !RDWR & TRS_A0 & TRS_A1;                  /* VALIDATION POUR LE REGISTRE BASE + 0b11 */

OFFSET_D1.d = TRS_A9;

OFFSET_D1.ck = MREQ & INOUT & !RDWR & TRS_A0 & TRS_A1;

OFFSET_D2.d = TRS_A10;

OFFSET_D2.ck = MREQ & INOUT & !RDWR & TRS_A0 & TRS_A1;

OFFSET_D3.d = TRS_A11;

OFFSET_D3.ck = MREQ & INOUT & !RDWR & TRS_A0 & TRS_A1;

OFFSET_D4.d = TRS_A12;

OFFSET_D4.ck = MREQ & INOUT & !RDWR & TRS_A0 & TRS_A1;

OFFSET_D5.d = TRS_A13;                                                                         /* OFFSET D’AFFICHAGE DE L’ECRAN NATIF POIDS FAIBLE*/

OFFSET_D5.ck = MREQ & INOUT & !RDWR & TRS_A0 & TRS_A1;

 

Nous pouvons maintenant ajouter de nouvelles fonctionnalités :