CODING ★ Les derniers mysteres ★

LOGON CPCPLUS 47: Les derniers mystères

Oui, je sais ! Il n'y a pas eu d'article sur le CPC Plus dans le numéro précédent, mais c'est la faute de Pict qui a pris toute la place.

Hmmm, après cette explication fumeuse, venons-en directement au sujet de la prose de ce mois. Cet article met enfin un terme à la description de tous les registres « secrets » du CPC Plus.

Je vais donc aborder:

  • les interruptions du CPC+ ;
  • la rupture facile ;
  • la gestion des ports analogiques ;
  • la gestion du 8e bit de l'imprimante.

LES INTERRUPTIONS!

Argh! Nous avons déjà abordé le chapitre des interruptions dans la rubrique Logon (cf. Amstrad CPC n033, p. 50)et Digit vous avait preque tout expliqué. Pour reprendre, une interruption est le nom donné à une action (le plus souvent un branchement) effectuée par le microprocesseur (en l'occurrence le Z80A). Celui ci interrompt l'exécution séquentielle des instructions pour simuler un appel à une routine (un CALL en Z80A si vous préférez). Deux questions se posent dès lors.

Qui dit au micro-processeur qu'il va devoir « interrompre » le programme en cours?
Tout simplement un périphérique (par exemple un circuit ou le microprocesseur lui-même [dans certains cas, mais c'est une autre histoire]). Sur le CPC en mode "normal", les interruptions sont émises par le "gate array", toutes les 52 HBL [en principe il y a 1 HBL par ligne vidéo], ce comptage étant fait en 2 fois (32 HBL, puis 20 HBL)(cette gestion peut décaler les interruptions de 32 HBL si une interruption en attente est autorisée lorsque le 2ème compteur est en train de compter). Sans bidouille CRTC, on a une HBL par ligne qui dure 64 microseconde. Le Z80A est donc interrompu tous les 1/300ème de seconde (soit 6 fois durant 1 balayage, sachant que la première se produit 2 HBL après que le signal VBL soit signalé via la bit 0 du port B du PPI).

A quelle adresse le Z80A va-t-il?

A cette question... il y a plusieurs réponses. Ben pourquoi donc? Parce qu'il y a plusieurs type d'interruptions sur Z80A. Les "ordinaires" (modes IM0, IM1 et IM2), les demandes de Bus (BUSRQ) et les interruptions non masquables (NMI).

Je signale au passage que je parlerai ici uniquement des interruptions ordinaires, mais sachez néanmoins que la NMI est générée par le bouton poussoir de votre multiface 2 (le vecteur de cette interruption se trouvant en #0066).

Le mode IM0 est un mode ou le périphérique insère ses propres instructions sur le bus de données et ne nous intéresse pas, car il n'est jamais utilisé.

Le mode IM1 correspond à un mode non vectorisé.

Le mode IM2 à un mode vectorisé des interruptions.

La vectorisation permet d'attribuer à chaque périphérique (souvenez-vous, c'est un déclencheur d'interruption) sa propre adresse.

En mode non vectorisé, le Z80A appelle une adresse précise (située en #0038) et la routine située à cet endroit doit alors tester quel périphérique l'a appelée.

Sur le CPC+ en mode « old generation », seul le Gate Arrray émulé « génère » des interruptions. Le Gate Array étant la seule source d'interruption, il n'y a pas besoin de l'identifier. Sur un CPC "ancienne génération" (ou CPC+ dans ce mode) le mode vectorisé IM2 n'a donc pas d'utilité pour identifier la source de l'interruption mais ce mode peut en revanche permettre le changement de l'adresse « immuable » #0038 pour les interruptions (certains programmes pouvant avoir besoin de libérer cette zone...). Mais un bug du mode IM2 sur les CPC "ancienne génération" oblige à dépenser 257 octets de Ram pour pouvoir déplacer l'adresse d'interruption.

VECTORISER EN MODE IM2

Pour vectoriser en mode IM2 il faut utiliser une table de vecteurs (entendez « adresse d'interruption » pour « vecteurs). Ainsi, dans une table se suivent des adresses de routines d'interruption.

Comment définir l'adresse de la table d'interruption?

a) L'octet de poids fort de l'adresse de la table est défini par le registre I du Z80A (mais si, mais si, il servait à quelque chose !).

b) L'octet de poids faible de l'adresse est normalement fourni par le périphérique qui génère l'interruption. Le problème sur les vieux CPC est que le périphérique n'a pas de numéro et les 7 bits de poids fort de cette valeur sont aléatoires (en outre, le bit 0 est souvent à 1 sur les « old » et toujours à 0 sur le CPC+, d'où une incompatibilité du mode IM2 entre les 2 machines lorsque le Plus fonctionne en mode "Old"!).C'est pourquoi, pour utiliser le mode IM2 sur un Cpc "Old" (ou Plus en mode "Old"), l'astuce consiste à utiliser un vecteur qui soit le même quelque soit l'adresse pointée dans la page de 257 octets pointée par Ix256. Il faut donc que le vecteur soit une adresse dont le poids fort est égal au poids faible, par exemple #3232, et recopier 257 fois la valeur #32 (pour l'exemple) pour utiliser le mode IM2.


Mais revenons au Plus. L'Asic, qui est LE périphérique principal du Z80A est capable de générer 4 interruptions différentes:

  • une interruption raster;
  • trois interruptions DMA-son.


Schéma n°1 : Calcul de l'adresse d'un vecteur

Le schéma n°1 décrit l'adresse de la table des vecteurs sur CPC+. L'octet situé en #6805 Asic (IVR) permet de définir, avec le registre I, les bits 3 à 15 de l'adresse de la table. Lorsqu'une interruption à lieu, les bits 1 & 2 sont positionnés par le périphérique qui génère l'interruption, d'où branchement à une adresse spécifique. Notons au passage que le bit 0 de l'adresse vaut toujours 0 et implique que la table commence sur une adresse paire.

La grande précision au niveau de l'adresse apportée par le registre IVR permet de ne « dépenser » que 8 octets pour la table d'interruption.

En mode IM1, nous avons vu que les interruptions ont toutes lieu en #0038. La routine située à cette adresse doit donc être capable de savoir quelle était l'interruption générée par l'Asic. Pour cela, il existe un registre de statuts dans l'Asic, qui permet de savoir quelle interruption a eu lieu. Vous connaissez déjà ce registre, appelé DCSR, car je l'avais décrit dans le n°45, page 39, schéma 3. Le revoici sur le schéma n°2.


Schéma n°2 : Resgistre de contrôle DMA (DCSR)

Que l'interruption ait bien lieu est une chose, mais il faut savoir dire qu'elle est finie pour qu'une nouvelle puisse « arriver ». On appelle cette action un acquittement d'interruption.

D'ordinaire, un simple EI suffit à informer le Z80A qu'il pourra accepter une nouvelle interruption. Sur le CPC+, plusieurs méthodes s'offrent à nous.


Schéma n°3

Le tableau du schéma n°3 décrit tous les acquittements possibles. Signalons au passage que le bit 0 du registre IVR, placé à 0, permet d'utiliser EI comme instruction d'acquittement automatique non spécifique à une interruption (ceci pour les DMA puisque l'interruption raster est toujours acquittée automatiquement). Ceci a été fait pour faciliter les acquittements en mode vectorisé (IM2), puisque chaque interruption a sa routine propre.

L'inconvénient de ce procédé (bit 0 de IVR à 0) en mode IM1 est que les bits 4 à 7 de DCSR ne sont plus mis à jour (ou du moins testables), et la routine ne peut donc pas savoir quelle interruption a eu lieu.

POUR RESUMER

En mode IM2, vous savez implicitement quelle interruption a lieu et vous pouvez vous contenter d'acquitter vos interruptions par EI en plaçant le bit 0 de IVR à 0.
En mode IM1, vous pouvez:

  • connaître quelle interruption a eu lieu grâce à DCSR, auquel cas le bit 0 de IVR est à 1, et vous devez acquitter votre interruption en positionnant le bit correspondant dans DCSR à 1. Notons toutefois que la « consultation » de DCSR doit impérativement commencer par l'interruption raster, car celle-ci est acquittée automatiquement et de ce fait classée prioritaire
  • ne pas connaître quelle interruption a eu lieu, mais l'acquitter automatiquement grâce à EI en positionnant le bit 0 de IVR à 0.

Sachez néanmoins que la valeur du bit 0 de IVR au reset est 1

LES DIFFERENTES INTERRUPTIONS

L' interruption Raster permet de déclencher une interruption à une ligne spécifiée à l'adresse #6800 (PRI).

Il est possible de reprogrammer cette interruption pour générer plusieurs interruptions durant le balayage. Notons que la ligne prise en compte est la première ligne de données affichées et non pas la première ligne du balayage !

Ceci peut être gênant pour avoir des interruptions « en dehors de l'espace d'affichage programmé avec le CRTC lorsqu'on augmente les lignes définies par le basic (200)». Lorsque le contenu de #6800 est différent de 0, alors l'interruption raster remplace l'ancien système d'interruptions émulé.
Ainsi vous avez peut-être remarqué qu'une valeur différente de 0 en #6800 de la page Asic provoque un ralentissement général du CPC, et pour cause : Il n'y a plus qu'une interruption par balayage au lieu de six!
Si on dimensionne l'écran verticalement au-delà de 256 lignes, il faut mettre 1 pour avoir une interruption sur la ligne 257 par exemple, puisque le registre ne fait que 8 bits. Mais la ligne 256 est la grande oubliée, car 0 désactive l'interruption.

Il existe par ailleurs un bug hardware avec le mode vectorisé du CPC+. Si le bit 13 de l'adresse de l'instruction interrompue est égal à 0, alors l'interruption DMA 0 est appelée en lieu et place de l'interruption Raster dans certaines situations, selon la nature de l'instruction interrompue (dans le contexte ou le bit 13 de son adresse=0).

Autrement dit, pour éviter cette erreur, il faut prévoir de loger le code "interruptible" sur les plages d'adresse ou A13=1, ou encore traiter le vecteur Raster et DMA-0 comme un seul vecteur.

LES INTERRUPTIONS DMA-SONS

Hem ! Celles-ci sont générées via les AY-Listes que je vous ai décrites dans le n°45, pages 38-40.
L'instruction INT (#4010) lue par un canal DMA dans une AY-Liste permet de déclencher une interruption.
Vu la taille de l'article sur le son, je vous conseille de le relire.

Voilà, fini le tour d'horizon des interruptions du CPC+ ! Pfewww!

LA RUPTURE

Passons maintenant à la rupture sur le CPC+. Cette technique, superbidouillage des anciens CPC, est maintenant prévue d'origine dans les entrailles de Asic (qui émule le CRTC !). Il suffit juste de spécifier le numéro de ligne et l'adresse du nouvel écran! Ainsi (#6801 ou Reg SPLT) contient le numéro de la ligne de rupture. Et (#6802, #6803 ou Reg SSA) contient l'adresse du second écran (le premier étant défini par les classiques registres 12 et 13 du CRTC émulé). Tout comme pour l'interruption raster, le numéro de ligne varie entre 1 et 255 ( 0 pour annuler le « split » ) et commence à partir de la première ligne de données affichées. Ceci pose donc problème pour faire du "fullscreen" car un écran peut afficher plus de 256 lignes en hauteur.

Après ce bref interlude dans le merveilleux monde de la rupture, passons à la prise située sous l'interrupteur (mais si, elle sert à quelquechose !).

LA PRISE ANALOGIQUE

Cette prise est donc une entrée analogique composée d'un « convertisseur analogique/digital octal en conjonction avec un réseau R-2R, un comparateur et un multiplexeur analogique ». Burp...A vos souhaits

A quoi ça sert?

A beaucoup de choses, mais, entre autres, à brancher 4 paddles, 2 joysticks analogiques, etc. On aurait pu penser au son si la vitesse d'échantillonnage avait été autre.

Un paddle est en quelque sorte, un potentiomètre permettant de déplacer unidirectionnellement la raquette de votre casse-briques, par exemple. Quant à définir un joystick analogique par rapport à un joystick digital, disons que c'est un joystick « mou » (Poum est un spécialiste de la chose [NDPoum Longshot l'a testé pour vous]) disposant d'une très haute précision et équipé de deux poussoirs (et pas de malentendus).

L'Asic dispose de 8 canaux d'entrée analogique, mais seulement 4 parmi eux sont reliés à la prise physiquement (no comment sur le gaspillage). Bref, 8 registres existent dont 4 sont lisibles. Ces registres sont des registres 6 bits mis à jour 200 fois par seconde et traduisent des variations de 0 volt (valeur #00) à 2,5 volts (valeur #3F). Notez que l'impédance en entrée doit être de 1 kilo-ohm.

Cependant, chers lecteurs, la doc technique Amstrad, largement incomplète, ne précise pas où les boutons « Fire » sont gérés. Je suppose donc, n'ayant pu le tester à ce jour, que le bit 6 de chaque registre contient l'état du Fire (ou du moins un état fourni sur les broches correspondantes aux Fires).
Je vous livre dans le schéma n°4 la structure de ces registres, ainsi que le brochage de la prise pour les joysticks analogiques compatibles PC200(PC-8).


Schéma n°4 : Convertiseur analogique/digital

ET L'IMPRIMANTE?

Et pour finir en beauté, si nous parlions de l'imprimante. Pour lui envoyer un octet il suffit de lui demander si elle est prête, ceci via le bit 6 du port B du PPI situé en #F500 (cf. n043, pages 23 à 27).
Lorsque ce bit est à 0, on peut lui envoyer un octet Lorsqu'il est à 1, l'imprimante est occupée (son buffer est plein, il manque du papier, elle est éteinte, pas OnLine, ...).

Notons que le système arrive à faire la différence entre un buffer plein et un autre type d'erreur lorsque le bit de contrôle reste trop longtemps à l'état 1. Jusqu'à maintenant le fonctionnement de l'imprimante me paraissait simple. Il suffisait pour lui envoyer un octet d'utiliser le port #EF00 en envoyant 3 fois la valeur (1e: Bit 7=0; 2e: Bit7=1; 3e: Bit7=0), le bit 7 servant à valider l'octet! Pour cette raison, seuls les 7 bits de poids faibles étaient pris en compte. C'est toujours le cas sur ce port pour des raisons de compatibilité!

Mais alors ? Où est le 8e bit manquant? (NDLR : Oui, où ?). Accrochez-vous. Celui-ci se trouve sur le bit 3 du registre 12 du CRTC 6845 émulé ( cf n°38, page 48 ).

Comme quoi, il n'y a pas de petites économies, puisque ce bit « semblait » inoccupé pour les techniciens d'Amstrad. Ceux-ci ne connaissaient malheureusement pas les Overscan Bits.

Dans le cas d'un logiciel "full screen" faisant des impressions, le buffer vidéo fera la valse entre 16 K et 32 K sans arrêt (très psychédélique). Heureusement toutefois que la rupture est là!

Bref, pour envoyer un octet 8 bits à l'imprimante, voici quelques lignes de basic que vous adapterez sans problème en assembleur si vous souhaitez modifier les vecteurs systèmes du firmware.

10000 REM B Contient le caractère (0 à 255)
10005 REM Longshot Logon System 1993
10010 OUT &BC00,12:A=INP(&BF00):B1=B AND 127
10020 IF ((B AND 128) = 0) THEN B2=0 ELSE B2=8
10030 A=A AND 247:OUT &BD00,A OR B2
10040 IF (INP(&F500) AND 64)<>0) THEN 10040
10050 OUT &EF00,B1:OUT &EF00,B1 OR 128:OUT &EF00,B1
10060 RETURN

Alors, gavés ? Encore des registres? Gaaaaa....Buurpp! Euh... excusez-moi!

Pour les plus observateurs, vous aurez remarqué une autre prise à côté de la prise analogique (sur laquelle la doc technique originale est très incomplète. En effet l'article est le fruit de ma sueur). Là, c'est encore mieux, la doc ne dit rien ! Et pourtant cette prise n'est ni plus ni moins qu'une prise pour brancher un stylo optique ou même un GunPhaser (Yeah !) puisqu'il y a deux boutons de feu ! En attendant de vérifier si les registres CRTC 14 et 15 y sont pour quelque chose (j'ai un doute !), je vous donne rendez-vous pour la prochaine fois avec la carte complète de tous les registres Asic, ainsi que le brochage de TOUS les connecteurs!

Bonne nuit.. Et à demain!

Longshot. Logon System , ACPC n°47 page 34-35-36-37! (Révisé en 2019)

★ ANNÉE: 1993
★ AUTEUR: LONGSHOT
★ UPDATED: 10/08/2019

 

Page précédente : LOGON CPCPLUS 45: Le CPC plus en musique
★ AMSTRAD CPC ★ DOWNLOAD ★

Aucun fichier de disponible:
» Vous avez des fichiers que nous ne possédons pas concernent cette page ?
★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » LOGON CPCPLUS 41: Programmation de l'ASIC
» Coding » Chronique A100% CPC+ (Logon System)
» Coding » Cours CPC Plus par AST / IMPACT
» Coding » LOGON CPCPLUS 39: Exploitez les sprites de votre CPC Plus
» Coding » LOGON CPCPLUS 48: En avant l'ASIC
» Coding » LOGON CPCPLUS 45: Le CPC plus en musique
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 438 millisecondes et consultée 2975 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.